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 ----