]> arthur.barton.de Git - netatalk.git/commitdiff
Fix keep session stuff
authorFrank Lahm <franklahm@googlemail.com>
Sat, 24 Mar 2012 13:15:03 +0000 (14:15 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Sat, 24 Mar 2012 13:15:03 +0000 (14:15 +0100)
etc/cnid_dbd/cnid_metad.c
etc/netatalk/netatalk.c
man/man5/afp.conf.5.tmpl

index dcc70123b7e19676988f9cbef4ed9ac8fd59c301..d6fbcb060696c3b502a1cc5ee2196a31b0380f58 100644 (file)
@@ -128,11 +128,13 @@ static void daemon_exit(int i)
 }
 
 /* ------------------ */
-static void sigterm_handler(int sig)
+static void sig_handler(int sig)
 {
     switch( sig ) {
-    case SIGTERM :
-        LOG(log_info, logtype_afpd, "shutting down on signal %d", sig );
+    case SIGTERM:
+    case SIGQUIT:
+        LOG(log_note, logtype_afpd, "shutting down on %s",
+            sig == SIGTERM ? "SIGTERM" : "SIGQUIT");
         break;
     default :
         LOG(log_error, logtype_afpd, "unexpected signal: %d", sig);
@@ -380,13 +382,17 @@ static void set_signal(void)
         daemon_exit(EXITERR_SYS);
     }
 
-    /* Catch SIGTERM */
-    sv.sa_handler = sigterm_handler;
+    /* Catch SIGTERM and SIGQUIT */
+    sv.sa_handler = sig_handler;
     sigfillset(&sv.sa_mask );
     if (sigaction(SIGTERM, &sv, NULL ) < 0 ) {
         LOG(log_error, logtype_afpd, "sigaction: %s", strerror(errno) );
         daemon_exit(EXITERR_SYS);
     }
+    if (sigaction(SIGQUIT, &sv, NULL ) < 0 ) {
+        LOG(log_error, logtype_afpd, "sigaction: %s", strerror(errno) );
+        daemon_exit(EXITERR_SYS);
+    }
 
     /* Ignore the rest */
     sv.sa_handler = SIG_IGN;
index ec323e218bb076eb669aa0c99a8f9037949c47c4..7c7f1003fbfaa2a2f6a6527b2457774566ead0e2 100644 (file)
@@ -40,7 +40,7 @@
 
 /* forward declaration */
 static pid_t run_process(const char *path, ...);
-static void kill_childs(int count, int sig, ...);
+static void kill_childs(int sig, ...);
 
 /* static variables */
 static AFPObj obj;
@@ -93,8 +93,7 @@ static void sigterm_cb(evutil_socket_t fd, short what, void *arg)
 static void sigquit_cb(evutil_socket_t fd, short what, void *arg)
 {
     LOG(log_note, logtype_afpd, "Exiting on SIGQUIT");
-    in_shutdown = 1;
-    event_base_loopbreak(base);
+    kill_childs(SIGQUIT, &afpd_pid, &cnid_metad_pid, NULL);
 }
 
 /* SIGCHLD callback */
@@ -153,16 +152,15 @@ static void sigchld_cb(evutil_socket_t fd, short what, void *arg)
  * helper functions
  ******************************************************************/
 
-/* kill "count" processes passed as varargs of type "pid_t *" */
-static void kill_childs(int count, int sig, ...)
+/* kill processes passed as varargs of type "pid_t *", terminate list with NULL */
+static void kill_childs(int sig, ...)
 {
     va_list args;
     pid_t *pid;
 
     va_start(args, sig);
 
-    while (count--) {
-        pid = va_arg(args, pid_t *);
+    while ((pid = va_arg(args, pid_t *)) != NULL) {
         if (*pid == -1)
             continue;
         kill(*pid, sig);
@@ -272,7 +270,7 @@ 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, sigquit_cb, NULL);
+    sigquit_ev = event_new(base, SIGQUIT, EV_SIGNAL | EV_PERSIST, sigquit_cb, NULL);
     sigchld_ev = event_new(base, SIGCHLD, EV_SIGNAL | EV_PERSIST, sigchld_cb, NULL);
 
     event_add(sigterm_ev, NULL);
@@ -288,7 +286,7 @@ int main(int argc, char **argv)
     /* run the event loop */
     ret = event_base_dispatch(base);
 
-    /* got SIGTERM or similar, so we're going to shutdown */
+    /* got SIGTERM so we're going to shutdown */
 
     /* block any signal but SIGCHLD */
     sigfillset(&blocksigs);
@@ -304,7 +302,7 @@ int main(int argc, char **argv)
     event_del(sigquit_ev);
 
     /* run the event loop again, waiting for child to exit on SIGTERM for KILL_GRACETIME seconds */
-    kill_childs(2, SIGTERM, &afpd_pid, &cnid_metad_pid);
+    kill_childs(SIGTERM, &afpd_pid, &cnid_metad_pid, NULL);
     ret = event_base_dispatch(base);
 
     if (afpd_pid != -1 || cnid_metad_pid != -1) {
@@ -312,7 +310,7 @@ int main(int argc, char **argv)
             LOG(log_error, logtype_afpd, "AFP service did not shutdown, killing it");
         if (cnid_metad_pid != -1)
             LOG(log_error, logtype_afpd, "CNID database service did not shutdown, killing it");
-        kill_childs(2, SIGKILL, &afpd_pid, &cnid_metad_pid);
+        kill_childs(SIGKILL, &afpd_pid, &cnid_metad_pid, NULL);
     }
     netatalk_exit(ret);
 }
index af6bb4ea0a9408a3b6f05236a0fbac6707913b38..6f2a7515c77281c1ca141867587218d18435cb6d 100644 (file)
@@ -372,7 +372,7 @@ Search scope for user search:
 .sp
 .RE
 .PP
-ldap uuuid attr = \fIdn\fR \fB(G)\fR
+ldap uuid attr = \fIdn\fR \fB(G)\fR
 .RS 4
 Name of the LDAP attribute with the UUIDs\&.
 .sp
@@ -665,7 +665,9 @@ Use the platform\-specific icon\&. Mac OS X doesn\'t display it\&.
 .PP
 keep sessions = \fIBOOLEAN\fR (default: \fIno\fR) \fB(G)\fR
 .RS 4
-Enable "Continuous AFP Service"\&. This means the ability to stop the master afpd process with a SIGQUIT signal, possibly install an afpd update and start the afpd process\&. Existing AFP sessions afpd processes will remain unaffected\&. Technically they will be notified of the master afpd shutdown, sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. If this reconnect fails, the sessions are in an undefined state\&. Therefor it\'s absolutely critical to restart the master process in time!
+Enable "Continuous AFP Service"\&. This means restarting AFP and CNID service daemons master processes, but keeping the AFP session processes\&. This can be used to install (most) updates to Netatalk without interruping active AFP sessions\&. Existing AFP sessions will still run the version from before updating, but new AFP sessions will run the updated code\&. After enabling this option when sending SIGQUIT to the
+\fInetatalk\fR
+service controller process, the AFP and CNID daemons will exit and then the service controller will restart them\&. AFP session processes are notified of the master afpd shutdown, they will then sleep 15\-20 seconds and then try to reconnect their IPC channel to the master afpd process\&. The IPC channel between the AFP master service daemon and the AFP session child is used for keeping session state of AFP sessions in the AFP master process\&. The session state is needed when AFP clients experience eg network outages and try to reconnect to the AFP server\&.
 .RE
 .PP
 map acls = \fIBOOLEAN\fR (default: \fIyes\fR) \fB(G)\fR