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

