slurm/split-xdaemon-in-xdaemon_init-and-xdaemon_finish-for-systemd-compatibilty.patch
Egbert Eich 8d80dfc527 - Fix interaction with systemd: systemd expects that a
daemonizing process doesn't go away until the PID file
  with it PID of the daemon has bee written (bsc#1084125).

OBS-URL: https://build.opensuse.org/package/show/network:cluster/slurm?expand=0&rev=52
2018-04-12 16:42:36 +00:00

157 lines
3.8 KiB
Diff

From: Christian Goll <cgoll@suse.de>
Date: Mon Apr 9 10:05:50 2018 +0200
Subject: split xdaemon in xdaemon_init and xdaemon_finish for systemd compatibilty
Patch-mainline: Not yet
Git-repo: https://github.com/SchedMD/slurm
Git-commit: 2bbe988c0ef133942d0d0077b0f064eff553e3a2
References: bsc#1084125
Signed-off-by: Egbert Eich <eich@suse.de>
---
src/common/daemonize.c | 73 ++++++++++++++++++++++++++++++++++++++++++++------
src/common/daemonize.h | 20 ++++++++++++++
2 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/src/common/daemonize.c b/src/common/daemonize.c
index e22a1d0a7f..2987a40af0 100644
--- a/src/common/daemonize.c
+++ b/src/common/daemonize.c
@@ -53,31 +53,75 @@
#include "src/common/xassert.h"
/*
- * Double-fork and go into background.
+ * Start daemonization with double-fork and go into background.
* Caller is responsible for umasks
*/
-int xdaemon(void)
+int xdaemon_init(void)
{
- int devnull;
-
+ int fds [2];
+ int n;
+ signed char priority;
+ char ebuf [1024];
+ /*
+ * Create pipe in order to get signal from grand child to terminate
+ */
+ if (pipe (fds) < 0) {
+ error("Failed to create daemon pipe");
+ }
switch (fork()) {
case 0 : break; /* child */
case -1 : return -1;
- default : _exit(0); /* exit parent */
+ default : {
+ if (close (fds[1]) < 0) {
+ error("Failed to close write-pipe in parent process");
+ }
+
+ /*
+ * get signal of grandchild to exit
+ */
+ if ((n = read (fds[0], &priority, sizeof (priority))) < 0) {
+ error("Failed to read status from grandchild process");
+ }
+ if ((n > 0) && (priority >= 0)) {
+ if ((n = read (fds[0], ebuf, sizeof (ebuf))) < 0) {
+ error("Failed to read err msg from grandchild process");
+ }
+ if ((n > 0) && (ebuf[0] != '\0')) {
+ error("Error with forking and steeing up pipe: %s", ebuf);
+ }
+ return -1;
+ }
+ _exit(0);
+ }
}
if (setsid() < 0)
return -1;
-
+ if (close (fds[0]) < 0) {
+ error("Failed to close read-pipe in child process");
+ }
switch (fork()) {
case 0 : break; /* child */
case -1: return -1;
default: _exit(0); /* exit parent */
}
+ return (fds[1]);
+}
+/*
+ * finish daemonization after pidfile was written
+ */
+
+
+void xdaemon_finish(int fd)
+{
/*
- * dup stdin, stdout, and stderr onto /dev/null
+ * PID file was written, now do dup stdin, stdout,
+ * and stderr onto /dev/null and close pipe
+ * so that systemd realizes we are daemonized
*/
+ int devnull;
+
devnull = open("/dev/null", O_RDWR);
if (devnull < 0)
error("Unable to open /dev/null: %m");
@@ -89,8 +133,21 @@ int xdaemon(void)
error("Unable to dup /dev/null onto stderr: %m");
if (close(devnull) < 0)
error("Unable to close /dev/null: %m");
+ if ((fd >= 0) && (close (fd) < 0)) {
+ error( "Failed to close write-pipe in grandchild process");
+ }
+}
+
+/*
+ * keep depercated api
+ */
- return 0;
+int xdaemon(void)
+{
+ int ret_val;
+ ret_val= xdaemon_init();
+ xdaemon_finish(ret_val);
+ return ret_val;
}
/*
diff --git a/src/common/daemonize.h b/src/common/daemonize.h
index 22a31f6ccf..c932d83f74 100644
--- a/src/common/daemonize.h
+++ b/src/common/daemonize.h
@@ -40,6 +40,26 @@
#ifndef _HAVE_DAEMONIZE_H
#define _HAVE_DAEMONIZE_H
+
+/*
+ * Fork process into background open a pipe to
+ * communicate status between parent and child.
+ * parent: wait until child has closed the pipe.
+ * child: return fd.
+ *
+ * Returns fd or -1 on error.
+ */
+extern int xdaemon_init(void);
+
+/*
+ * Finish child side of the fork:
+ * This needs to get called after the PID file
+ * has been written.
+ * Close STDIN, STDOUT and STDERR and inherit
+ * new session. Close pipe when done.
+ */
+extern void xdaemon_finish(int fd);
+
/*
* Fork process into background and inherit new session.
*