X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fnetatalk%2Fnetatalk.c;h=bbae394ccc49b4a4802b3382e522c60fd45ef852;hb=59ba70c884ca7356e28873fccab7d3611369e6cc;hp=7c7f1003fbfaa2a2f6a6527b2457774566ead0e2;hpb=a0e6244c0526e79d3455ffee71bb9d36b49df4a6;p=netatalk.git diff --git a/etc/netatalk/netatalk.c b/etc/netatalk/netatalk.c index 7c7f1003..bbae394c 100644 --- a/etc/netatalk/netatalk.c +++ b/etc/netatalk/netatalk.c @@ -48,7 +48,7 @@ static sig_atomic_t got_chldsig; static pid_t afpd_pid = -1, cnid_metad_pid = -1; static uint afpd_restarts, cnid_metad_restarts; static struct event_base *base; -struct event *sigterm_ev, *sigquit_ev, *sigchld_ev; +struct event *sigterm_ev, *sigquit_ev, *sigchld_ev, *timer_ev; static int in_shutdown; /****************************************************************** @@ -84,9 +84,29 @@ static void libevent_logmsg_cb(int severity, const char *msg) /* SIGTERM callback */ static void sigterm_cb(evutil_socket_t fd, short what, void *arg) { - LOG(log_note, logtype_afpd, "Exiting on SIGTERM"); + sigset_t sigs; + struct timeval tv; + + LOG(log_info, logtype_afpd, "Exiting on SIGTERM"); + + if (in_shutdown) + return; in_shutdown = 1; - event_base_loopbreak(base); + + /* block any signal but SIGCHLD */ + sigfillset(&sigs); + sigdelset(&sigs, SIGCHLD); + sigprocmask(SIG_SETMASK, &sigs, NULL); + + /* add 10 sec timeout timer, remove all events but SIGCHLD */ + tv.tv_sec = KILL_GRACETIME; + tv.tv_usec = 0; + event_base_loopexit(base, &tv); + event_del(sigterm_ev); + event_del(sigquit_ev); + event_del(timer_ev); + + kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, NULL); } /* SIGQUIT callback */ @@ -96,6 +116,13 @@ static void sigquit_cb(evutil_socket_t fd, short what, void *arg) kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL); } +/* SIGQUIT callback */ +static void sighup_cb(evutil_socket_t fd, short what, void *arg) +{ + LOG(log_note, logtype_afpd, "Received SIGHUP, sending all processes signal to reload config"); + kill_childs(SIGHUP, &afpd_pid, &cnid_metad_pid, NULL); +} + /* SIGCHLD callback */ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) { @@ -117,37 +144,43 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg) LOG(log_info, logtype_afpd, "child[%d]: died", pid); } - if (pid == afpd_pid) { - if (in_shutdown) { - afpd_pid = -1; - } else { - sleep(1); - afpd_restarts++; - LOG(log_note, logtype_afpd, "Restarting 'afpd' (restarts: %u)", afpd_restarts); - if ((afpd_pid = run_process(_PATH_AFPD, "-d", "-F", obj.options.configfile, NULL)) == -1) { - LOG(log_error, logtype_afpd, "Error starting 'afpd'"); - } - } - } else if (pid = cnid_metad_pid) { - if (in_shutdown) { - cnid_metad_pid = -1; - } else { - sleep(1); - cnid_metad_restarts++; - LOG(log_note, logtype_afpd, "Restarting 'cnid_metad' (restarts: %u)", cnid_metad_restarts); - if ((cnid_metad_pid = run_process(_PATH_CNID_METAD, "-d", "-F", obj.options.configfile, NULL)) == -1) { - LOG(log_error, logtype_afpd, "Error starting 'cnid_metad'"); - } - } - } else { + if (pid == afpd_pid) + afpd_pid = -1; + else if (pid = cnid_metad_pid) + cnid_metad_pid = -1; + else LOG(log_error, logtype_afpd, "Bad pid: %d", pid); - } } if (in_shutdown && afpd_pid == -1 && cnid_metad_pid == -1) event_base_loopbreak(base); } +/* timer callback */ +static void timer_cb(evutil_socket_t fd, short what, void *arg) +{ + static int i = 0; + + if (in_shutdown) + return; + + if (afpd_pid == -1) { + afpd_restarts++; + LOG(log_note, logtype_afpd, "Restarting 'afpd' (restarts: %u)", afpd_restarts); + if ((afpd_pid = run_process(_PATH_AFPD, "-d", "-F", obj.options.configfile, NULL)) == -1) { + LOG(log_error, logtype_afpd, "Error starting 'afpd'"); + } + } + + if (cnid_metad_pid == -1) { + cnid_metad_restarts++; + LOG(log_note, logtype_afpd, "Restarting 'cnid_metad' (restarts: %u)", cnid_metad_restarts); + if ((cnid_metad_pid = run_process(_PATH_CNID_METAD, "-d", "-F", obj.options.configfile, NULL)) == -1) { + LOG(log_error, logtype_afpd, "Error starting 'cnid_metad'"); + } + } +} + /****************************************************************** * helper functions ******************************************************************/ @@ -214,6 +247,7 @@ int main(int argc, char **argv) const char *configfile = NULL; int c, ret, debug = 0; sigset_t blocksigs; + struct timeval tv; /* Log SIGBUS/SIGSEGV SBT */ fault_setup(NULL); @@ -244,11 +278,9 @@ int main(int argc, char **argv) sigfillset(&blocksigs); sigprocmask(SIG_SETMASK, &blocksigs, NULL); - if (afp_config_parse(&obj) != 0) + if (afp_config_parse(&obj, "netatalk") != 0) netatalk_exit(EXITERR_CONF); - set_processname("netatalk"); - setuplog(obj.options.logconfig, obj.options.logfile); event_set_log_callback(libevent_logmsg_cb); event_set_fatal_callback(netatalk_exit); @@ -271,40 +303,28 @@ int main(int argc, char **argv) sigterm_ev = event_new(base, SIGTERM, EV_SIGNAL, sigterm_cb, NULL); sigquit_ev = event_new(base, SIGQUIT, EV_SIGNAL | EV_PERSIST, sigquit_cb, NULL); + sigquit_ev = event_new(base, SIGHUP, EV_SIGNAL | EV_PERSIST, sighup_cb, NULL); sigchld_ev = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, sigchld_cb, NULL); + timer_ev = event_new(base, -1, EV_PERSIST, timer_cb, NULL); + + tv.tv_sec = 1; + tv.tv_usec = 0; event_add(sigterm_ev, NULL); event_add(sigquit_ev, NULL); event_add(sigchld_ev, NULL); + event_add(timer_ev, &tv); sigfillset(&blocksigs); sigdelset(&blocksigs, SIGTERM); sigdelset(&blocksigs, SIGQUIT); sigdelset(&blocksigs, SIGCHLD); + sigdelset(&blocksigs, SIGHUP); sigprocmask(SIG_SETMASK, &blocksigs, NULL); /* run the event loop */ ret = event_base_dispatch(base); - /* got SIGTERM so we're going to shutdown */ - - /* block any signal but SIGCHLD */ - sigfillset(&blocksigs); - sigdelset(&blocksigs, SIGCHLD); - sigprocmask(SIG_SETMASK, &blocksigs, NULL); - - /* setup new events: remove SIGTERM and SIGQUIT cbs, add timeout */ - struct timeval tv; - tv.tv_sec = KILL_GRACETIME; - tv.tv_usec = 0; - event_base_loopexit(base, &tv); - event_del(sigterm_ev); - event_del(sigquit_ev); - - /* run the event loop again, waiting for child to exit on SIGTERM for KILL_GRACETIME seconds */ - kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, NULL); - ret = event_base_dispatch(base); - if (afpd_pid != -1 || cnid_metad_pid != -1) { if (afpd_pid != -1) LOG(log_error, logtype_afpd, "AFP service did not shutdown, killing it"); @@ -312,5 +332,8 @@ int main(int argc, char **argv) LOG(log_error, logtype_afpd, "CNID database service did not shutdown, killing it"); kill_childs(SIGKILL, &afpd_pid, &cnid_metad_pid, NULL); } + + LOG(log_note, logtype_afpd, "Netatalk AFP server exiting"); + netatalk_exit(ret); }