Add a .gitignore file.
[paraslash.git] / server.c
index e39354e769ec04dc629c63f0bd590df30893dc8d..90f8cd535d67ac022284118e622e8f3528cf6099 100644 (file)
--- a/server.c
+++ b/server.c
  */
 
 
-
+#include "para.h"
 #include "server.cmdline.h"
 #include "afs_common.h"
+#include "afh.h"
 #include "server.h"
 #include "vss.h"
 #include "config.h"
 #include "string.h"
 #include "ipc.h"
 #include "fd.h"
+#include "list.h"
+#include "sched.h"
 #include "signal.h"
 #include "user_list.h"
+#include "afs.h"
 
 /** define the array of error lists needed by para_server */
 INIT_SERVER_ERRLISTS;
@@ -344,6 +348,30 @@ out:
        exit(EXIT_FAILURE);
 }
 
+uint32_t afs_socket_cookie;
+static int afs_socket;
+pid_t afs_pid;
+
+static void init_afs(void)
+{
+       int ret, afs_server_socket[2];
+
+       ret = socketpair(PF_UNIX, SOCK_DGRAM, 0, afs_server_socket);
+       if (ret < 0)
+               exit(EXIT_FAILURE);
+       afs_socket_cookie = para_random((uint32_t)-1);
+       afs_pid = fork();
+       if (afs_pid < 0)
+               exit(EXIT_FAILURE);
+       if (!afs_pid) /* child (afs) */
+               afs_init(afs_socket_cookie, afs_server_socket[1]);
+       close(afs_server_socket[1]);
+       afs_socket = afs_server_socket[0];
+       PARA_INFO_LOG("afs_socket: %d, afs_socket_cookie: %u\n", afs_socket,
+               (unsigned) afs_socket_cookie);
+}
+
+
 static unsigned do_inits(int argc, char **argv)
 {
        /* connector's address information */
@@ -369,6 +397,7 @@ static unsigned do_inits(int argc, char **argv)
        vss_init();
        mmd->server_pid = getpid();
        setup_signal_handling();
+       init_afs();
        mmd_lock();
        /* init network socket */
        PARA_NOTICE_LOG("%s", "initializing tcp command socket\n");
@@ -492,23 +521,34 @@ repeat:
        status_refresh();
        if (FD_ISSET(signal_pipe, &rfds)) {
                int sig;
+               pid_t pid;
                sig = para_next_signal();
                switch (sig) {
                case SIGHUP:
                        handle_sighup();
                        break;
                case SIGCHLD:
-                       para_reap_children();
+                       for (;;) {
+                               pid = para_reap_child();
+                               if (pid <= 0)
+                                       break;
+                               if (pid != afs_pid)
+                                       continue;
+                               PARA_EMERG_LOG("fatal: afs died\n");
+                               goto genocide;
+                       }
                        break;
                /* die on sigint/sigterm. Kill all children too. */
                case SIGINT:
                case SIGTERM:
                        PARA_EMERG_LOG("terminating on signal %d\n", sig);
+genocide:
                        kill(0, SIGTERM);
                        selectors[mmd->selector_num].shutdown();
                        mutex_destroy(mmd_mutex);
                        shm_detach(mmd);
                        shm_destroy(mmd_shm_id);
+
                        exit(EXIT_FAILURE);
                }
        }