Monitor observes death of child (email kernel). The number
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 2 May 1995 15:25:59 +0000 (15:25 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 2 May 1995 15:25:59 +0000 (15:25 +0000)
of simultanous processes is controlled now. Email requests are
queued if necessary. This scheme should only be forced if no kernels
are idle.

kernel/default.res
kernel/monitor.c
kernel/persist.c

index e25323f..71105be 100644 (file)
@@ -1,5 +1,5 @@
 # Email gateway - general kernel resources
-# $Id: default.res,v 1.17 1995/04/19 16:01:57 adam Exp $
+# $Id: default.res,v 1.18 1995/05/02 15:25:59 adam Exp $
 #
 # Important directories, programs, etc.
 gw.reply.mta: /usr/lib/sendmail
@@ -9,6 +9,7 @@ gw.reply.tmp.dir: /tmp
 gw.marc.log: marc.log
 gw.timeout: 20
 gw.resultset: 0
+gw.max.process: 1
 
 # Retrieval settings
 gw.ignore.which: 1
index 9f5f79a..405369b 100644 (file)
@@ -2,7 +2,13 @@
  * Europagate, 1995
  *
  * $Log: monitor.c,v $
- * Revision 1.3  1995/05/02 07:20:10  adam
+ * Revision 1.4  1995/05/02 15:26:00  adam
+ * Monitor observes death of child (email kernel). The number
+ * of simultanous processes is controlled now. Email requests are
+ * queued if necessary. This scheme should only be forced if no kernels
+ * are idle.
+ *
+ * Revision 1.3  1995/05/02  07:20:10  adam
  * Use pid of exited child to close fifos.
  *
  * Revision 1.2  1995/05/01  16:26:57  adam
 #include <sys/wait.h>
 
 #include <gw-log.h>
-#include <gw-log.h>
+#include <gw-res.h>
 #include <gip.h>
 #include <strqueue.h>
 #include <lgets.h>
 
 #define LINE_MAX 1024
 
+#define MONITOR_FIFO_S "fifo.s"
+#define MONITOR_FIFO_C "fifo.c"
+
 static char *module = "monitor";
 static jmp_buf retry_jmp;
 
+static GwRes monitor_res = NULL;
+static int no_process = 0;
+static int max_process = 1;
+static int got_sighup = 0;
+static int got_term = 0;
+const char *default_res = "default.res";
+
+static void reread_resources (void)
+{
+    if (monitor_res)
+        gw_res_close (monitor_res);
+    monitor_res = gw_res_init ();
+    if (gw_res_merge (monitor_res, default_res))
+    {
+        gw_log (GW_LOG_WARN, module, "Couldn't read resource file %s",
+                default_res);
+        exit (1);
+    }
+    max_process = atoi (gw_res_get (monitor_res, "gw.max.process", "10"));
+}
+
 struct ke_info {
     pid_t pid;
     int id;
@@ -62,15 +92,11 @@ struct ke_info *ke_info_add (int id)
     (*kip)->next = NULL;
     (*kip)->id = id;
     (*kip)->gip = NULL;
-    if (!((*kip)->queue = str_queue_mk ()))
-    {
-        gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, module, "str_queue_mk");
-        exit (1);
-    }
+    (*kip)->queue = NULL;
     return *kip;
 }
 
-void ke_info_del (void)
+static void ke_info_del (void)
 {
     struct ke_info *ki;
 
@@ -81,24 +107,31 @@ void ke_info_del (void)
     free (ki);
 }
 
-static void catchchild (int num)
+static void catch_child (int num)
 {
     pid_t pid;
     struct ke_info *ki;
 
     while ((pid=waitpid (-1, 0, WNOHANG)) > 0)
+    {
         for (ki = ke_info_list; ki; ki = ki->next)
            if (ki->pid == pid)
-           {
-                gw_log (GW_LOG_DEBUG, module, "Close of %d", ki->id);
-               if (ki->gip)
-               {
-                    gipc_close (ki->gip);
-                    gipc_destroy (ki->gip);
-                    ki->gip = NULL;
-               }
-            }
-    signal (SIGCHLD, catchchild);
+                ki->pid = -1;
+        --no_process;
+    }
+    signal (SIGCHLD, catch_child);
+}
+
+static void catch_hup (int num)
+{
+    got_sighup = 1;
+    signal (SIGHUP, catch_hup);
+}
+
+static void catch_term (int num)
+{
+    got_term = 1;
+    signal (SIGTERM, catch_term);
 }
 
 static void pipe_handle (int dummy)
@@ -142,8 +175,8 @@ static pid_t start_kernel (int argc, char **argv, int id)
     return pid;
 }
 
-static void deliver (int argc, char **argv, int id, struct str_queue *queue,
-                     GIP *gip, pid_t *pidp)
+static int deliver (int argc, char **argv, int id, struct str_queue *queue,
+                    GIP *gip, pid_t *pidp, int dont_exec)
 {
     int pass = 0;
     int r;
@@ -164,11 +197,19 @@ static void deliver (int argc, char **argv, int id, struct str_queue *queue,
     setjmp (retry_jmp);
     ++pass;
     if (pass == 1)
+    {
+        gipc_close (*gip);
         r = gipc_open (*gip, fifo_server_name, 0);
+    }
     else if (pass == 2)
     {
         pid_t pid;
 
+        if (dont_exec)
+        {
+            signal (SIGPIPE, oldsig);
+            return 0;
+        }
         mknod (fifo_server_name, S_IFIFO|0666, 0);
        pid = start_kernel (argc, argv, id);
        if (pidp)
@@ -177,8 +218,9 @@ static void deliver (int argc, char **argv, int id, struct str_queue *queue,
     }
     else
     {
+        signal (SIGPIPE, oldsig);
         gw_log (GW_LOG_WARN, module, "Cannot start kernel");
-       return;
+       return 0;
     }
     if (r < 0)
     {
@@ -195,13 +237,13 @@ static void deliver (int argc, char **argv, int id, struct str_queue *queue,
        else
        {
             gw_log (GW_LOG_WARN|GW_LOG_ERRNO, module, "gipc_open");
-           return;
        }
     }
     index = 0;
     while ((msg = str_queue_get (queue, index++)))
         gip_wline (*gip, msg);
     signal (SIGPIPE, oldsig);
+    return pass;
 }
 
 static void monitor_events (int argc, char **argv)
@@ -211,45 +253,72 @@ static void monitor_events (int argc, char **argv)
     char line_buf[1024];
     fd_set set_r;
     char command[128], *cp;
-    int no_process = 0;
-    int max_process = 4;
 
-    gip_m = gips_initialize ("fifo.s");
-    r = gips_open (gip_m, "fifo.c");
+    gip_m = gips_initialize (MONITOR_FIFO_S);
+    r = gips_open (gip_m, MONITOR_FIFO_C);
     gip_m_fd = gip_infileno (gip_m);
-    open ("fifo.s", O_WRONLY);
+    open (MONITOR_FIFO_S, O_WRONLY);
 
     while (1)
     {
         int fd_max;
        struct ke_info *ki;
 
-       while (1)
+        while (1)
         {
-            FD_ZERO (&set_r);
-            FD_SET (gip_m_fd, &set_r);
-            gw_log (GW_LOG_DEBUG, module, "set r %d", gip_m_fd);
-            fd_max = gip_m_fd;
-            
+            if (got_sighup)
+            {
+                gw_log (GW_LOG_STAT, module, "Got SIGHUP. Reading resources");
+                reread_resources ();
+                got_sighup = 0;
+            }
+            if (got_term)
+            {
+                gw_log (GW_LOG_STAT, module, "Got SIGTERM. Exiting...");
+                unlink (MONITOR_FIFO_S);
+                unlink (MONITOR_FIFO_C);
+                exit (0);
+            }
             for (ki = ke_info_list; ki; ki = ki->next)
             {
                 if (!ki->queue)
                     continue;
                 gw_log (GW_LOG_DEBUG, module, "Transfer mail to %d", ki->id);
-                deliver (argc, argv, ki->id, ki->queue, &ki->gip, &ki->pid);
-                str_queue_rm (&ki->queue);
+                r = deliver (argc, argv, ki->id, ki->queue, &ki->gip, &ki->pid,
+                             no_process >= max_process);
+                if (r == 2)
+                    ++no_process;
+                if (r == 1 || r == 2)
+                    str_queue_rm (&ki->queue);
             }
+            FD_ZERO (&set_r);
+            FD_SET (gip_m_fd, &set_r);
+            gw_log (GW_LOG_DEBUG, module, "set gip_m_fd %d", gip_m_fd);
+            fd_max = gip_m_fd;
+            
             for (ki = ke_info_list; ki; ki = ki->next)
             {
                 int fd;
-                if (ki->gip && (fd = gip_infileno (ki->gip)) != -1)
+                if (ki->gip)
                 {
-                    gw_log (GW_LOG_DEBUG, module, "set r %d", fd);
-                    FD_SET (fd, &set_r);
-                    if (fd > fd_max)
-                        fd_max = fd;
+                    if (ki->pid == -1)
+                    {
+                        gw_log (GW_LOG_DEBUG, module, "Close of %d", ki->id);
+                        gipc_close (ki->gip);
+                        gipc_destroy (ki->gip);
+                        ki->gip = NULL;
+                    }
+                    else if ((fd = gip_infileno (ki->gip)) != -1)
+                    {
+                        gw_log (GW_LOG_DEBUG, module, "set fd %d", fd);
+                        FD_SET (fd, &set_r);
+                        if (fd > fd_max)
+                            fd_max = fd;
+                    }
                 }
             }
+            gw_log (GW_LOG_DEBUG, module, "Cur/Max processes %d/%d",
+                    no_process, max_process);
             gw_log (GW_LOG_DEBUG, module, "IPC select");
             r = select (fd_max+1, &set_r, NULL, NULL, NULL);
             if (r != -1)
@@ -284,7 +353,6 @@ static void monitor_events (int argc, char **argv)
                 }
            }
        }
-
         gw_log (GW_LOG_DEBUG, module, "Testing gip_m_fd %d", gip_m_fd);
        if (FD_ISSET (gip_m_fd, &set_r))
        {
@@ -305,6 +373,16 @@ static void monitor_events (int argc, char **argv)
                 
                 new_k = ke_info_add (id);
                 gw_log (GW_LOG_DEBUG, module, "Incoming mail %d", id);
+                
+                if (!new_k->queue)
+                {
+                    if (!(new_k->queue = str_queue_mk ()))
+                    {
+                        gw_log (GW_LOG_FATAL|GW_LOG_ERRNO, module,
+                                "str_queue_mk");
+                        exit (1);
+                    }
+                }
                str_queue_enq (new_k->queue, "mail\n");
                while (lgets (line_buf, sizeof(line_buf)-1, gip_m_fd))
                    str_queue_enq (new_k->queue, line_buf);
@@ -316,16 +394,39 @@ static void monitor_events (int argc, char **argv)
 
 int main (int argc, char **argv)
 {
+    int argno = 0;
+
     gw_log_init (*argv);
-    gw_log_level (GW_LOG_ALL);
-    signal (SIGCHLD, catchchild);
+    while (++argno < argc)
+    {
+        if (argv[argno][0] == '-')
+        {
+            switch (argv[argno][1])
+            {
+            case 'H':
+                fprintf (stderr, "monitor [option..] [resource]\n");
+                fprintf (stderr, "If no resource file is given");
+                fprintf (stderr, " default.res is used\n");
+                fprintf (stderr, "Options are transferred to kernel\n");
+                exit (1);
+            case 'd':
+                gw_log_level (GW_LOG_ALL & ~RES_DEBUG);
+                break;
+            case 'D':
+                gw_log_level (GW_LOG_ALL);
+                break;
+            }
+        }
+        else
+            default_res = argv[argno];
+    }
+    reread_resources ();
+    signal (SIGCHLD, catch_child);
+    signal (SIGHUP, catch_hup);
+    signal (SIGTERM, catch_term);
 #if 0
     gw_log_file (GW_LOG_ALL, "monitor.log");
 #endif
     monitor_events (argc, argv);
     exit (0);
 }
-
-
-
-
index 9158d40..6e4e174 100644 (file)
@@ -2,7 +2,13 @@
  * Europagate, 1995
  *
  * $Log: persist.c,v $
- * Revision 1.4  1995/04/20 16:10:46  adam
+ * Revision 1.5  1995/05/02 15:26:00  adam
+ * Monitor observes death of child (email kernel). The number
+ * of simultanous processes is controlled now. Email requests are
+ * queued if necessary. This scheme should only be forced if no kernels
+ * are idle.
+ *
+ * Revision 1.4  1995/04/20  16:10:46  adam
  * Modified to work with non-blocking zass-api. Not using non-blocking
  * facility yet.
  *
@@ -234,7 +240,9 @@ int load_p_state (int userid)
         return -1;
     gw_log (GW_LOG_DEBUG, KERNEL_LOG, 
            "Reading persistence file %s (2)", fname);
+#if 0
     reopen_target ();
+#endif
     while (fgetsx (fline, 1024, inf))
     {
         gw_log (GW_LOG_DEBUG, KERNEL_LOG,