ben         96/07/16 12:39:19

  Modified:    src       CHANGES http_config.c http_config.h http_main.c
                        httpd.h  scoreboard.h
  Log:
  Graceful restart patches.
  
  Revision  Changes    Path
  1.42      +5 -0      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -C3 -r1.41 -r1.42
  *** CHANGES   1996/07/10 14:38:04     1.41
  --- CHANGES   1996/07/16 19:39:10     1.42
  ***************
  *** 1,3 ****
  --- 1,8 ----
  + Changes with Apache 1.2b1:
  + 
  +   *) Graceful restart code added. This allows the server to restart without
  +      losing current connections on receipt of signal 2 (SIGINT). [Ben 
Laurie]
  + 
    Changes with Apache 1.1.1:
    
      *) Fixed bug where Cookie module would make two entries in the
  
  
  
  1.14      +42 -1     apache/src/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_config.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -C3 -r1.13 -r1.14
  *** http_config.c     1996/06/29 19:52:11     1.13
  --- http_config.c     1996/07/16 19:39:12     1.14
  ***************
  *** 75,80 ****
  --- 75,83 ----
    #include "http_log.h"               /* for errors in parse_htaccess */
    #include "http_request.h"   /* for default_handler (see invoke_handler) */
    #include "http_conf_globals.h"      /* Sigh... */
  + #include "explain.h"
  + 
  + DEF_Explain
    
    /****************************************************************
     *
  ***************
  *** 206,211 ****
  --- 209,248 ----
        return create_empty_config (p);
    }
    
  + #ifdef EXPLAIN
  + 
  + struct
  +     {
  +     int offset;
  +     char *method;
  +     } aMethods[]=
  +     {
  + #define m(meth)     { XtOffsetOf(module,meth),#meth }
  +     m(translate_handler),
  +     m(check_user_id),
  +     m(auth_checker),
  +     m(type_checker),
  +     m(fixer_upper),
  +     m(logger),
  +     { -1,"?" },
  + #undef m
  +     };
  + 
  + char *ShowMethod(module *modp,int offset)
  +     {
  +     int n;
  +     static char buf[200];
  + 
  +     for(n=0 ; aMethods[n].offset >= 0 ; ++n)
  +     if(aMethods[n].offset == offset)
  +         break;
  +     sprintf(buf,"%s:%s",modp->name,aMethods[n].method);
  +     return buf;
  +     }
  + #else
  + #define ShowMethod(modp,offset)
  + #endif
  + 
    /****************************************************************
     *
     * Dispatch through the modules to find handlers for various phases
  ***************
  *** 221,228 ****
           handler mod_handler = *(handler *)(offset + (char *)(modp));
    
           if (mod_handler) {
  !        int result = (*mod_handler)(r);
    
           if (result != DECLINED && (!run_all || result != OK))
               return result;
           }
  --- 258,269 ----
           handler mod_handler = *(handler *)(offset + (char *)(modp));
    
           if (mod_handler) {
  !            int result;
  ! 
  !            Explain1("Run %s",ShowMethod(modp,offset));
  !        result = (*mod_handler)(r);
    
  +        Explain2("%s returned %d",ShowMethod(modp,offset),result);
           if (result != DECLINED && (!run_all || result != OK))
               return result;
           }
  
  
  
  1.7       +4 -1      apache/src/http_config.h
  
  Index: http_config.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_config.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -C3 -r1.6 -r1.7
  *** http_config.h     1996/05/27 19:48:38     1.6
  --- http_config.h     1996/07/16 19:39:12     1.7
  ***************
  *** 146,151 ****
  --- 146,154 ----
        int module_index;               /* Index to this modules structures in
                                 * config vectors.
                                 */
  + 
  +     const char *name;
  + 
        struct module_struct *next;
    
    #ifdef ULTRIX_BRAIN_DEATH
  ***************
  *** 198,204 ****
     */
    
    #define MODULE_MAGIC_NUMBER 19960526
  ! #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, NULL
    
    /* Generic accessors for other modules to get at their own module-specific
     * data
  --- 201,207 ----
     */
    
    #define MODULE_MAGIC_NUMBER 19960526
  ! #define STANDARD_MODULE_STUFF MODULE_MAGIC_NUMBER, 0, __FILE__, NULL
    
    /* Generic accessors for other modules to get at their own module-specific
     * data
  
  
  
  1.48      +193 -40   apache/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.c,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -C3 -r1.47 -r1.48
  *** http_main.c       1996/07/13 01:47:36     1.47
  --- http_main.c       1996/07/16 19:39:13     1.48
  ***************
  *** 88,93 ****
  --- 88,94 ----
    #include "http_core.h"          /* for get_remote_host */
    #include "scoreboard.h"
    #include <setjmp.h>
  + #include <assert.h>
    #ifdef HAVE_SHMGET
    #include <sys/types.h>
    #include <sys/ipc.h>
  ***************
  *** 165,171 ****
     */
    void
    accept_mutex_init(pool *p)
  ! {
        char lock_fname[30];
    
        strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX");
  --- 166,172 ----
     */
    void
    accept_mutex_init(pool *p)
  !     {
        char lock_fname[30];
    
        strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX");
  ***************
  *** 481,494 ****
     */
    
    #if defined(HAVE_MMAP)
  ! static short_score *scoreboard_image=NULL;
    
    static void setup_shared_mem(void)
    {
        caddr_t m;
    #if defined(MAP_ANON) || defined(MAP_FILE)
    /* BSD style */
  !     m = mmap((caddr_t)0, HARD_SERVER_LIMIT*sizeof(short_score),
             PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
        if (m == (caddr_t)-1)
        {
  --- 482,495 ----
     */
    
    #if defined(HAVE_MMAP)
  ! static scoreboard *scoreboard_image=NULL;
    
    static void setup_shared_mem(void)
    {
        caddr_t m;
    #if defined(MAP_ANON) || defined(MAP_FILE)
    /* BSD style */
  !     m = mmap((caddr_t)0, SCOREBOARD_SIZE,
             PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
        if (m == (caddr_t)-1)
        {
  ***************
  *** 507,513 ****
        fprintf(stderr, "httpd: Could not open /dev/zero\n");
        exit(1);
        }
  !     m = mmap((caddr_t)0, HARD_SERVER_LIMIT*sizeof(short_score),
             PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (m == (caddr_t)-1)
        {
  --- 508,514 ----
        fprintf(stderr, "httpd: Could not open /dev/zero\n");
        exit(1);
        }
  !     m = mmap((caddr_t)0, SCOREBOARD_SIZE,
             PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (m == (caddr_t)-1)
        {
  ***************
  *** 517,540 ****
        }
        close(fd);
    #endif
  !     scoreboard_image = (short_score *)m;
    }
    
    #elif defined(HAVE_SHMGET)
  ! static short_score *scoreboard_image=NULL;
    static key_t shmkey = IPC_PRIVATE;
    static int shmid = -1;
    
    static void setup_shared_mem(void)
    {
  -     int score_size = HARD_SERVER_LIMIT*sizeof(short_score);
        char errstr[MAX_STRING_LEN];
        struct shmid_ds shmbuf;
    #ifdef MOVEBREAK
        char *obrk;
    #endif
    
  !     if ((shmid = shmget(shmkey, score_size, IPC_CREAT|SHM_R|SHM_W)) == -1)
        {
        perror("shmget");
        fprintf(stderr, "httpd: Could not call shmget\n");
  --- 518,541 ----
        }
        close(fd);
    #endif
  !     scoreboard_image = (scoreboard *)m;
  !     scoreboard_image->global.exit_generation=0;
    }
    
    #elif defined(HAVE_SHMGET)
  ! static scoreboard *scoreboard_image=NULL;
    static key_t shmkey = IPC_PRIVATE;
    static int shmid = -1;
    
    static void setup_shared_mem(void)
    {
        char errstr[MAX_STRING_LEN];
        struct shmid_ds shmbuf;
    #ifdef MOVEBREAK
        char *obrk;
    #endif
    
  !     if ((shmid = shmget(shmkey, SCOREBOARD_SIZE, IPC_CREAT|SHM_R|SHM_W)) == 
-1)
        {
        perror("shmget");
        fprintf(stderr, "httpd: Could not call shmget\n");
  ***************
  *** 561,568 ****
        }
    #endif
    
  ! #define BADSHMAT    ((short_score*)(-1))
  !     if ((scoreboard_image = (short_score*)shmat(shmid, 0, 0)) == BADSHMAT)
        {
        perror("shmat");
        fprintf(stderr, "httpd: Could not call shmat\n");
  --- 562,569 ----
        }
    #endif
    
  ! #define BADSHMAT    ((scoreboard *)(-1))
  !     if ((scoreboard_image = (scoreboard *)shmat(shmid, 0, 0)) == BADSHMAT)
        {
        perror("shmat");
        fprintf(stderr, "httpd: Could not call shmat\n");
  ***************
  *** 608,617 ****
        fprintf(stderr, "httpd: Could not move break back\n");
        }
    #endif
    }
    
    #else
  ! static short_score scoreboard_image[HARD_SERVER_LIMIT];
    static int have_scoreboard_fname = 0;
    static int scoreboard_fd;
    
  --- 609,620 ----
        fprintf(stderr, "httpd: Could not move break back\n");
        }
    #endif
  +     scoreboard_image->global.exit_generation=0;
    }
    
    #else
  ! static scoreboard _scoreboard_image;
  ! static scoreboard *scoreboard_image=&_scoreboard_image;
    static int have_scoreboard_fname = 0;
    static int scoreboard_fd;
    
  ***************
  *** 649,660 ****
    /* Called by parent process */
    void reinit_scoreboard (pool *p)
    {
    #if defined(HAVE_SHMGET) || defined(HAVE_MMAP)
        if (scoreboard_image == NULL)
        {
        setup_shared_mem();
        }
  !     memset(scoreboard_image, 0, HARD_SERVER_LIMIT*sizeof(short_score));
    #else
        scoreboard_fname = server_root_relative (p, scoreboard_fname);
    
  --- 652,668 ----
    /* Called by parent process */
    void reinit_scoreboard (pool *p)
    {
  +     int exit_gen=0;
  +     if(scoreboard_image)
  +     exit_gen=scoreboard_image->global.exit_generation;
  +     
    #if defined(HAVE_SHMGET) || defined(HAVE_MMAP)
        if (scoreboard_image == NULL)
        {
        setup_shared_mem();
        }
  !     memset(scoreboard_image, 0, SCOREBOARD_SIZE);
  !     scoreboard_image->global.exit_generation=exit_gen;
    #else
        scoreboard_fname = server_root_relative (p, scoreboard_fname);
    
  ***************
  *** 673,681 ****
        exit (1);
        }
    
  !     memset ((char*)scoreboard_image, 0, sizeof(scoreboard_image));
        force_write (scoreboard_fd, (char*)scoreboard_image,
  !              sizeof(scoreboard_image));
    #endif
    }
    
  --- 681,690 ----
        exit (1);
        }
    
  !     memset ((char*)scoreboard_image, 0, sizeof(*scoreboard_image));
  !     scoreboard_image->global.exit_generation=exit_gen;
        force_write (scoreboard_fd, (char*)scoreboard_image,
  !              sizeof(*scoreboard_image));
    #endif
    }
    
  ***************
  *** 723,729 ****
    #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
        lseek (scoreboard_fd, 0L, 0);
        force_read (scoreboard_fd, (char*)scoreboard_image,
  !             sizeof(scoreboard_image));
    #endif
    }
    
  --- 732,738 ----
    #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
        lseek (scoreboard_fd, 0L, 0);
        force_read (scoreboard_fd, (char*)scoreboard_image,
  !             sizeof(*scoreboard_image));
    #endif
    }
    
  ***************
  *** 735,741 ****
        if (child_num < 0)
        return -1;
        
  !     memcpy(&new_score_rec,&scoreboard_image[child_num],sizeof 
new_score_rec);
        new_score_rec.pid = getpid();
        old_status = new_score_rec.status;
        new_score_rec.status = status;
  --- 744,750 ----
        if (child_num < 0)
        return -1;
        
  !     memcpy(&new_score_rec,&scoreboard_image->servers[child_num],sizeof 
new_score_rec);
        new_score_rec.pid = getpid();
        old_status = new_score_rec.status;
        new_score_rec.status = status;
  ***************
  *** 767,773 ****
    #endif
    
    #if defined(HAVE_MMAP) || defined(HAVE_SHMGET)
  !     memcpy(&scoreboard_image[child_num], &new_score_rec, 
sizeof(short_score));
    #else
        lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
        force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score));
  --- 776,782 ----
    #endif
    
    #if defined(HAVE_MMAP) || defined(HAVE_SHMGET)
  !     memcpy(&scoreboard_image->servers[child_num], &new_score_rec, sizeof 
new_score_rec);
    #else
        lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
        force_write (scoreboard_fd, (char*)&new_score_rec, sizeof(short_score));
  ***************
  *** 776,787 ****
        return old_status;
    }
    
    int get_child_status (int child_num)
    {
        if (child_num<0 || child_num>=HARD_SERVER_LIMIT)
                return -1;
        else
  !     return scoreboard_image[child_num].status;
    }
    
    int count_busy_servers ()
  --- 785,806 ----
        return old_status;
    }
    
  + void update_scoreboard_global()
  +     {
  + #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
  +     lseek(scoreboard_fd,
  +       (char *)&scoreboard_image->global-(char *)scoreboard_image,0);
  +     force_write(scoreboard_fd,(char *)&scoreboard_image->global,
  +             sizeof scoreboard_image->global);
  + #endif
  +     }
  + 
    int get_child_status (int child_num)
    {
        if (child_num<0 || child_num>=HARD_SERVER_LIMIT)
                return -1;
        else
  !     return scoreboard_image->servers[child_num].status;
    }
    
    int count_busy_servers ()
  ***************
  *** 790,807 ****
        int res = 0;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !       if (scoreboard_image[i].status == SERVER_BUSY_READ ||
  !               scoreboard_image[i].status == SERVER_BUSY_WRITE ||
  !               scoreboard_image[i].status == SERVER_BUSY_KEEPALIVE ||
  !               scoreboard_image[i].status == SERVER_BUSY_LOG ||
  !               scoreboard_image[i].status == SERVER_BUSY_DNS)
              ++res;
        return res;
    }
    
    short_score get_scoreboard_info(int i)
    {
  !     return (scoreboard_image[i]);
    }
    
    #if defined(STATUS)
  --- 809,837 ----
        int res = 0;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !       if (scoreboard_image->servers[i].status == SERVER_BUSY_READ ||
  !               scoreboard_image->servers[i].status == SERVER_BUSY_WRITE ||
  !               scoreboard_image->servers[i].status == SERVER_BUSY_KEEPALIVE 
||
  !               scoreboard_image->servers[i].status == SERVER_BUSY_LOG ||
  !               scoreboard_image->servers[i].status == SERVER_BUSY_DNS)
              ++res;
        return res;
    }
    
  + int count_live_servers()
  +     {
  +     int i;
  +     int res = 0;
  + 
  +     for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  +       if (scoreboard_image->servers[i].status != SERVER_DEAD)
  +       ++res;
  +     return res;
  +     }
  + 
    short_score get_scoreboard_info(int i)
    {
  !     return (scoreboard_image->servers[i]);
    }
    
    #if defined(STATUS)
  ***************
  *** 845,852 ****
        int res = 0;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image[i].status == SERVER_READY
  !       || scoreboard_image[i].status == SERVER_STARTING)
            ++res;
    
        return res;
  --- 875,882 ----
        int res = 0;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image->servers[i].status == SERVER_READY
  !       || scoreboard_image->servers[i].status == SERVER_STARTING)
            ++res;
    
        return res;
  ***************
  *** 857,863 ****
        int i;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image[i].status == SERVER_DEAD)
            return i;
    
        return -1;
  --- 887,893 ----
        int i;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image->servers[i].status == SERVER_DEAD)
            return i;
    
        return -1;
  ***************
  *** 868,874 ****
        int i;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image[i].pid == pid)
            return i;
    
        return -1;
  --- 898,904 ----
        int i;
    
        for (i = 0; i < HARD_SERVER_LIMIT; ++i)
  !     if (scoreboard_image->servers[i].pid == pid)
            return i;
    
        return -1;
  ***************
  *** 881,890 ****
    
        sync_scoreboard_image();
        for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
  !     int pid = scoreboard_image[i].pid;
    
        if (pid != my_pid && pid != 0)
  !         waitpid (scoreboard_image[i].pid, &status, 0);
        }
    }
    
  --- 911,920 ----
    
        sync_scoreboard_image();
        for (i = 0; i < HARD_SERVER_LIMIT; ++i) {
  !     int pid = scoreboard_image->servers[i].pid;
    
        if (pid != my_pid && pid != 0)
  !         waitpid (scoreboard_image->servers[i].pid, &status, 0);
        }
    }
    
  ***************
  *** 1053,1068 ****
      }
    }
    
    void restart() {
        signal (SIGALRM, SIG_IGN);
        alarm (0);
  ! #if defined(NEXT) || defined(USE_LONGJMP)
        longjmp(restart_buffer,1);
    #else
        siglongjmp(restart_buffer,1);
    #endif
    }
    
    void set_signals() {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
  --- 1083,1114 ----
      }
    }
    
  + static int is_graceful;
  + static int generation;
  + 
    void restart() {
        signal (SIGALRM, SIG_IGN);
        alarm (0);
  !     is_graceful=0;
  ! #ifdef NEXT
        longjmp(restart_buffer,1);
    #else
        siglongjmp(restart_buffer,1);
    #endif
    }
    
  + void graceful_restart()
  +     {
  +     scoreboard_image->global.exit_generation=generation;
  +     is_graceful=1;
  +     update_scoreboard_global();
  + #if defined(NEXT) || defined(USE_LONGJMP)
  +     longjmp(restart_buffer,1);
  + #else
  +     siglongjmp(restart_buffer,1);
  + #endif
  +     }
  + 
    void set_signals() {
    #ifndef NO_USE_SIGACTION
        struct sigaction sa;
  ***************
  *** 1075,1080 ****
  --- 1121,1127 ----
    #ifdef NO_USE_SIGACTION
        signal(SIGTERM,(void (*)())sig_term);
        signal(SIGHUP,(void (*)())restart);
  +     signal(SIGINT,(void (*)())graceful_restart);
    #else
        memset(&sa,0,sizeof sa);
        sa.sa_handler=(void (*)())sig_term;
  ***************
  *** 1083,1088 ****
  --- 1130,1138 ----
        sa.sa_handler=(void (*)())restart;
        if(sigaction(SIGHUP,&sa,NULL) < 0)
        log_unixerr("sigaction(SIGHUP)", NULL, NULL, server_conf);
  +     sa.sa_handler=(void (*)())graceful_restart;
  +     if(sigaction(SIGINT,&sa,NULL) < 0)
  +     log_unixerr("sigaction(SIGINT)", NULL, NULL, server_conf);
    #endif
    }
    
  ***************
  *** 1235,1240 ****
  --- 1285,1294 ----
        clear_pool (ptrans);
        
        sync_scoreboard_image();
  + 
  +     /*fprintf(stderr,"%d check %d 
%d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/
  +     if(scoreboard_image->global.exit_generation >= generation)
  +         exit(0);
        
        if ((count_idle_servers() >= daemons_max_free)
            || (max_requests_per_child > 0
  ***************
  *** 1261,1266 ****
  --- 1315,1325 ----
    #endif
                if (csd == -1 && errno != EINTR)
                    log_unixerr("select",NULL,"select error", server_conf);
  + 
  +             /*fprintf(stderr,"%d check(2a) %d 
%d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/
  +             if(scoreboard_image->global.exit_generation >= generation)
  +                 exit(0);
  + 
                if (csd <= 0) continue;
                for (sd=listenmaxfd; sd >= 0; sd--)
                    if (FD_ISSET(sd, &fds)) break;
  ***************
  *** 1273,1281 ****
  --- 1332,1360 ----
                log_unixerr("accept", "(client socket)", NULL, server_conf);
            }
        } else
  +         {
  +         fd_set fds;
  + 
  +         memset(&fds,0,sizeof fds);
  +         FD_SET(sd,&fds);
  +         
  +         do
  +             csd = select(sd+1, &fds, NULL, NULL, NULL);
  +         while(csd < 0 && errno == EINTR);
  + 
  +         if(csd < 0)
  +             {
  +             log_unixerr("select","(listen)",NULL,server_conf);
  +             exit(0);
  +             }
  +         /*fprintf(stderr,"%d check(2a) %d 
%d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/
  +         if(scoreboard_image->global.exit_generation >= generation)
  +             exit(0);
  + 
            while ((csd=accept(sd, &sa_client, &clen)) == -1) 
                if (errno != EINTR) 
                    log_unixerr("accept",NULL,"socket error: accept failed", 
server_conf);
  +         }
    
        accept_mutex_off(); /* unlock after "accept" */
    
  ***************
  *** 1318,1323 ****
  --- 1397,1407 ----
    #if defined(STATUS)
            if (r) increment_counts(child_num,r,0);
    #endif
  +       sync_scoreboard_image();
  +       if(scoreboard_image->global.exit_generation >= generation)
  +           exit(0);
  +       /*fprintf(stderr,"%d check(3) %d 
%d\n",getpid(),scoreboard_image->global.exit_generation,generation);*/
  + 
        }
    #if 0       
        if (bytes_in_pool (ptrans) > 80000)
  ***************
  *** 1373,1379 ****
            exit(1);
        }
    
  !     note_cleanups_for_fd (pconf, s); /* arrange to close on exec or restart 
*/
        
        if((setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)))
           == -1) {
  --- 1457,1463 ----
            exit(1);
        }
    
  !     /*    note_cleanups_for_fd (pconf, s); /* arrange to close on exec or 
restart */
        
        if((setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)))
           == -1) {
  ***************
  *** 1423,1428 ****
  --- 1507,1555 ----
        return s;
    }
    
  + static listen_rec *old_listeners;
  + 
  + static void copy_listeners()
  +     {
  +     listen_rec *lr;
  + 
  +     assert(old_listeners == NULL);
  +     for(lr=listeners ; lr ; lr=lr->next)
  +     {
  +     listen_rec *nr=malloc(sizeof *nr);
  +     *nr=*lr;
  +     nr->next=old_listeners;
  +     assert(!nr->used);
  +     old_listeners=nr;
  +     }
  +     }
  + 
  + static int find_listener(listen_rec *lr)
  +     {
  +     listen_rec *or;
  + 
  +     for(or=old_listeners ; or ; or=or->next)
  +     if(!memcmp(&or->local_addr,&lr->local_addr,sizeof or->local_addr))
  +         {
  +         or->used=1;
  +         return or->fd;
  +         }
  +     return -1;
  +     }
  + 
  + static void close_unused_listeners()
  +     {
  +     listen_rec *or,*next;
  + 
  +     for(or=old_listeners ; or ; or=next)
  +     {
  +     next=or->next;
  +     if(!or->used)
  +         close(or->fd);
  +     free(or);
  +     }
  +     old_listeners=NULL;
  +     }
    
    /*****************************************************************
     * Executive routines.
  ***************
  *** 1433,1438 ****
  --- 1560,1566 ----
    void standalone_main(int argc, char **argv)
    {
        struct sockaddr_in sa_server;
  +     int saved_sd;
    
        standalone = 1;
        sd = listenmaxfd = -1;
  ***************
  *** 1445,1453 ****
        sigsetjmp(restart_buffer,1);
    #endif
    
        signal (SIGHUP, SIG_IGN);       /* Until we're done (re)reading config 
*/
        
  !     if(!one_process)
        {
    #ifndef NO_KILLPG
          if (killpg(pgrp,SIGHUP) < 0)    /* Kill 'em off */
  --- 1573,1583 ----
        sigsetjmp(restart_buffer,1);
    #endif
    
  +     ++generation;
  + 
        signal (SIGHUP, SIG_IGN);       /* Until we're done (re)reading config 
*/
        
  !     if(!one_process && !is_graceful)
        {
    #ifndef NO_KILLPG
          if (killpg(pgrp,SIGHUP) < 0)    /* Kill 'em off */
  ***************
  *** 1457,1467 ****
            log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf);
        }
        
  !     if (sd != -1 || listenmaxfd != -1) {
        reclaim_child_processes(); /* Not when just starting up */
        log_error ("SIGHUP received.  Attempting to restart", server_conf);
        }
        
        restart_time = time(NULL);
        clear_pool (pconf);
        ptrans = make_sub_pool (pconf);
  --- 1587,1601 ----
            log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf);
        }
        
  !     if(is_graceful)
  !     log_error("SIGINT received.  Doing graceful restart",server_conf);
  !     else if (sd != -1 || listenmaxfd != -1) {
        reclaim_child_processes(); /* Not when just starting up */
        log_error ("SIGHUP received.  Attempting to restart", server_conf);
        }
        
  +     copy_listeners();
  +     saved_sd=sd;
        restart_time = time(NULL);
        clear_pool (pconf);
        ptrans = make_sub_pool (pconf);
  ***************
  *** 1476,1487 ****
    
        if (listeners == NULL)
        {
  !     memset((char *) &sa_server, 0, sizeof(sa_server));
  !     sa_server.sin_family=AF_INET;
  !     sa_server.sin_addr=bind_address;
  !     sa_server.sin_port=htons(server_conf->port);
    
  !     sd = make_sock(pconf, &sa_server);
        } else
        {
        listen_rec *lr;
  --- 1610,1626 ----
    
        if (listeners == NULL)
        {
  !         if(!is_graceful)
  !         {
  !         memset((char *) &sa_server, 0, sizeof(sa_server));
  !         sa_server.sin_family=AF_INET;
  !         sa_server.sin_addr=bind_address;
  !         sa_server.sin_port=htons(server_conf->port);
    
  !         sd = make_sock(pconf, &sa_server);
  !         }
  !     else
  !         sd=saved_sd;
        } else
        {
        listen_rec *lr;
  ***************
  *** 1491,1500 ****
        FD_ZERO(&listenfds);
        for (lr=listeners; lr != NULL; lr=lr->next)
        {
  !         fd = make_sock(pconf, &lr->local_addr);
            FD_SET(fd, &listenfds);
            if (fd > listenmaxfd) listenmaxfd = fd;
        }
        sd = -1;
        }
    
  --- 1630,1643 ----
        FD_ZERO(&listenfds);
        for (lr=listeners; lr != NULL; lr=lr->next)
        {
  !         fd=find_listener(lr);
  !         if(fd < 0)
  !             fd = make_sock(pconf, &lr->local_addr);
            FD_SET(fd, &listenfds);
            if (fd > listenmaxfd) listenmaxfd = fd;
  +         lr->fd=fd;
        }
  +     close_unused_listeners();
        sd = -1;
        }
    
  ***************
  *** 1532,1538 ****
  --- 1675,1691 ----
            (void)update_child_status(child_slot,SERVER_STARTING,
             (request_rec*)NULL);
            make_child(server_conf, child_slot);
  + 
        }
  + 
  +     /*
  +     if(scoreboard_image->global.please_exit && !count_live_servers())
  + #ifdef NEXT
  +         longjmp(restart_buffer,1);
  + #else
  +         siglongjmp(restart_buffer,1);
  + #endif
  +     */
        }
    
    } /* standalone_main */
  
  
  
  1.38      +2 -0      apache/src/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/httpd.h,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -C3 -r1.37 -r1.38
  *** httpd.h   1996/07/03 22:58:45     1.37
  --- httpd.h   1996/07/16 19:39:14     1.38
  ***************
  *** 498,503 ****
  --- 498,505 ----
    struct listen_rec {
        listen_rec *next;
        struct sockaddr_in local_addr; /* local IP address and port */
  +     int fd;
  +     int used;       /* Only used during restart */
    /* more stuff here, like which protocol is bound to the port */
    };
    
  
  
  
  1.14      +15 -0     apache/src/scoreboard.h
  
  Index: scoreboard.h
  ===================================================================
  RCS file: /export/home/cvs/apache/src/scoreboard.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -C3 -r1.13 -r1.14
  *** scoreboard.h      1996/07/13 01:47:38     1.13
  --- scoreboard.h      1996/07/16 19:39:14     1.14
  ***************
  *** 91,95 ****
  --- 91,110 ----
    #endif
    } short_score;
    
  + typedef struct
  +     {
  +     int exit_generation;    /* Set by the main process if a graceful
  +                                restart is required */
  +     } global_score;
  + 
  + typedef struct
  +     {
  +     short_score servers[HARD_SERVER_LIMIT];
  +     global_score global;
  +     } scoreboard;
  + 
  + #define SCOREBOARD_SIZE             sizeof(scoreboard)
  + 
    extern void sync_scoreboard_image(void);
    short_score get_scoreboard_info(int x);
  + 
  
  
  

Reply via email to