Split signal setup into loop_setup_signals()
authorGreg Hudson <ghudson@mit.edu>
Wed, 14 Sep 2011 16:12:33 +0000 (16:12 +0000)
committerGreg Hudson <ghudson@mit.edu>
Wed, 14 Sep 2011 16:12:33 +0000 (16:12 +0000)
In the KDC, set up signals in the worker process child after forking
from the monitor process.  From npmccallum@redhat.com.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25176 dc483132-0cff-0310-8789-dd5450dbe970

src/include/net-server.h
src/kadmin/server/ovsec_kadmd.c
src/kdc/main.c
src/lib/apputils/net-server.c

index b8414a158a6d1e25ac780e38acedd02cc39faa18..66bedf63aaf43ff173a2b91297f8b84de37e6517 100644 (file)
@@ -40,7 +40,7 @@ typedef struct _krb5_fulladdr {
 void init_addr(krb5_fulladdr *, struct sockaddr *);
 
 /* exported from net-server.c */
-verto_ctx *loop_init(verto_ev_type types, void *handle, void (*reset)());
+verto_ctx *loop_init(verto_ev_type types);
 krb5_error_code loop_add_udp_port(int port);
 krb5_error_code loop_add_tcp_port(int port);
 krb5_error_code loop_add_rpc_service(int port, u_long prognum, u_long versnum,
@@ -49,6 +49,8 @@ krb5_error_code loop_setup_routing_socket(verto_ctx *ctx, void *handle,
                                           const char *progname);
 krb5_error_code loop_setup_network(verto_ctx *ctx, void *handle,
                                    const char *progname);
+krb5_error_code loop_setup_signals(verto_ctx *ctx, void *handle,
+                                   void (*reset)());
 void loop_free(verto_ctx *ctx);
 
 /* to be supplied by the server application */
index fac5ccd2491822d72089819e15be15786f97ba26..63d1787cbc1b9ca4e2732ce3ba88d449cd0e92c8 100644 (file)
@@ -357,7 +357,7 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
-    ctx = loop_init(VERTO_EV_TYPE_SIGNAL, global_server_handle, NULL);
+    ctx = loop_init(VERTO_EV_TYPE_SIGNAL);
     if (!ctx) {
         krb5_klog_syslog(LOG_ERR,
                          _("%s: could not initialize loop, aborting"),
@@ -369,6 +369,18 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
+    if ((ret = loop_setup_signals(ctx, global_server_handle, NULL))) {
+        const char *e_txt = krb5_get_error_message (context, ret);
+        krb5_klog_syslog(LOG_ERR, _("%s: %s while initializing signal "
+                                    "handlers, aborting"), whoami, e_txt);
+        fprintf(stderr, _("%s: %s while initializing signal "
+                          "handlers, aborting\n"), whoami, e_txt);
+        loop_free(ctx);
+        kadm5_destroy(global_server_handle);
+        krb5_klog_close(context);
+        exit(1);
+    }
+
 #define server_handle ((kadm5_server_handle_t)global_server_handle)
     if ((ret = loop_add_udp_port(server_handle->params.kpasswd_port))
         || (ret = loop_add_tcp_port(server_handle->params.kpasswd_port))
index c978a77a9c69a6a8428ad6b740a932ebf4707bc2..15a5a9ee7fc999945363017c8708dd3374230f98 100644 (file)
@@ -536,6 +536,7 @@ terminate_workers(pid_t *pids, int bound, int num_active)
 static krb5_error_code
 create_workers(verto_ctx *ctx, int num)
 {
+    krb5_error_code retval;
     int i, status, numleft;
     pid_t pid, *pids;
 #ifdef POSIX_SIGNALS
@@ -551,6 +552,16 @@ create_workers(verto_ctx *ctx, int num)
         pid = fork();
         if (pid == 0) {
             verto_reinitialize(ctx);
+            retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
+            if (retval) {
+                krb5_klog_syslog(LOG_ERR, _("Unable to initialize signal "
+                                            "handlers in pid %d"), pid);
+                return retval;
+            }
+
+            /* Avoid race condition */
+            if (signal_received)
+                exit(0);
 
             /* Return control to main() in the new worker process. */
             free(pids);
@@ -984,7 +995,7 @@ int main(int argc, char **argv)
      */
     initialize_realms(kcontext, argc, argv);
 
-    ctx = loop_init(VERTO_EV_TYPE_NONE, NULL, reset_for_hangup);
+    ctx = loop_init(VERTO_EV_TYPE_NONE);
     if (!ctx) {
         kdc_err(kcontext, ENOMEM, _("while creating main loop"));
         finish_realms();
@@ -1046,6 +1057,12 @@ int main(int argc, char **argv)
             finish_realms();
             return 1;
         }
+        retval = loop_setup_signals(ctx, NULL, reset_for_hangup);
+        if (retval) {
+            kdc_err(kcontext, retval, _("while initializing signal handlers"));
+            finish_realms();
+            return 1;
+        }
     }
     if ((retval = loop_setup_network(ctx, NULL, kdc_progname))) {
     net_init_error:
index 546ed769ea2ffd7bfa00c5a66237653e9cafbc14..af6552521e50ae962c0d0b1b1ec798c32fbaad6e 100644 (file)
@@ -270,6 +270,20 @@ static SET(unsigned short) udp_port_data, tcp_port_data;
 static SET(struct rpc_svc_data) rpc_svc_data;
 static SET(verto_ev *) events;
 
+verto_ctx *
+loop_init(verto_ev_type types)
+{
+    types |= VERTO_EV_TYPE_IO;
+    types |= VERTO_EV_TYPE_SIGNAL;
+    types |= VERTO_EV_TYPE_TIMEOUT;
+
+#ifdef INTERNAL_VERTO
+    return verto_default_k5ev();
+#else
+    return verto_default(NULL, types);
+#endif
+}
+
 static void
 do_break(verto_ctx *ctx, verto_ev *ev)
 {
@@ -299,43 +313,30 @@ free_sighup_context(verto_ctx *ctx, verto_ev *ev)
     free(verto_get_private(ev));
 }
 
-verto_ctx *
-loop_init(verto_ev_type types, void *handle, void (*reset)())
+krb5_error_code
+loop_setup_signals(verto_ctx *ctx, void *handle, void (*reset)())
 {
     struct sighup_context *sc;
-    verto_ctx *ctx;
-    verto_ev  *ev;
+    verto_ev *ev;
 
-    types |= VERTO_EV_TYPE_IO;
-    types |= VERTO_EV_TYPE_SIGNAL;
-    types |= VERTO_EV_TYPE_TIMEOUT;
-#ifdef INTERNAL_VERTO
-    ctx = verto_default_k5ev();
-#else
-    ctx = verto_default(NULL, types);
-#endif
     if (!verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGINT)  ||
         !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGTERM) ||
         !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_break, SIGQUIT) ||
         !verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, VERTO_SIG_IGN, SIGPIPE))
-        goto error;
+        return ENOMEM;
 
     ev = verto_add_signal(ctx, VERTO_EV_FLAG_PERSIST, do_reset, SIGHUP);
     if (!ev)
-        goto error;
+        return ENOMEM;
 
     sc = malloc(sizeof(*sc));
     if (!sc)
-        goto error;
+        return ENOMEM;
+
     sc->handle = handle;
     sc->reset = reset;
-
     verto_set_private(ev, sc, free_sighup_context);
-    return ctx;
-
-error:
-    verto_free(ctx);
-    return NULL;
+    return 0;
 }
 
 krb5_error_code