From 232ee45a29845cc8b31955bdc398ac335421e63c Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Wed, 14 Sep 2011 16:12:33 +0000 Subject: [PATCH] Split signal setup into loop_setup_signals() 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 | 4 ++- src/kadmin/server/ovsec_kadmd.c | 14 ++++++++++- src/kdc/main.c | 19 ++++++++++++++- src/lib/apputils/net-server.c | 43 +++++++++++++++++---------------- 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/include/net-server.h b/src/include/net-server.h index b8414a158..66bedf63a 100644 --- a/src/include/net-server.h +++ b/src/include/net-server.h @@ -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 */ diff --git a/src/kadmin/server/ovsec_kadmd.c b/src/kadmin/server/ovsec_kadmd.c index fac5ccd24..63d1787cb 100644 --- a/src/kadmin/server/ovsec_kadmd.c +++ b/src/kadmin/server/ovsec_kadmd.c @@ -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)) diff --git a/src/kdc/main.c b/src/kdc/main.c index c978a77a9..15a5a9ee7 100644 --- a/src/kdc/main.c +++ b/src/kdc/main.c @@ -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: diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c index 546ed769e..af6552521 100644 --- a/src/lib/apputils/net-server.c +++ b/src/lib/apputils/net-server.c @@ -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 -- 2.26.2