On Thu, 2006-02-16 at 12:24 +0100, Javier Fernández-Sanguino Peña wrote: > - run 'portreserve start' twice, check # of portreserve instances. Stop > port reserve. > - run 'portreserve start' once, run 'portreserve', check # of instances and > pidfile contents. Stop port reserve.
Handles both these tests with no problems. > There are other situations which could be tested out and which, I believe, > the init.d script does not cover (like creating a stale pidfile when > portreserve is not running, stopping portreseve and trying to start it > again). It also handles this situation cleanly. I did however discover one minor bug that occurred when the stop target of the init script was run twice in a row and resulted in some ugly error output from trying to read the non-existant pidfile. The functionality was still correct, but it didn't look nice. Yet another version attached which fixes this minor annoyance. This is the patch that I will pass on to my AM to NMU as part of my application. > Thanks for working on this, hope you don't mind my nit-picking. The package is much improved as a result. Kind Regards -- Matt Brown [EMAIL PROTECTED] Mob +64 21 611 544 www.mattb.net.nz
diff -ur portreserve-0.0.0/debian/changelog portreserve-0.0.0-matt/debian/changelog --- portreserve-0.0.0/debian/changelog 2006-02-18 14:08:00.000000000 +1300 +++ portreserve-0.0.0-matt/debian/changelog 2006-02-18 14:05:59.000000000 +1300 @@ -1,3 +1,16 @@ +portreserve (0.0.0-2.1) unstable; urgency=low + + * Non-maintainer upload + * Fixed minor init script bugs (Closes: #352103) + - Use -z instead of -n to test list of service files + - Use $NAME instead of the undefined $prog in the pidfile name + * Reworked portreserve pidfile handling + - Check for existance of pidfile on startup, fail if already running + - Create pidfile on startup + - Remove pidfile when program exits cleanly + + -- Matt Brown <[EMAIL PROTECTED]> Thu, 16 Feb 2006 01:02:03 +1300 + portreserve (0.0.0-2) unstable; urgency=low * Added xmlto to Build-Depends (Closes: #337848) diff -ur portreserve-0.0.0/debian/portreserve.init portreserve-0.0.0-matt/debian/portreserve.init --- portreserve-0.0.0/debian/portreserve.init 2006-02-18 14:08:00.000000000 +1300 +++ portreserve-0.0.0-matt/debian/portreserve.init 2006-02-18 14:07:05.000000000 +1300 @@ -11,19 +11,19 @@ test -f $DAEMON || exit 0 NAME=`basename $DAEMON` -PIDFILE=/var/run/$prog.pid +PIDFILE=/var/run/$NAME.pid running() { # No pidfile, probably no daemon present # [ ! -f "$PIDFILE" ] && return 1 - pid=`cat $PIDFILE` + pid=`cat $PIDFILE 2>/dev/null` # No pid, probably no daemon present [ -z "$pid" ] && return 1 [ ! -d /proc/$pid ] && return 1 - cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1` - + cmdline=`cat /proc/$pid/cmdline 2>/dev/null | tr "\000" "\n"|head -n 1 |cut -d : -f 1` + cmd=`basename $cmdline` [ "$cmd" != "$NAME" ] && return 1 return 0 } @@ -36,7 +36,7 @@ if [ ! -d /etc/portreserve ] ; then return 1 fi - if [ -n "`find /etc/portreserve \! -name "*~" -a \! -name "*.*" -type f`" ] ; then + if [ -z "`find /etc/portreserve \! -name "*~" -a \! -name "*.*" -type f`" ] ; then return 1 fi return 0 Only in portreserve-0.0.0: portreserve.spec diff -ur portreserve-0.0.0/src/portreserve.c portreserve-0.0.0-matt/src/portreserve.c --- portreserve-0.0.0/src/portreserve.c 2003-09-04 02:12:52.000000000 +1200 +++ portreserve-0.0.0-matt/src/portreserve.c 2006-02-18 14:05:59.000000000 +1300 @@ -64,7 +64,13 @@ # include <unistd.h> #endif +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + #define UNIX_SOCKET "/var/run/portreserve/socket" +#define PIDFILE "/var/run/portreserve.pid" struct map { struct map *next; @@ -264,9 +270,85 @@ return 0; } +/* daemon_lock_pidfile and fcntl_lock taken from libslack + * Copyright (C) 1999-2004 raf <[EMAIL PROTECTED]> + * Licensed under the GPL + */ +int +fcntl_lock(int fd, int cmd, int type, int whence, int start, int len) +{ + struct flock lock[1]; + + lock->l_type = type; + lock->l_whence = whence; + lock->l_start = start; + lock->l_len = len; + + return fcntl(fd, cmd, lock); +} + +static int +daemon_lock_pidfile(char *pidfile) +{ + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + int pid_fd; + + /* This is broken over NFS (Linux). So pidfiles must reside locally. */ + + if ((pid_fd = open(pidfile, O_RDWR | O_CREAT | O_EXCL, mode)) == -1) + { + if (errno != EEXIST) + return -1; + + /* + ** The pidfile already exists. Is it locked? + ** If so, another invocation is still alive. + ** If not, the invocation that created it has died. + ** Open the pidfile to attempt a lock. + */ + + if ((pid_fd = open(pidfile, O_RDWR)) == -1) + return -1; + } + + if (fcntl_lock(pid_fd, F_SETLK, F_WRLCK, SEEK_SET, 0, 0) == -1) + return -1; + + return pid_fd; +} + +int +create_pidfile(char *pidfile) +{ + + int fd; + char pid[32]; + + /* Open and lock pidfile */ + if ((fd = daemon_lock_pidfile(pidfile)) == -1) { + return -1; + } + + /* Store our pid */ + snprintf(pid, sizeof(pid), "%d\n", (int)getpid()); + if (write(fd, pid, strlen(pid)) != strlen(pid)) { + return -1; + } + + return 0; +} + +void +handle_sigterm (int sig) +{ + unlink(PIDFILE); + exit(0); +} + int main (int argc, char **argv) { + int rv; const char *p = strrchr (argv[0], '/'); if (!p++) p = argv[0]; @@ -278,7 +360,9 @@ r += portrelease (argv[i]); return r; } - + + signal (SIGTERM, handle_sigterm); + if (argc > 1) { if (!strcmp (argv[1], "-d")) debug = 1; @@ -302,7 +386,12 @@ close (STDOUT_FILENO); close (STDERR_FILENO); setsid (); + if (create_pidfile(PIDFILE)==-1) + error (EXIT_FAILURE, errno, + "Failed to write pidfile!"); } - return portreserve (); + rv = portreserve(); + unlink(PIDFILE); + return rv; }
signature.asc
Description: This is a digitally signed message part