]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/util/server_child.c
Merge branch 'sendfile' into develop
[netatalk.git] / libatalk / util / server_child.c
index 1375a63978f945433d906eeea9abec98e5fee699..b4bc3542acf562731539744a20f7f1136f718d68 100644 (file)
@@ -55,8 +55,6 @@ typedef struct server_child_fork {
     void (*cleanup)(const pid_t);
 } server_child_fork;
 
-int parent_or_child; /* 0: parent, 1: child */
-
 static inline void hash_child(struct server_child_data **htable,
                               struct server_child_data *child)
 {
@@ -129,8 +127,10 @@ afp_child_t *server_child_add(server_child *children, int forkid, pid_t pid, uin
 
     /* it's possible that the child could have already died before the
      * pthread_sigmask. we need to check for this. */
-    if (kill(pid, 0) < 0)
+    if (kill(pid, 0) < 0) {
+        LOG(log_error, logtype_default, "server_child_add: no such process pid [%d]", pid);
         goto exit;
+    }
 
     fork = (server_child_fork *) children->fork + forkid;
 
@@ -199,6 +199,7 @@ void server_child_free(server_child *children)
     server_child_fork *fork;
     struct server_child_data *child, *tmp;
     int i, j;
+    pid_t pid = getpid();
 
     for (i = 0; i < children->nforks; i++) {
         fork = (server_child_fork *) children->fork + i;
@@ -206,6 +207,9 @@ void server_child_free(server_child *children)
             child = fork->table[j]; /* start at the beginning */
             while (child) {
                 tmp = child->next;
+
+                if (child->ipc_fds[0] != -1)
+                    close(child->ipc_fds[0]);
                 if (child->clientid) {
                     free(child->clientid);
                 }
@@ -273,6 +277,16 @@ int server_child_transfer_session(server_child *children,
     fork = (server_child_fork *) children->fork + forkid;
     if ((child = resolve_child(fork->table, pid)) == NULL) {
         LOG(log_note, logtype_default, "Reconnect: no child[%u]", pid);
+        if (kill(pid, 0) == 0) {
+            LOG(log_note, logtype_default, "Reconnect: terminating old session[%u]", pid);
+            kill(pid, SIGTERM);
+            sleep(2);
+            if (kill(pid, 0) == 0) {
+                LOG(log_error, logtype_default, "Reconnect: killing old session[%u]", pid);
+                kill(pid, SIGKILL);
+                sleep(2);
+            }
+        }
         return 0;
     }
 
@@ -320,23 +334,28 @@ void server_child_kill_one_by_id(server_child *children, int forkid, pid_t pid,
             if ( child->pid != pid) {
                 if (child->idlen == idlen && memcmp(child->clientid, id, idlen) == 0) {
                     if ( child->time != boottime ) {
+                        /* Client rebooted */
                         if (uid == child->uid) {
                             kill_child(child);
-                            LOG(log_note, logtype_default, "Disconnected child[%u], client rebooted.", child->pid);
+                            LOG(log_warning, logtype_default,
+                                "Terminated disconnected child[%u], client rebooted.",
+                                child->pid);
                         } else {
-                            LOG(log_note, logtype_default, "Session with different pid[%u]", child->pid);
+                            LOG(log_warning, logtype_default,
+                                "Session with different pid[%u]", child->pid);
                         }
+                    } else {
+                        /* One client with multiple sessions */
+                        LOG(log_debug, logtype_default,
+                            "Found another session[%u] for client[%u]", child->pid, pid);
                     }
-                    if (child->killed)
-                        kill_child(child); /* this will send SIGKILL */
-                    LOG(log_note, logtype_default, "", child->pid, pid);
                 }
             } else {
                 /* update childs own slot */
                 child->time = boottime;
                 if (child->clientid)
                     free(child->clientid);
-                LOG(log_debug, logtype_default, "Setting client ID for %d", child->pid);
+                LOG(log_debug, logtype_default, "Setting client ID for %u", child->pid);
                 child->uid = uid;
                 child->valid = 1;
                 child->idlen = idlen;