- the master process allowed to restart the slave process when it disappears
authorDaniel Kouřil <kouril@ics.muni.cz>
Mon, 14 Mar 2005 21:10:23 +0000 (21:10 +0000)
committerDaniel Kouřil <kouril@ics.muni.cz>
Mon, 14 Mar 2005 21:10:23 +0000 (21:10 +0000)
- the slave process commits suicide after 1000 renewal attempts (this should prevent from problems with memory leaks in myproxy/globus libraries).
- signals handled properly

org.glite.security.proxyrenewal/src/renew.c
org.glite.security.proxyrenewal/src/renewal_locl.h
org.glite.security.proxyrenewal/src/renewd.c

index 6c6e577..35df781 100644 (file)
@@ -7,6 +7,8 @@
 
 #ident "$Header$"
 
+#define RENEWAL_COUNTS_MAX     1000    /* the slave daemon exits after that many attemtps */
+
 extern char *repository;
 extern char *cadir;
 extern char *vomsdir;
@@ -14,10 +16,10 @@ extern int voms_enabled;
 extern char *vomsconf;
 extern struct vomses_records vomses;
 
-static int received_signal = -1;
+static int received_signal = -1, die = 0;
 
 static void
-check_renewal(char *datafile, int force_renew);
+check_renewal(char *datafile, int force_renew, int *num_renewed);
 
 static int
 renew_proxy(proxy_record *record, char *basename, char **new_proxy);
@@ -835,6 +837,15 @@ static void
 register_signal(int signal)
 {
       received_signal = signal;
+      switch ((received_signal = signal)) {
+        case SIGINT:
+        case SIGTERM:
+        case SIGQUIT:
+           die = signal;
+           break;
+        default:
+           break;
+      }
 }
 
 static int
@@ -950,7 +961,7 @@ end:
 }
 
 static void
-check_renewal(char *datafile, int force_renew)
+check_renewal(char *datafile, int force_renew, int *num_renewed)
 {
    char line[1024];
    proxy_record record;
@@ -968,6 +979,8 @@ check_renewal(char *datafile, int force_renew)
 
    assert(datafile != NULL);
 
+   *num_renewed = 0;
+
    memset(&record, 0, sizeof(record));
    memset(basename, 0, sizeof(basename));
    memset(&request, 0, sizeof(request));
@@ -1054,17 +1067,22 @@ check_renewal(char *datafile, int force_renew)
    edg_wlpr_CleanResponse(&response);
    edg_wlpr_CleanRequest(&request);
 
+   *num_renewed = num;
+
    return;
 }
 
-int renewal(int force_renew)
+int renewal(int force_renew, int *num_renewed)
 {
    DIR *dir = NULL;
    struct dirent *file;
    FILE *fd;
+   int num = 0;
 
    edg_wlpr_Log(LOG_DEBUG, "Starting renewal process");
 
+   *num_renewed = 0;
+
    if (chdir(repository)) {
       edg_wlpr_Log(LOG_ERR, "Cannot access repository directory %s (%s)",
                   repository, strerror(errno));
@@ -1090,7 +1108,8 @@ int renewal(int force_renew)
                      file->d_name, strerror(errno));
         continue;
       }
-      check_renewal(file->d_name, force_renew);
+      check_renewal(file->d_name, force_renew, &num);
+      *num_renewed += num;
       fclose(fd);
    }
    closedir(dir);
@@ -1103,18 +1122,28 @@ watchdog_start(void)
 {
    struct sigaction sa;
    int force_renewal;
+   int count = 0, num;
    
    memset(&sa,0,sizeof(sa));
    sa.sa_handler = register_signal;
    sigaction(SIGUSR1, &sa, NULL);
+   sigaction(SIGINT,&sa,NULL);
+   sigaction(SIGQUIT,&sa,NULL);
+   sigaction(SIGTERM,&sa,NULL);
+   sigaction(SIGPIPE,&sa,NULL);
 
    /* load_vomses(); */
 
-   while (1) {
+   while (count < RENEWAL_COUNTS_MAX && !die) {
        received_signal = -1;
        sleep(60 * 5);
        force_renewal = (received_signal == SIGUSR1) ? 1 : 0;
+       if (die)
+         break;
        /* XXX uninstall signal handler ? */
-       renewal(force_renewal);
+       renewal(force_renewal, &num);
+       count += num;
    }
+   edg_wlpr_Log(LOG_DEBUG, "Terminating after %d renewal attempts", count);
+   exit(0);
 }
index 45317e3..6ebc8c4 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/file.h>
+#include <sys/wait.h>
 #include <openssl/md5.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
index adebb09..29e4dbb 100644 (file)
@@ -19,6 +19,8 @@ char *vomsconf = "/opt/edg/etc/vomses";
 struct vomses_records vomses;
 #endif
 
+static volatile int die = 0, child_died = 0;
+
 static struct option opts[] = {
    { "help",       no_argument,       NULL,  'h' },
    { "version",    no_argument,       NULL,  'v' },
@@ -71,6 +73,26 @@ doit(int sock);
 static int
 decode_request(const char *msg, const size_t msg_len, edg_wlpr_Request *request);
 
+int
+start_watchdog(pid_t *pid);
+
+static void
+catchsig(int sig)
+{
+   switch (sig) {
+      case SIGINT:
+      case SIGTERM:
+      case SIGQUIT:
+        die = sig;
+        break;
+      case SIGCHLD:
+        child_died = 1;
+        break;
+      default:
+        break;
+   }
+}
+
 static command_table *
 find_command(edg_wlpr_Command code)
 {
@@ -158,44 +180,36 @@ doit(int sock)
    proxies[0] = NULL;
 #endif
 
-#if 0
-   sigemptyset(&sset);
-   sigaddset(&sset,SIGTERM);
-   sigaddset(&sset,SIGINT);
-   sigaddset(&sset, SIGKILL);
-   sigaddset(&sset, SIGUSR1);
-   sigaddset(&sset, SIGALRM);
-   sigprocmask(SIG_BLOCK,&sset,NULL);
-#endif
+   while (!die) {
 
-   while (1) {
-#if 0
-      sigprocmask(SIG_UNBLOCK,&sset,NULL);
-      newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
-      sigprocmask(SIG_BLOCK,&sset,NULL);
+      if (child_died) {
+        int pid, newpid, ret;
 
-      if (newsock == -1) {
-         if (errno == EINTR) /* ERESTARTSYS */
-             proxy_renewal(received_signal);
-         else
-            log();
-         continue;
+        while ((pid=waitpid(-1,NULL,WNOHANG))>0)
+           ;
+        ret = start_watchdog(&newpid);
+        if (ret)
+           return ret;
+        edg_wlpr_Log(LOG_DEBUG, "Renewal slave process re-started");
+        child_died = 0;
+        continue;
       }
-#else
+
       newsock = accept(sock, (struct sockaddr *) &client_addr, &client_addr_len);
       if (newsock == -1) {
-         edg_wlpr_Log(LOG_ERR, "accept() failed");
+        if (errno != EINTR)
+           edg_wlpr_Log(LOG_ERR, "accept() failed");
          continue;
       }
       edg_wlpr_Log(LOG_DEBUG, "Got connection");
 
-#endif
-
       proto(newsock);
 
       edg_wlpr_Log(LOG_DEBUG, "Connection closed");
       close(newsock);
    }
+   edg_wlpr_Log(LOG_DEBUG, "Terminating on signal %d\n",die);
+   return 0;
 }
 
 static int
@@ -571,6 +585,7 @@ int main(int argc, char *argv[])
    char  sockname[PATH_MAX];
    int   ret;
    pid_t pid;
+   struct sigaction    sa;
 
    progname = strrchr(argv[0],'/');
    if (progname) progname++; 
@@ -631,7 +646,15 @@ int main(int argc, char *argv[])
          setenv("PATH", new_path, 1);
       }
    }
-   
+
+   memset(&sa,0,sizeof(sa));
+   sa.sa_handler = catchsig;
+   sigaction(SIGINT,&sa,NULL);
+   sigaction(SIGQUIT,&sa,NULL);
+   sigaction(SIGTERM,&sa,NULL);
+   sigaction(SIGCHLD,&sa,NULL);
+   sigaction(SIGPIPE,&sa,NULL);
+
    ret = start_watchdog(&pid);
    if (ret)
       return 1;
@@ -645,22 +668,6 @@ int main(int argc, char *argv[])
       return 1;
    edg_wlpr_Log(LOG_DEBUG, "Listening at %s", sockname);
 
-#if 0
-   /* XXX ??? */
-   install_handlers();
-#endif
-   
-
-#if 0
-   /* XXX this overrides setings done by install_handlers()? */
-   signal(SIGTERM, cleanup);
-   signal(SIGINT, cleanup);
-   signal(SIGKILL, cleanup);
-   signal(SIGPIPE, SIG_IGN);
-
-   atexit(cleanup);
-#endif
-
    ret = doit(sock);
 
    close(sock);