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>