dgaudet     97/04/27 00:45:04

  Modified:    htdocs/manual  stopping.html
               src       CHANGES http_main.c
  Log:
  Deal with EINTR while processing scoreboard file.  Fix graceful restart
  for scoreboard files.
  
  Reviewed by:  Randy, Roy
  
  Revision  Changes    Path
  1.4       +9 -10     apache/htdocs/manual/stopping.html
  
  Index: stopping.html
  ===================================================================
  RCS file: /export/home/cvs/apache/htdocs/manual/stopping.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -C3 -r1.3 -r1.4
  *** stopping.html     1997/04/25 00:06:59     1.3
  --- stopping.html     1997/04/27 07:45:00     1.4
  ***************
  *** 57,67 ****
    <p><b>Note:</b> prior to release 1.2b9 this code is quite unstable and
    shouldn't be used at all.
    
  - <p><b>Note:</b> Architectures that use an on disk <a
  - href="mod/core.html#scoreboardfile">ScoreBoardFile</a> are not supported
  - on graceful restarts.  See the ScoreBoardFile documentation for a method
  - to determine if your architecture uses a file.
  - 
    <p>The <code>USR1</code> signal causes the parent process to <i>advise</i>
    the children to exit after their current request (or to exit immediately
    if they're not serving anything).  The parent re-reads its configuration
  --- 57,62 ----
  ***************
  *** 112,122 ****
    But it should be noted that there still do exist race conditions on
    certain architectures.
    
  ! <p>Architectures that use an on disk <a
  ! href="mod/core.html#scoreboardfile">ScoreBoardFile</a> have the potential
  ! to corrupt their scoreboards whenever a signal is received (by the
  ! parent or children).  It is
  ! possible for the server to forget about some children when this happens.
    See the ScoreBoardFile documentation for a method to determine if your
    architecture uses it.
    
  --- 107,121 ----
    But it should be noted that there still do exist race conditions on
    certain architectures.
    
  ! <p>Architectures that use an on disk
  ! <a href="mod/core.html#scoreboardfile">ScoreBoardFile</a>
  ! have the potential to corrupt their scoreboards.  This can result in
  ! the "bind: Address already in use" (after <code>HUP</code>) or
  ! "long lost child came home!" (after <code>USR1</code>).  The former is
  ! a fatal error, while the latter just causes the server to lose a scoreboard
  ! slot.  So it might be advisable to use graceful restarts, with
  ! an occasional hard restart.  These problems are very difficult to work
  ! around, but fortunately most architectures do not require a scoreboard file.
    See the ScoreBoardFile documentation for a method to determine if your
    architecture uses it.
    
  
  
  
  1.253     +4 -6      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.252
  retrieving revision 1.253
  diff -C3 -r1.252 -r1.253
  *** CHANGES   1997/04/27 07:14:14     1.252
  --- CHANGES   1997/04/27 07:45:02     1.253
  ***************
  *** 9,20 ****
         than mod_alias, and mod_alias has higher priority than mod_proxy.
         [Sameer Parekh]
    
  !   *) Fix graceful restart on architectures not using scoreboard files
  !      (it is still broken on scoreboard-file architectures).
  !      Eliminate many signal-related race conditions in both forms of
  !      restart, and in SIGTERM.  See htdocs/manual/stopping.html for
  !      details on stopping and restarting the parent.
  !      [Dean Gaudet]
    
      *) Fix memory leaks in mod_rewrite, mod_browser, mod_include.  Tune
         memory allocator to avoid a behaviour that required extra blocks to
  --- 9,18 ----
         than mod_alias, and mod_alias has higher priority than mod_proxy.
         [Sameer Parekh]
    
  !   *) Fix graceful restart.  Eliminate many signal-related race
  !      conditions in both forms of restart, and in SIGTERM.  See
  !      htdocs/manual/stopping.html for details on stopping and
  !      restarting the parent.  [Dean Gaudet]
    
      *) Fix memory leaks in mod_rewrite, mod_browser, mod_include.  Tune
         memory allocator to avoid a behaviour that required extra blocks to
  
  
  
  1.140     +28 -23    apache/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.c,v
  retrieving revision 1.139
  retrieving revision 1.140
  diff -C3 -r1.139 -r1.140
  *** http_main.c       1997/04/24 23:35:20     1.139
  --- http_main.c       1997/04/27 07:45:03     1.140
  ***************
  *** 73,83 ****
     *      Extensive rework for Apache.
     */
    
  - /* XXX: systems without HAVE_SHMGET or HAVE_MMAP do not reliably update
  -  * the scoreboard because a received signal might interrupt the scoreboard
  -  * calls.
  -  */
  - 
    #define CORE_PRIVATE
    
    #include "httpd.h"
  --- 73,78 ----
  ***************
  *** 804,814 ****
    }
    
    #else
    static scoreboard _scoreboard_image;
    static scoreboard *scoreboard_image=&_scoreboard_image;
  - static int have_scoreboard_fname = 0;
    static int scoreboard_fd;
    
    static int force_write (int fd, char *buffer, int bufsz)
    {
        int rv, orig_sz = bufsz;
  --- 799,812 ----
    }
    
    #else
  + #define SCOREBOARD_FILE
    static scoreboard _scoreboard_image;
    static scoreboard *scoreboard_image=&_scoreboard_image;
    static int scoreboard_fd;
    
  + /* XXX: things are seriously screwed if we ever have to do a partial
  +  * read or write ... we could get a corrupted scoreboard
  +  */
    static int force_write (int fd, char *buffer, int bufsz)
    {
        int rv, orig_sz = bufsz;
  ***************
  *** 819,825 ****
            buffer += rv;
            bufsz -= rv;
        }
  !     } while (rv > 0 && bufsz > 0);
    
        return rv < 0? rv : orig_sz - bufsz;
    }
  --- 817,823 ----
            buffer += rv;
            bufsz -= rv;
        }
  !     } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
    
        return rv < 0? rv : orig_sz - bufsz;
    }
  ***************
  *** 834,840 ****
            buffer += rv;
            bufsz -= rv;
        }
  !     } while (rv > 0 && bufsz > 0);
        
        return rv < 0? rv : orig_sz - bufsz;
    }
  --- 832,838 ----
            buffer += rv;
            bufsz -= rv;
        }
  !     } while ((rv > 0 && bufsz > 0) || (rv == -1 && errno == EINTR));
        
        return rv < 0? rv : orig_sz - bufsz;
    }
  ***************
  *** 847,853 ****
        if(scoreboard_image)
        exit_gen=scoreboard_image->global.exit_generation;
        
  ! #if defined(HAVE_SHMGET) || defined(HAVE_MMAP)
        if (scoreboard_image == NULL)
        {
        setup_shared_mem();
  --- 845,851 ----
        if(scoreboard_image)
        exit_gen=scoreboard_image->global.exit_generation;
        
  ! #ifndef SCOREBOARD_FILE
        if (scoreboard_image == NULL)
        {
        setup_shared_mem();
  ***************
  *** 857,864 ****
    #else
        scoreboard_fname = server_root_relative (p, scoreboard_fname);
    
  -     have_scoreboard_fname = 1;
  -     
    #ifdef __EMX__
        /* OS/2 needs binary mode set. */
        scoreboard_fd = popenf(p, scoreboard_fname, O_CREAT|O_BINARY|O_RDWR, 
0644);
  --- 855,860 ----
  ***************
  *** 882,888 ****
    /* called by child */
    void reopen_scoreboard (pool *p)
    {
  ! #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
        if (scoreboard_fd != -1) pclosef (p, scoreboard_fd);
        
    #ifdef __EMX__    
  --- 878,884 ----
    /* called by child */
    void reopen_scoreboard (pool *p)
    {
  ! #ifdef SCOREBOARD_FILE
        if (scoreboard_fd != -1) pclosef (p, scoreboard_fd);
        
    #ifdef __EMX__    
  ***************
  *** 918,924 ****
    
    void cleanup_scoreboard ()
    {
  ! #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
        unlink (scoreboard_fname);
    #endif
    }
  --- 914,920 ----
    
    void cleanup_scoreboard ()
    {
  ! #ifdef SCOREBOARD_FILE
        unlink (scoreboard_fname);
    #endif
    }
  ***************
  *** 936,942 ****
    
    void sync_scoreboard_image ()
    {
  ! #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
        lseek (scoreboard_fd, 0L, 0);
        force_read (scoreboard_fd, (char*)scoreboard_image,
                sizeof(*scoreboard_image));
  --- 932,938 ----
    
    void sync_scoreboard_image ()
    {
  ! #ifdef SCOREBOARD_FILE
        lseek (scoreboard_fd, 0L, 0);
        force_read (scoreboard_fd, (char*)scoreboard_image,
                sizeof(*scoreboard_image));
  ***************
  *** 987,993 ****
        }
    #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);
  --- 983,989 ----
        }
    #endif
    
  ! #ifndef SCOREBOARD_FILE
        memcpy(&scoreboard_image->servers[child_num], &new_score_rec, sizeof 
new_score_rec);
    #else
        lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
  ***************
  *** 999,1005 ****
    
    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,
  --- 995,1001 ----
    
    void update_scoreboard_global()
        {
  ! #ifdef SCOREBOARD_FILE
        lseek(scoreboard_fd,
          (char *)&scoreboard_image->global-(char *)scoreboard_image,0);
        force_write(scoreboard_fd,(char *)&scoreboard_image->global,
  ***************
  *** 1067,1073 ****
        times(&new_score_rec.times);
    
    
  ! #if defined(HAVE_MMAP) || defined(HAVE_SHMGET)
        memcpy(&scoreboard_image->servers[child_num], &new_score_rec, 
sizeof(short_score));
    #else
        lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
  --- 1063,1069 ----
        times(&new_score_rec.times);
    
    
  ! #ifndef SCOREBOARD_FILE
        memcpy(&scoreboard_image->servers[child_num], &new_score_rec, 
sizeof(short_score));
    #else
        lseek (scoreboard_fd, (long)child_num * sizeof(short_score), 0);
  ***************
  *** 2128,2133 ****
  --- 2124,2134 ----
        if (!is_graceful) {
            restart_time = time(NULL);
        }
  + #ifdef SCOREBOARD_FILE
  +     else {
  +         kill_cleanups_for_fd (pconf, scoreboard_fd);
  +     }
  + #endif
        clear_pool (pconf);
        ptrans = make_sub_pool (pconf);
    
  ***************
  *** 2138,2143 ****
  --- 2139,2150 ----
        if (!is_graceful) {
            reinit_scoreboard(pconf);
        }
  + #ifdef SCOREBOARD_FILE
  +     else {
  +         scoreboard_fname = server_root_relative (pconf, scoreboard_fname);
  +         note_cleanups_for_fd (pconf, scoreboard_fd);
  +     }
  + #endif
    
        default_server_hostnames (server_conf);
    
  ***************
  *** 2284,2292 ****
            if (ap_killpg(pgrp, SIGUSR1) < 0) {
                log_unixerr ("killpg SIGUSR1", NULL, NULL, server_conf);
            }
            /* This is mostly for debugging... so that we know what is still
  !          * gracefully dealing with existing request.
  !          * XXX: clean this up a bit?
             */
            sync_scoreboard_image();
            for (i = 0; i < daemons_limit; ++i ) {
  --- 2291,2301 ----
            if (ap_killpg(pgrp, SIGUSR1) < 0) {
                log_unixerr ("killpg SIGUSR1", NULL, NULL, server_conf);
            }
  + #ifndef SCOREBOARD_FILE
            /* This is mostly for debugging... so that we know what is still
  !          * gracefully dealing with existing request.  But we can't really
  !          * do it if we're in a SCOREBOARD_FILE because it'll cause
  !          * corruption too easily.
             */
            sync_scoreboard_image();
            for (i = 0; i < daemons_limit; ++i ) {
  ***************
  *** 2294,2303 ****
                    scoreboard_image->servers[i].status = SERVER_GRACEFUL;
                }
            }
  - #if !defined(HAVE_MMAP) && !defined(HAVE_SHMGET)
  -         lseek (scoreboard_fd, 0L, 0);
  -         force_write (scoreboard_fd, (char*)scoreboard_image,
  -                     sizeof(*scoreboard_image));
    #endif
        }
        else {
  --- 2303,2308 ----
  
  
  

Reply via email to