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