You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Joe Orton <jo...@redhat.com> on 2003/05/22 22:26:03 UTC

[PATCH] better failure mode for >2gb logfiles

The failure mode when write()ing past the 2gb file size limit on 
systems which have such a limit is that a SIGXFSZ is delivered; 
SIGXFSZ has an equivalent disposition to SIGSEGV on POSIX systems,
by default.

This patch changes the failure mode so that the SIGXFSZ is ignored;  
the LFS standard requires that the write() then fails with EFBIG, so
this becomes equivalent to an out-of-disk-space condition: the log
messages are then silently dropped on the floor, and you don't know
about it, but the server keeps functioning normally otherwise.

(On restart, the open() still fails on a file which is >2gb, this
doesn't change that)

improves-but-doesn't-really-fix PR: 13511

Index: server/mpm/prefork/prefork.c
===================================================================
RCS file: /store/cvs/root/httpd-2.0/server/mpm/prefork/prefork.c,v
retrieving revision 1.277
diff -u -r1.277 prefork.c
--- server/mpm/prefork/prefork.c	24 Apr 2003 13:45:00 -0000	1.277
+++ server/mpm/prefork/prefork.c	22 May 2003 20:10:55 -0000
@@ -422,7 +422,7 @@
 	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
 #endif
 #ifdef SIGXFSZ
-    sa.sa_handler = SIG_DFL;
+    sa.sa_handler = SIG_IGN;
     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
 	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
 #endif
@@ -447,7 +447,7 @@
 	apr_signal(SIGXCPU, SIG_DFL);
 #endif /* SIGXCPU */
 #ifdef SIGXFSZ
-	apr_signal(SIGXFSZ, SIG_DFL);
+	apr_signal(SIGXFSZ, SIG_IGN);
 #endif /* SIGXFSZ */
     }
 
Index: server/mpm/worker/worker.c
===================================================================
RCS file: /store/cvs/root/httpd-2.0/server/mpm/worker/worker.c,v
retrieving revision 1.135
diff -u -r1.135 worker.c
--- server/mpm/worker/worker.c	9 Apr 2003 16:58:30 -0000	1.135
+++ server/mpm/worker/worker.c	22 May 2003 20:10:55 -0000
@@ -473,7 +473,7 @@
                      "sigaction(SIGXCPU)");
 #endif
 #ifdef SIGXFSZ
-    sa.sa_handler = SIG_DFL;
+    sa.sa_handler = SIG_IGN;
     if (sigaction(SIGXFSZ, &sa, NULL) < 0)
         ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
                      "sigaction(SIGXFSZ)");
@@ -502,7 +502,7 @@
         apr_signal(SIGXCPU, SIG_DFL);
 #endif /* SIGXCPU */
 #ifdef SIGXFSZ
-        apr_signal(SIGXFSZ, SIG_DFL);
+        apr_signal(SIGXFSZ, SIG_IGN);
 #endif /* SIGXFSZ */
     }
 

RE: [PATCH] better failure mode for >2gb logfiles

Posted by Sander Striker <st...@apache.org>.
> From: Joe Orton [mailto:jorton@redhat.com]
> Sent: Friday, May 23, 2003 11:00 AM

> Log writes already fail silently with ENOSPC, for instance - this isn't
> a particularly fundamental change I'm proposing, just making the 2gb
> limit equivalent to ENOSPC.

+1 on the patch (in concept).

Sander

Re: [PATCH] better failure mode for >2gb logfiles

Posted by Joe Orton <jo...@redhat.com>.
On Thu, May 22, 2003 at 09:38:36PM -0400, Glenn wrote:
> On Thu, May 22, 2003 at 11:18:53PM +0100, Joe Orton wrote:
> > On Thu, May 22, 2003 at 01:46:26PM -0700, Ian Holsman wrote:
> > > Joe Orton wrote:
> > > >The failure mode when write()ing past the 2gb file size limit on 
> > > >systems which have such a limit is that a SIGXFSZ is delivered; 
> > > >SIGXFSZ has an equivalent disposition to SIGSEGV on POSIX systems,
> > > >by default.
> > > >
> > > >This patch changes the failure mode so that the SIGXFSZ is ignored;  
> > > >the LFS standard requires that the write() then fails with EFBIG, so
> > > >this becomes equivalent to an out-of-disk-space condition: the log
> > > >messages are then silently dropped on the floor, and you don't know
> > > >about it, but the server keeps functioning normally otherwise.
> > > 
> > > -1 as default behavior
> > > I'd rather have a machine go down then for it to stop logging.
> > 
> > The current behaviour with prefork if the access_log passes 2gb is that
> > the server continues handling requests, but in "MaxRequestsPerChild 1"
> > mode, i.e. slowly and with very high load.  So I think this change is
> > an improvement.
> > 
> > > Silent failure is never a good thing.
> > 
> > It does appear that mod_log_config ignores write() failures, but I'd
> > say that issue is orthogonal to this change.
> 
> Joe, how about modifying your approach a bit:
> Create a handler for SIGXFSZ that sends the _parent_ httpd a USR1 signal.

If you want that behaviour, I think the appropriate place to put it is
in mod_log_config, by handling the write() failure - that way all the
different errors can be handled consistently.

Log writes already fail silently with ENOSPC, for instance - this isn't
a particularly fundamental change I'm proposing, just making the 2gb
limit equivalent to ENOSPC.

Regards,

joe

Re: [PATCH] better failure mode for >2gb logfiles

Posted by Glenn <gs...@gluelogic.com>.
On Thu, May 22, 2003 at 11:18:53PM +0100, Joe Orton wrote:
> On Thu, May 22, 2003 at 01:46:26PM -0700, Ian Holsman wrote:
> > Joe Orton wrote:
> > >The failure mode when write()ing past the 2gb file size limit on 
> > >systems which have such a limit is that a SIGXFSZ is delivered; 
> > >SIGXFSZ has an equivalent disposition to SIGSEGV on POSIX systems,
> > >by default.
> > >
> > >This patch changes the failure mode so that the SIGXFSZ is ignored;  
> > >the LFS standard requires that the write() then fails with EFBIG, so
> > >this becomes equivalent to an out-of-disk-space condition: the log
> > >messages are then silently dropped on the floor, and you don't know
> > >about it, but the server keeps functioning normally otherwise.
> > 
> > -1 as default behavior
> > I'd rather have a machine go down then for it to stop logging.
> 
> The current behaviour with prefork if the access_log passes 2gb is that
> the server continues handling requests, but in "MaxRequestsPerChild 1"
> mode, i.e. slowly and with very high load.  So I think this change is
> an improvement.
> 
> > Silent failure is never a good thing.
> 
> It does appear that mod_log_config ignores write() failures, but I'd
> say that issue is orthogonal to this change.

Joe, how about modifying your approach a bit:
Create a handler for SIGXFSZ that sends the _parent_ httpd a USR1 signal.
Upon startup or reconfiguration after a USR1/HUP, the master httpd could
check log file sizes (fstat() after opening the log) and could artificially
rotate a log file if was too large, and then could log a message to the
error log indicating that such was done (and the unique name to which the
oversized log was rotated).  If people like the concept, I'll put together
a patch.

IMHO, an even better approach would be to use piped logs and to have
the piped log program handle log rotation and other logging policy.
That's the unix way; a small program does one small job and does it
really well.

(The LAST thing I want done is to set such an uncommon signal to SIG_IGN
 because the ignored disposition is inherited by spawned children (i.e. CGI)
 unless explicitly reset.  Block the signal if you must (also inherited, but
 more efficiently reset with a single system call for lots of signals), but
 please try to avoid ignoring it.)

Cheers,
Glenn

Re: [PATCH] better failure mode for >2gb logfiles

Posted by Joe Orton <jo...@redhat.com>.
On Thu, May 22, 2003 at 01:46:26PM -0700, Ian Holsman wrote:
> Joe Orton wrote:
> >The failure mode when write()ing past the 2gb file size limit on 
> >systems which have such a limit is that a SIGXFSZ is delivered; 
> >SIGXFSZ has an equivalent disposition to SIGSEGV on POSIX systems,
> >by default.
> >
> >This patch changes the failure mode so that the SIGXFSZ is ignored;  
> >the LFS standard requires that the write() then fails with EFBIG, so
> >this becomes equivalent to an out-of-disk-space condition: the log
> >messages are then silently dropped on the floor, and you don't know
> >about it, but the server keeps functioning normally otherwise.
> 
> -1 as default behavior
> I'd rather have a machine go down then for it to stop logging.

The current behaviour with prefork if the access_log passes 2gb is that
the server continues handling requests, but in "MaxRequestsPerChild 1"
mode, i.e. slowly and with very high load.  So I think this change is
an improvement.

> Silent failure is never a good thing.

It does appear that mod_log_config ignores write() failures, but I'd
say that issue is orthogonal to this change.

Regards,

joe

Re: [PATCH] better failure mode for >2gb logfiles

Posted by Ian Holsman <ia...@apache.org>.
Joe Orton wrote:
> The failure mode when write()ing past the 2gb file size limit on 
> systems which have such a limit is that a SIGXFSZ is delivered; 
> SIGXFSZ has an equivalent disposition to SIGSEGV on POSIX systems,
> by default.
> 
> This patch changes the failure mode so that the SIGXFSZ is ignored;  
> the LFS standard requires that the write() then fails with EFBIG, so
> this becomes equivalent to an out-of-disk-space condition: the log
> messages are then silently dropped on the floor, and you don't know
> about it, but the server keeps functioning normally otherwise.

-1 as default behavior
I'd rather have a machine go down then for it to stop logging.

Silent failure is never a good thing.

> 
> (On restart, the open() still fails on a file which is >2gb, this
> doesn't change that)
> 
> improves-but-doesn't-really-fix PR: 13511
> 
> Index: server/mpm/prefork/prefork.c
> ===================================================================
> RCS file: /store/cvs/root/httpd-2.0/server/mpm/prefork/prefork.c,v
> retrieving revision 1.277
> diff -u -r1.277 prefork.c
> --- server/mpm/prefork/prefork.c	24 Apr 2003 13:45:00 -0000	1.277
> +++ server/mpm/prefork/prefork.c	22 May 2003 20:10:55 -0000
> @@ -422,7 +422,7 @@
>  	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)");
>  #endif
>  #ifdef SIGXFSZ
> -    sa.sa_handler = SIG_DFL;
> +    sa.sa_handler = SIG_IGN;
>      if (sigaction(SIGXFSZ, &sa, NULL) < 0)
>  	ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)");
>  #endif
> @@ -447,7 +447,7 @@
>  	apr_signal(SIGXCPU, SIG_DFL);
>  #endif /* SIGXCPU */
>  #ifdef SIGXFSZ
> -	apr_signal(SIGXFSZ, SIG_DFL);
> +	apr_signal(SIGXFSZ, SIG_IGN);
>  #endif /* SIGXFSZ */
>      }
>  
> Index: server/mpm/worker/worker.c
> ===================================================================
> RCS file: /store/cvs/root/httpd-2.0/server/mpm/worker/worker.c,v
> retrieving revision 1.135
> diff -u -r1.135 worker.c
> --- server/mpm/worker/worker.c	9 Apr 2003 16:58:30 -0000	1.135
> +++ server/mpm/worker/worker.c	22 May 2003 20:10:55 -0000
> @@ -473,7 +473,7 @@
>                       "sigaction(SIGXCPU)");
>  #endif
>  #ifdef SIGXFSZ
> -    sa.sa_handler = SIG_DFL;
> +    sa.sa_handler = SIG_IGN;
>      if (sigaction(SIGXFSZ, &sa, NULL) < 0)
>          ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, 
>                       "sigaction(SIGXFSZ)");
> @@ -502,7 +502,7 @@
>          apr_signal(SIGXCPU, SIG_DFL);
>  #endif /* SIGXCPU */
>  #ifdef SIGXFSZ
> -        apr_signal(SIGXFSZ, SIG_DFL);
> +        apr_signal(SIGXFSZ, SIG_IGN);
>  #endif /* SIGXFSZ */
>      }
>  
>