[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#270136: patch for partman_server



reassign 270136 partman-base
tag 270136 + patch
thanks

Patch attached to make this behaviour a bit more robust (I hope).

Mark

-- 
Mark Hymers <mark.hymers@ncl.ac.uk>

"But Yossarian *still* didn't understand either how Milo could buy eggs
 in Malta for seven cents apiece and sell them at a profit in Pianosa
 for five cents."
     Catch 22, Joseph Heller
Index: debian/changelog
===================================================================
--- debian/changelog	(revision 37382)
+++ debian/changelog	(working copy)
@@ -1,3 +1,9 @@
+partman-base (83) unstable; urgency=low
+
+  * Add more robust pid file and fifo handling.  Closes: #270136.
+
+ -- Mark Hymers <mark.hymers@ncl.ac.uk>  Thu, 18 May 2006 03:37:26 +0100
+
 partman-base (82) unstable; urgency=low
 
   [ Frans Pop ]
Index: definitions.sh
===================================================================
--- definitions.sh	(revision 37382)
+++ definitions.sh	(working copy)
@@ -255,8 +255,6 @@
     open_infifo
     write_line "QUIT"
     close_infifo
-
-    rm /var/run/parted_server.pid
 }
 
 # Must call stop_parted_server before calling this.
Index: init.d/parted
===================================================================
--- init.d/parted	(revision 37382)
+++ init.d/parted	(working copy)
@@ -5,12 +5,13 @@
 . /lib/partman/definitions.sh
 
 if [ ! -f /var/run/parted_server.pid ]; then
-    mknod /var/lib/partman/infifo p >/dev/null 2>/dev/null || true
-    mknod /var/lib/partman/outfifo p >/dev/null 2>/dev/null || true
-    mknod /var/lib/partman/stopfifo p >/dev/null 2>/dev/null || true
     [ -d /var/run ] || mkdir /var/run
-    parted_server &
-    echo $! >/var/run/parted_server.pid
+    parted_server
+    RET=$?
+    if [ $RET != 0 ]; then
+        # TODO: How do we signal we couldn't start partman_server properly?
+        exit $RET
+    fi
 
     if [ -d /var/lib/partman/old_devices ]; then
 	rm -rf /var/lib/partman/old_devices
Index: parted_server.c
===================================================================
--- parted_server.c	(revision 37382)
+++ parted_server.c	(working copy)
@@ -8,11 +8,20 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <ctype.h>
+#include <signal.h>
 
 /**********************************************************************
    Logging
 **********************************************************************/
 
+/* This file is used as pid-file. */
+char pidfile_name[] = "/var/run/parted_server.pid";
+
+/* These are the communication fifos */
+char infifo_name[] = "/var/lib/partman/infifo";
+char outfifo_name[] = "/var/lib/partman/outfifo";
+char stopfifo_name[] = "/var/lib/partman/stopfifo";
+
 /* This file is used as log-file. */
 char logfile_name[] = "/var/log/partman";
 
@@ -2053,6 +2062,91 @@
         activate_exception_handler();
 }
 
+void
+make_fifo(char* name)
+{
+    int status;
+    status = mkfifo(name, 0x644);
+    if ((status != 0))
+            if (errno != EEXIST) {
+                    perror("Cannot create FIFO");
+                    exit(252);
+            }
+}
+
+void
+make_fifos()
+{
+    make_fifo(infifo_name);
+    make_fifo(outfifo_name);
+    make_fifo(stopfifo_name);
+}   
+
+int
+write_pid_file()
+{
+        FILE *fd;
+        int status;
+        pid_t oldpid;
+        if ((fd = fopen(pidfile_name, "a+")) == NULL)
+                return -1;
+
+        if (!feof(fd)) {
+                status = fscanf(fd, "%d", &oldpid);
+                if (status != 0) {
+                        // If kill(oldpid, 0) == 0 the process is still alive
+                        // so we abort
+                        if (kill(oldpid, 0) == 0) {
+                                fprintf(stderr, "Not starting: process %d still exists\n", oldpid);
+                                fclose(fd);
+                                exit(250);
+                        }
+                }
+                // Truncate the pid file and continue
+                freopen(pidfile_name, "w", fd);
+        }
+        
+        fprintf(fd, "%d", (int)(getpid()));
+        fclose(fd);
+        return 0;
+}
+
+void
+cleanup_and_die()
+{
+        if (unlink(pidfile_name) != 0)
+                perror("Cannot unlink pid file");
+        if (unlink(infifo_name) != 0)
+                perror("Cannot unlink input FIFO");
+        if (unlink(outfifo_name) != 0)
+                perror("Cannot unlink output FIFO");
+        if (unlink(stopfifo_name) != 0)
+                perror("Cannot unlink stop FIFO");
+}
+
+void
+prnt_sig_hdlr(int signal)
+{
+        int status;
+        switch(signal) {
+                // SIGUSR1 signals that child is ready to take
+                // requests (i.e. has finished initialisation)
+                case SIGUSR1:
+                    exit(0);
+                    break;
+                // We'll only get SIGCHLD if our child has pre-deceased us
+                // In this case we should exit with its error code
+                case SIGCHLD:
+                    if (waitpid(-1, &status, WNOHANG) < 0) 
+                        exit(0);
+                    if (WIFEXITED(status))
+                        exit(WEXITSTATUS(status));
+                    break;
+                default:
+                    break;
+        }
+}
+
 /**********************************************************************
    Main
 **********************************************************************/
@@ -2149,11 +2243,51 @@
 int
 main(int argc, char *argv[])
 {
+        // Set up signal handling
+        struct sigaction act, oldact;
+        act.sa_handler = prnt_sig_hdlr;
+        sigemptyset(&act.sa_mask);
+
+        // Set up signal handling for parent
+        if  ((sigaction(SIGCHLD, &act, &oldact) < 0) 
+          || (sigaction(SIGUSR1, &act, &oldact) < 0))
+        {
+            fprintf(stderr, "Could not set up signal handling for parent\n");
+            exit(251);
+        }
+        
+        // The parent process should wait; we die once child is
+        // initialised (signalled by a SIGUSR1)
+        if (fork()) {
+            while (1) { sleep(5); };
+        }
+
+        // Set up signal handling for child
+        if  ((sigaction(SIGCHLD, &oldact, NULL) < 0) 
+          || (sigaction(SIGUSR1, &oldact, NULL) < 0))
+        {
+            fprintf(stderr, "Could not set up signal handling for child\n");
+            exit(250);
+        }
+ 
+        // Continue as a daemon process
         logfile = fopen(logfile_name, "a+");
         if (logfile == NULL) {
                 fprintf(stderr, "Cannot append to the log file\n");
                 exit(255);
         }
+        if (write_pid_file() != 0) {
+                fprintf(stderr, "Cannot open pid file\n");
+                exit(254);
+        }
+        if (atexit(cleanup_and_die) != 0) {
+                fprintf(stderr, "Cannot set atexit routine\n");
+                exit(253);
+        }
+        make_fifos();
+        // Signal that we've finished initialising so that the parent process
+        // can die and the shell scripts can continue
+        kill(getppid(), SIGUSR1);
         ped_exception_set_handler(exception_handler);
         log("======= Starting the server");
         main_loop();

Attachment: signature.asc
Description: Digital signature


Reply to: