From 3061b866610c4c706ddf36a916bdd4632bb06710 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 2 May 1995 15:25:59 +0000 Subject: [PATCH] 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. --- kernel/default.res | 3 +- kernel/monitor.c | 197 +++++++++++++++++++++++++++++++++++++++------------- kernel/persist.c | 10 ++- 3 files changed, 160 insertions(+), 50 deletions(-) diff --git a/kernel/default.res b/kernel/default.res index e25323f..71105be 100644 --- a/kernel/default.res +++ b/kernel/default.res @@ -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 diff --git a/kernel/monitor.c b/kernel/monitor.c index 9f5f79a..405369b 100644 --- a/kernel/monitor.c +++ b/kernel/monitor.c @@ -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 @@ -30,16 +36,40 @@ #include #include -#include +#include #include #include #include #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); } - - - - diff --git a/kernel/persist.c b/kernel/persist.c index 9158d40..6e4e174 100644 --- a/kernel/persist.c +++ b/kernel/persist.c @@ -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, -- 1.7.10.4