Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 22 Jun 2002 20:17:54 -0400 (EDT)
From:      "Geoffrey C. Speicher" <geoff@sea-incorporated.com>
To:        "Matthew D. Fuller" <fullermd@over-yonder.net>
Cc:        freebsd-stable@freebsd.org, Matt Simerson <freebsd@blockads.com>, Paul Herman <pherman@frenchfries.net>
Subject:   Re: bug in pw, -STABLE [patch]
Message-ID:  <20020622180011.V80651-100000@sea-incorporated.com>
In-Reply-To: <20020622071722.GA57065@over-yonder.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 22 Jun 2002, Matthew D. Fuller wrote:

> You, sir, are an evil, evil, evil man.

You've got me pegged.  :)

> pidmond(8); reads /etc/pidmond.conf, which contains a list of PID files
> and actions.  Every N-interval (in config file), scan the PID file and
> check if PID specified is still alive.  If not, take given action (could
> range from 'restart' to 'remove PID file').

Hmm.  This takes care of our problem, which was that pw(8) might
die and leave a stale pid file behind.  It also takes care of the
problem of automatically restarting dead daemons, though as you
pointed out, init(8) could be used for this too, so I'm not sure
what pidmond(8) gives you for daemons.

Drat.  Let's back up for a second.  There are (at least) two different
kinds of programs that need to keep track of pid files:

 (A) transient processes, which basically use a pid file as a mutex

 (B) daemon processes, which we always want running, and whose pid
     we might want later so that we can send the process a signal
     or something

Things that are nice to have for transient processes are:

 A1. a way for a newly-created process to make sure another competitor
     for the same resource is not already running, and inform
     everybody that it is now running
 A2. a way to inform everybody that it is no longer running

Things that are nice to have for daemon processes are:

 B1. a monitor to ensure that the daemon is always running
 B2. A1 and A2 from above

I think that B1 is already taken care of by init(8) and other
solutions.  That leaves A1 and A2 (or B2 if you prefer), and what
I'm thinking is that it should probably just be implemented as a
library whose API consists of two functions that look something
like this:

SYNOPSIS
    int
    pid_begin(const char* path, int flags=0);

    int
    pid_end(const char* path);

DESCRIPTION
    pid_begin() will check for existence of the pid file named
    _path_, and if it exists, determine whether the process whose
    pid is contained therein is still running.

    If the file does not exist, or the contained pid is no
    longer valid, then pid_begin() will create the file, write
    the current pid, and return 0 (success).

    If the file exists and the pid is valid, pid_begin() will
    check the _flags_ argument.  If the flag PID_NOBLOCK is
    specified, pid_begin() will return -1 and global variable
    _errno_ is set to indicate EWOULDBLOCK.  Otherwise, pid_begin()
    will sleep until the file is removed or the pid becomes
    invalid, create the file, write the current pid, and return
    0 (success).

    pid_end() simply removes the pid file _path_ so that other
    processes may continue with their business.

Of course, I'm not attached to the symbols, and in addition to
EWOULDBLOCK, the functions could return other errno values based
on the result of open() and unlink(), but you get the idea.

Then pw(8) and friends would just have to:

#define LOCKFILE "/var/run/passwd.pid"
if (!pid_begin(LOCKFILE))
    err(1, "%s", LOCKFILE);
/* run pwd_mkdb */
if (!pid_end(LOCKFILE))
    err(1, "%s", LOCKFILE);

And daemons would just have to:

#define PIDFILE "/var/run/named.pid"
if (!pid_begin(PIDFILE, PID_NOBLOCK)) {
    if (errno == EWOULDBLOCK)
        errx(1, "named is already running");
    else
        err(1, "%s", PIDFILE);
}
/* ... */

What do you think about that?

Geoff


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020622180011.V80651-100000>