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>
