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