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;
 }

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to