Blame SOURCES/gssproxy-0.3.1-nfsd_startup.patch

4c520e
From 58a39677c961c72b052eae0b9d94b992254d6e10 Mon Sep 17 00:00:00 2001
4c520e
From: Simo Sorce <simo@redhat.com>
4c520e
Date: Fri, 3 Jan 2014 16:45:35 -0500
4c520e
Subject: [PATCH 1/2] Add utility functions to read()/write() safely
4c520e
MIME-Version: 1.0
4c520e
Content-Type: text/plain; charset=UTF-8
4c520e
Content-Transfer-Encoding: 8bit
4c520e
4c520e
Automatically handle short reads due to singals interrupting the process.
4c520e
4c520e
Signed-off-by: Simo Sorce <simo@redhat.com>
4c520e
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
4c520e
---
4c520e
 proxy/src/gp_common.h |  2 ++
4c520e
 proxy/src/gp_util.c   | 39 +++++++++++++++++++++++++++++++++++++++
4c520e
 2 files changed, 41 insertions(+)
4c520e
4c520e
diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h
4c520e
index f2b8c3e..3a1b7be 100644
4c520e
--- a/proxy/src/gp_common.h
4c520e
+++ b/proxy/src/gp_common.h
4c520e
@@ -69,6 +69,8 @@ bool gp_same(const char *a, const char *b);
4c520e
 bool gp_boolean_is_true(const char *s);
4c520e
 char *gp_getenv(const char *name);
4c520e
 
4c520e
+ssize_t gp_safe_read(int fd, void *buf, size_t count);
4c520e
+ssize_t gp_safe_write(int fd, const void *buf, size_t count);
4c520e
 /* NOTE: read the note in gp_util.c before using gp_strerror() */
4c520e
 char *gp_strerror(int errnum);
4c520e
 
4c520e
diff --git a/proxy/src/gp_util.c b/proxy/src/gp_util.c
4c520e
index 4fbac4e..34f3024 100644
4c520e
--- a/proxy/src/gp_util.c
4c520e
+++ b/proxy/src/gp_util.c
4c520e
@@ -29,6 +29,7 @@
4c520e
 #include <stdlib.h>
4c520e
 #include <stdio.h>
4c520e
 #include <errno.h>
4c520e
+#include <unistd.h>
4c520e
 
4c520e
 bool gp_same(const char *a, const char *b)
4c520e
 {
4c520e
@@ -125,3 +126,41 @@ char *gp_strerror(int errnum)
4c520e
     errno = saved_errno;
4c520e
     return buf;
4c520e
 }
4c520e
+
4c520e
+ssize_t gp_safe_read(int fd, void *buf, size_t count)
4c520e
+{
4c520e
+    char *b = (char *)buf;
4c520e
+    ssize_t len = 0;
4c520e
+    ssize_t ret;
4c520e
+
4c520e
+    do {
4c520e
+        ret = read(fd, &b[len], count - len);
4c520e
+        if (ret == -1) {
4c520e
+            if (errno == EINTR) continue;
4c520e
+            return ret;
4c520e
+        }
4c520e
+        if (ret == 0) break; /* EOF */
4c520e
+        len += ret;
4c520e
+    } while (count > len);
4c520e
+
4c520e
+    return len;
4c520e
+}
4c520e
+
4c520e
+ssize_t gp_safe_write(int fd, const void *buf, size_t count)
4c520e
+{
4c520e
+    const char *b = (const char *)buf;
4c520e
+    ssize_t len = 0;
4c520e
+    ssize_t ret;
4c520e
+
4c520e
+    do {
4c520e
+        ret = write(fd, &b[len], count - len);
4c520e
+        if (ret == -1) {
4c520e
+            if (errno == EINTR) continue;
4c520e
+            return ret;
4c520e
+        }
4c520e
+        if (ret == 0) break; /* EOF */
4c520e
+        len += ret;
4c520e
+    } while (count > len);
4c520e
+
4c520e
+    return len;
4c520e
+}
4c520e
-- 
4c520e
1.8.4.2
4c520e
4c520e
4c520e
From bd8ffcf67be8fdbe14bc49a65a8eafe904119d88 Mon Sep 17 00:00:00 2001
4c520e
From: Simo Sorce <simo@redhat.com>
4c520e
Date: Fri, 3 Jan 2014 12:10:36 -0500
4c520e
Subject: [PATCH 2/2] Block parent process until child is initialized.
4c520e
MIME-Version: 1.0
4c520e
Content-Type: text/plain; charset=UTF-8
4c520e
Content-Transfer-Encoding: 8bit
4c520e
4c520e
This way the init system will not proceed starting dependencies until gssproxy
4c520e
is actually ready to serve requests.
4c520e
In particular this is used to make sure the nfsd proc file has been touched
4c520e
before the nfsd server is started.
4c520e
4c520e
Resolves: https://fedorahosted.org/gss-proxy/ticket/114
4c520e
4c520e
Signed-off-by: Simo Sorce <simo@redhat.com>
4c520e
Reviewed-by: Günther Deschner <gdeschner@redhat.com>
4c520e
---
4c520e
 proxy/src/gp_init.c  | 42 +++++++++++++++++++++++++++++++++++++++---
4c520e
 proxy/src/gp_proxy.h |  3 ++-
4c520e
 proxy/src/gssproxy.c | 11 +++++++++--
4c520e
 3 files changed, 50 insertions(+), 6 deletions(-)
4c520e
4c520e
diff --git a/proxy/src/gp_init.c b/proxy/src/gp_init.c
4c520e
index 830ae16..6207a78 100644
4c520e
--- a/proxy/src/gp_init.c
4c520e
+++ b/proxy/src/gp_init.c
4c520e
@@ -37,12 +37,22 @@
4c520e
 #include <stdio.h>
4c520e
 #include "gp_proxy.h"
4c520e
 
4c520e
-void init_server(bool daemonize)
4c520e
+void init_server(bool daemonize, int *wait_fd)
4c520e
 {
4c520e
     pid_t pid, sid;
4c520e
     int ret;
4c520e
 
4c520e
+    *wait_fd = -1;
4c520e
+
4c520e
     if (daemonize) {
4c520e
+        int pipefd[2];
4c520e
+        char buf[1];
4c520e
+
4c520e
+        /* create parent-child pipe */
4c520e
+        ret = pipe(pipefd);
4c520e
+        if (ret == -1) {
4c520e
+            exit(EXIT_FAILURE);
4c520e
+        }
4c520e
 
4c520e
         pid = fork();
4c520e
         if (pid == -1) {
4c520e
@@ -50,10 +60,22 @@ void init_server(bool daemonize)
4c520e
             exit(EXIT_FAILURE);
4c520e
         }
4c520e
         if (pid != 0) {
4c520e
-            /* ok kill the parent */
4c520e
-            exit(EXIT_SUCCESS);
4c520e
+            /* wait for child to signal it is ready */
4c520e
+            close(pipefd[1]);
4c520e
+            ret = gp_safe_read(pipefd[0], buf, 1);
4c520e
+            if (ret == 1) {
4c520e
+                /* child signaled all ok */
4c520e
+                exit(EXIT_SUCCESS);
4c520e
+            } else {
4c520e
+                /* lost child, something went wrong */
4c520e
+                exit(EXIT_FAILURE);
4c520e
+            }
4c520e
         }
4c520e
 
4c520e
+        /* child */
4c520e
+        close(pipefd[0]);
4c520e
+        *wait_fd = pipefd[1];
4c520e
+
4c520e
         sid = setsid();
4c520e
         if (sid == -1) {
4c520e
             /* setsid error ? abort */
4c520e
@@ -78,6 +100,20 @@ void init_server(bool daemonize)
4c520e
     gp_logging_init();
4c520e
 }
4c520e
 
4c520e
+void init_done(int wait_fd)
4c520e
+{
4c520e
+    char buf = 0;
4c520e
+    int ret;
4c520e
+
4c520e
+    if (wait_fd != -1) {
4c520e
+        ret = gp_safe_write(wait_fd, &buf, 1);
4c520e
+        if (ret != 1) {
4c520e
+            exit(EXIT_FAILURE);
4c520e
+        }
4c520e
+        close(wait_fd);
4c520e
+    }
4c520e
+}
4c520e
+
4c520e
 void fini_server(void)
4c520e
 {
4c520e
     closelog();
4c520e
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
4c520e
index 733fec5..79bebb8 100644
4c520e
--- a/proxy/src/gp_proxy.h
4c520e
+++ b/proxy/src/gp_proxy.h
4c520e
@@ -106,7 +106,8 @@ struct gp_creds_handle *gp_service_get_creds_handle(struct gp_service *svc);
4c520e
 void free_config(struct gp_config **config);
4c520e
 
4c520e
 /* from gp_init.c */
4c520e
-void init_server(bool daemonize);
4c520e
+void init_server(bool daemonize, int *wait_fd);
4c520e
+void init_done(int wait_fd);
4c520e
 void fini_server(void);
4c520e
 verto_ctx *init_event_loop(void);
4c520e
 void init_proc_nfsd(struct gp_config *cfg);
4c520e
diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c
4c520e
index 1bf0a0b..80430d6 100644
4c520e
--- a/proxy/src/gssproxy.c
4c520e
+++ b/proxy/src/gssproxy.c
4c520e
@@ -42,6 +42,7 @@ int main(int argc, const char *argv[])
4c520e
     int vflags;
4c520e
     struct gssproxy_ctx *gpctx;
4c520e
     struct gp_sock_ctx *sock_ctx;
4c520e
+    int wait_fd;
4c520e
     int ret;
4c520e
     int i;
4c520e
 
4c520e
@@ -97,7 +98,7 @@ int main(int argc, const char *argv[])
4c520e
         exit(EXIT_FAILURE);
4c520e
     }
4c520e
 
4c520e
-    init_server(gpctx->config->daemonize);
4c520e
+    init_server(gpctx->config->daemonize, &wait_fd);
4c520e
 
4c520e
     write_pid();
4c520e
 
4c520e
@@ -139,9 +140,15 @@ int main(int argc, const char *argv[])
4c520e
         }
4c520e
     }
4c520e
 
4c520e
-    /* special call to tell the Linux kernel gss-proxy is available */
4c520e
+    /* We need to tell nfsd that GSS-Proxy is available before it starts,
4c520e
+     * as nfsd needs to know GSS-Proxy is in use before the first time it
4c520e
+     * needs to call accept_sec_context. */
4c520e
     init_proc_nfsd(gpctx->config);
4c520e
 
4c520e
+    /* Now it is safe to tell the init system that we're done starting up,
4c520e
+     * so it can continue with dependencies and start nfsd */
4c520e
+    init_done(wait_fd);
4c520e
+
4c520e
     ret = gp_workers_init(gpctx);
4c520e
     if (ret) {
4c520e
         exit(EXIT_FAILURE);
4c520e
-- 
4c520e
1.8.4.2
4c520e