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);
+