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