You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by David Robinson <dr...@ast.cam.ac.uk> on 1995/08/16 17:19:00 UTC

Re: Better Solaris fix...

Rst wrote:
>This can be solved for the moment by locking the scoreboard file
>(which is, for now, guaranteed to be in /tmp); if we move the
>scoreboard file elsewhere, then at that point we could open a file in
>/tmp, and immediately unlink it; this would allow us still lock it,
>with fcntl() at least (though not with flock()), while keeping files
>from piling up in /tmp.

I've already got a patch which does precisely that; it opens a new file
in /tmp and unlinks it. It was quicker to write this patch than to figure
out the scoreboard code, and I felt that the two features should be
separate. I'm currently awaiting a reply from someone who suffers from
the bug.

The effects of the bug that I see are that it takes a significant
amount of time (several seconds) for a HUP or TERM signal to affect httpd.
If I HUP httpd, the old daemons stay as defunct processes for a while,
and the server does not respond immediately. Similarly, if I TERM httpd,
it is a little while before the system unbinds the http port and allows
a new daemon to be run.

So I do not see a permanent hang of httpd, but scripts that do
kill -TERM `cat httpd.pid`
./httpd
will fail.

>Well, it turns out that locking the scoreboard file (as per previous
>patch) doesn't work directly, because tmpfs doesn't support locking of
>*any* sort.  It does appear to work (I'm running with it on port 80)
>with the scoreboard file in /usr/tmp, which is generally not a tmpfs;
>revised patch below.
>
>Sun Quality Software... gotta love it.  Waaaaaahhh....

Hmm, this works under Solaris 2.4, but I'll fix my patch.

 David.

-------------------- begin file lock.patch -----------------------------
*** http_main.c~	Fri Aug  4 01:00:05 1995
--- http_main.c	Wed Aug 16 13:24:31 1995
***************
*** 138,152 ****
  int one_process = 0;
  
  #ifdef FCNTL_SERIALIZED_ACCEPT
! struct flock lock_it = { F_WRLCK, 0, 0, 0 };
! struct flock unlock_it = { F_UNLCK, 0, 0, 0 };
  
  void accept_mutex_on()
  {
      int ret;
      
!     while ((ret = fcntl(fileno(server_conf->error_log),F_SETLKW, &lock_it)) < 0
! 	   && errno == EINTR)
  	continue;
  
      if (ret < 0) {
--- 138,182 ----
  int one_process = 0;
  
  #ifdef FCNTL_SERIALIZED_ACCEPT
! static struct flock lock_it = { F_WRLCK, 0, 0, 0 };
! static struct flock unlock_it = { F_UNLCK, 0, 0, 0 };
! 
! static int lock_fd=-1;
! 
! /*
!  * Initialise mutex lock.
!  * Must be safe to call this on a restart.
!  */
! void
! accept_mutex_init(pool *p)
! {
!     char lock_fname[19];
! 
!     if (lock_fd >= 0) return;  /* Already initialised */
! 
!     strcpy(lock_fname, "/usr/tmp/htlock.XXXXXX");
!     
!     if (mktemp(lock_fname) == NULL || lock_fname[0] == '\0')
!     {
! 	fprintf (stderr, "Cannot assign name to lock file!\n");
! 	exit (1);
!     }
! 
!     lock_fd = popenf(p, lock_fname, O_CREAT | O_WRONLY, 0644);
!     if (lock_fd == -1)
!     {
! 	perror ("open");
! 	fprintf (stderr, "Cannot open lcok file\n");
! 	exit (1);
!     }
!     unlink(lock_fname);
! }
  
  void accept_mutex_on()
  {
      int ret;
      
!     while ((ret = fcntl(lock_fd, F_SETLKW, &lock_it)) < 0 && errno == EINTR)
  	continue;
  
      if (ret < 0) {
***************
*** 158,169 ****
  
  void accept_mutex_off()
  {
!     fcntl (fileno(server_conf->error_log), F_SETLKW, &unlock_it);
  }
  #else
  /* Default --- no serialization.  Other methods *could* go here,
   * as #elifs...
   */
  #define accept_mutex_on()
  #define accept_mutex_off()
  #endif
--- 188,204 ----
  
  void accept_mutex_off()
  {
!     if (fcntl (lock_fd, F_SETLKW, &unlock_it) < 0)
!     {
! 	log_error("Error freeing accept lock.  Exiting!", server_conf);
! 	exit(1);
!     }
  }
  #else
  /* Default --- no serialization.  Other methods *could* go here,
   * as #elifs...
   */
+ #define accept_mutex_init()
  #define accept_mutex_on()
  #define accept_mutex_off()
  #endif
***************
*** 817,822 ****
--- 852,858 ----
      server_conf = read_config(pconf, ptrans, server_confname); 
      set_group_privs();
      open_logs(server_conf, pconf);
+     accept_mutex_init(pconf);
      reinit_scoreboard(pconf);
      
      if (!server_conf->server_hostname)
-------------------- end file lock.patch -----------------------------