Bill Jonas on Wed, 10 Apr 2002 00:00:18 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] logrotate question


On Tue, Apr 09, 2002 at 10:21:17AM -0400, Michael Whitman wrote:
> My question is why the killall is necessary?

Applications write to file handles, not file names.  Once you get a
filehandle, you can write to it for as long as you have it open and can
continue writing to it for as long as you like, even if the underlying
file gets deleted or renamed.  (Files don't really get deleted (in the
sense that the space is freed) until all processes which have that file
open close it.  You can see this in action by taking a large file
(created from /dev/zero, for example) and opening it with less, then
deleting the file.  df output will remain unchanged until you terminate
less (or open a different file with it).)

So Apache doesn't know or care what the underlying log file's called
after it gets it open (though there are limitations, of course; you
can't move it to a different filesystem, for example).  Let's walk
through the process, doing it by hand.  1.) You delete the oldest
logfile.  2.) You move each access.log.n.gz to access.log.n+1.gz.  3.)
Move access.log.0 to access.log.1, and gzip it.  4.)  Move access.log to
access.log.0 and then touch access.log (to create a new one).  5.)  Come
back some time later to look at access.log and wonder why you've gotten
no hits.

Actually, your hits are recorded, but they were logged in access.log.0;
Apache kept writing to the same *filehandle*, even though the file's
name had changed.  You need some way to tell Apache that you've changed
the files.  You also don't want to shut it down and restart it, because
you might miss a request during the few seconds it takes to restart it.

> Isn't this going to stop my webserver?

No.

> -HUP just means you are specifying a process name rather than a PID right?

No.  Refer to killall(1) and kill(1).  kill requires you to specify a
PID or a job number.  killall lets you give it a name; then it works on
each process that has that name.

Also keep in mind that kill (and its brethren) don't really "kill" a
process; it just sends signals.  (See the output of "kill -l".)  The
default is SIGTERM, which most programs interpret as a sign to exit.  In
this case, the signal being sent is a SIGHUP (specified as "-HUP").
Applications interpret different signals in different ways (the
exception being SIGKILL which can't be caught or ignored by processes
and terminates a process immediately), but many daemons, upon receiving
SIGHUP, will re-read their configuration files.  Apache is one of these
programs; when it receives SIGHUP, it flushes its log output, closes its
log files, re-reads its config file (and applies any changes it finds),
re-opens its log files, and resumes.  This is how you get around the
problem a couple paragraphs back, and that's why the logrotate files
does it like it does.

Incidentally, this is why the log file before the current one is not
gzip'd.  It could be done, in theory, after the necessary stuff has been
done to the daemon, but there are all sorts of subtle problems that
creep in with that, not the least of which is race conditions.  ("How do
we *know* when the daemon has quit writing to that file?")

-- 
Bill Jonas    *    bill@billjonas.com    *    http://www.billjonas.com/

Developer/SysAdmin for hire!   See http://www.billjonas.com/resume.html

Attachment: pgpWBhaZtBlcV.pgp
Description: PGP signature