forked from pool/s390-tools
d3b5067da2
- Added the following patches (bsc#1070836): s390-tools-sles15-cpuplugd-Improve-systemctl-start-error-handling.patch s390-tools-sles15-mon_tools-Improve-systemctl-start-error-handling.patch s390-tools-sles15-lsluns-do-not-scan-all-if-filters-match-nothing.patch s390-tools-sles15-lsluns-do-not-print-confusing-messages-when-a-filter.patch s390-tools-sles15-lsluns-fix-flawed-formatting-of-man-page.patch s390-tools-sles15-lsluns-enhance-usage-statement-and-man-page.patch s390-tools-sles15-lsluns-clarify-discovery-use-case-relation-to-NPIV-a.patch s390-tools-sles15-lsluns-point-out-IBM-Storwize-configuration-requirem.patch s390-tools-sles15-lsluns-document-restriction-to-zfcp-only-systems.patch s390-tools-sles15-lsluns-complement-alternative-tools-with-lszdev.patch OBS-URL: https://build.opensuse.org/request/show/554611 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=40
203 lines
6.4 KiB
Diff
203 lines
6.4 KiB
Diff
Subject: [PATCH] [BZ 161563] cpuplugd: Improve systemctl start error handling
|
|
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
|
|
|
Description: cpuplugd, mon_tools: Improve systemctl start error handling
|
|
Symptom: "systemctl start cpuplugd/mon_procd/mon_fsstatd" does not
|
|
report any errors in case the startup fails.
|
|
Problem: For type=simple, systemd forks/execs the process and if that
|
|
is successful, it immediately returns. There is no way to
|
|
find out if the initial startup fails.
|
|
Solution: Use type=fork and run the process in the background. In this
|
|
case systemd waits until the initial process returns.
|
|
In addition, use PIDFile and ensure that the pid file is
|
|
already available when the initial process returns. To
|
|
achieve this, use startup synchronization via pipe.
|
|
Reproduction: Add invalid values to the config files and start the daemons
|
|
with "systemctl start cpuplugd/mon_procd/mon_fsstatd".
|
|
Upstream-ID: 82c8148983fc09e9bfa5bf852b2d39571f8475a0
|
|
Problem-ID: 161563
|
|
|
|
Upstream-Description:
|
|
|
|
cpuplugd: Improve systemctl start error handling
|
|
|
|
Currently "systemctl start cpuplugd" does not report any errors in
|
|
case the startup fails.
|
|
|
|
Example:
|
|
|
|
# mv /etc/cpuplugd.conf /etc/cpuplugd.conf.xxx
|
|
# systemctl start cpuplugd
|
|
|
|
The reason is that for type=simple systemd forks/execs cpuplugd and if
|
|
that is successful immediately returns. There is no way to find out
|
|
if the initial startup fails.
|
|
|
|
Fix this by using type=fork and running cpuplugd in the background. In
|
|
this case systemd waits until the initial process returns.
|
|
|
|
In addition use PIDFile and ensure that the pid file is already available
|
|
when the initial cpuplugd process returns. To achieve this, replace the
|
|
daemon() function by our own implementation that introduces startup
|
|
synchronization via pipe. Without that systemd would print the following
|
|
warning:
|
|
|
|
systemd[1]: cpuplugd.service: PID file /var/run/cpuplugd.pid not readable
|
|
(yet?) after start: No such file or directory
|
|
|
|
With this patch, an early startup error like in the example above, is now
|
|
reported correctly in "systemctl start":
|
|
|
|
# systemctl start cpuplugd
|
|
Job for cpuplugd.service failed because the control process exited...
|
|
See "systemctl status cpuplugd.service" and "journalctl -xe" for ...
|
|
# journalctl -ex | grep cpuplugd
|
|
Nov 16 15:52:27 ... cpuplugd[5096]: Opening configuration file failed:
|
|
No such file or directory
|
|
|
|
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
|
Acked-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
|
|
|
|
|
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
|
---
|
|
cpuplugd/cpuplugd.h | 2 -
|
|
cpuplugd/daemon.c | 60 ++++++++++++++++++++++++++++++++++++++++++--
|
|
cpuplugd/main.c | 4 --
|
|
systemd/cpuplugd.service.in | 5 ++-
|
|
4 files changed, 63 insertions(+), 8 deletions(-)
|
|
|
|
--- a/cpuplugd/cpuplugd.h
|
|
+++ b/cpuplugd/cpuplugd.h
|
|
@@ -197,10 +197,10 @@ int is_online(int cpuid);
|
|
long get_cmmpages_size();
|
|
void parse_options(int argc, char **argv);
|
|
void check_if_started_twice();
|
|
-void store_pid(void);
|
|
void handle_signals(void);
|
|
void handle_sighup(void);
|
|
void reload_daemon(void);
|
|
+int daemonize(void);
|
|
int check_cmmfiles(void);
|
|
void check_config();
|
|
void set_cmm_pages(long size);
|
|
--- a/cpuplugd/daemon.c
|
|
+++ b/cpuplugd/daemon.c
|
|
@@ -9,6 +9,10 @@
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
+#include <fcntl.h>
|
|
+#include <sys/stat.h>
|
|
+#include <sys/types.h>
|
|
+
|
|
#include "cpuplugd.h"
|
|
|
|
const char *name = NAME;
|
|
@@ -49,7 +53,7 @@ void print_version()
|
|
/*
|
|
* Store daemon's pid so it can be stopped
|
|
*/
|
|
-void store_pid(void)
|
|
+static int store_pid(void)
|
|
{
|
|
FILE *filp;
|
|
|
|
@@ -57,10 +61,62 @@ void store_pid(void)
|
|
if (!filp) {
|
|
cpuplugd_error("cannot open pid file %s: %s\n", pid_file,
|
|
strerror(errno));
|
|
- exit(1);
|
|
+ return -1;
|
|
}
|
|
fprintf(filp, "%d\n", getpid());
|
|
fclose(filp);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Run daemon in background and write pid file
|
|
+ */
|
|
+int daemonize(void)
|
|
+{
|
|
+ int fd, pipe_fds[2], startup_rc = 1;
|
|
+ pid_t pid;
|
|
+
|
|
+ if (pipe(pipe_fds) == -1) {
|
|
+ cpuplugd_error("cannot create pipe\n");
|
|
+ return -1;
|
|
+ }
|
|
+ pid = fork();
|
|
+ if (pid < 0)
|
|
+ goto close_pipe;
|
|
+ if (pid != 0) {
|
|
+ /* Wait for startup return code from daemon */
|
|
+ if (read(pipe_fds[0], &startup_rc, sizeof(startup_rc)) == -1)
|
|
+ cpuplugd_error("cannot read from pipe\n");
|
|
+ /* On success daemon has written pid file at this point */
|
|
+ exit(startup_rc);
|
|
+ }
|
|
+ /* Create new session */
|
|
+ if (setsid() < 0)
|
|
+ goto notify_parent;
|
|
+ /* Redirect stdin/out/err to /dev/null */
|
|
+ fd = open("/dev/null", O_RDWR, 0);
|
|
+ if (fd == -1)
|
|
+ goto notify_parent;
|
|
+ if (dup2(fd, STDIN_FILENO) < 0)
|
|
+ goto notify_parent;
|
|
+ if (dup2(fd, STDOUT_FILENO) < 0)
|
|
+ goto notify_parent;
|
|
+ if (dup2(fd, STDERR_FILENO) < 0)
|
|
+ goto notify_parent;
|
|
+ /* Create pid file */
|
|
+ if (store_pid() < 0)
|
|
+ goto notify_parent;
|
|
+ startup_rc = 0;
|
|
+notify_parent:
|
|
+ /* Inform waiting parent about startup return code */
|
|
+ if (write(pipe_fds[1], &startup_rc, sizeof(startup_rc)) == -1) {
|
|
+ cpuplugd_error("cannot write to pipe\n");
|
|
+ startup_rc = 1;
|
|
+ }
|
|
+close_pipe:
|
|
+ close(pipe_fds[0]);
|
|
+ close(pipe_fds[1]);
|
|
+ return startup_rc ? -1 : 0;
|
|
}
|
|
|
|
/*
|
|
--- a/cpuplugd/main.c
|
|
+++ b/cpuplugd/main.c
|
|
@@ -418,13 +418,11 @@ int main(int argc, char *argv[])
|
|
check_config();
|
|
|
|
if (!foreground) {
|
|
- rc = daemon(1, 0);
|
|
+ rc = daemonize();
|
|
if (rc < 0)
|
|
cpuplugd_exit("Detach from terminal failed: %s\n",
|
|
strerror(errno));
|
|
}
|
|
- /* Store daemon pid */
|
|
- store_pid();
|
|
/* Unlock lock file */
|
|
flock(fd, LOCK_UN);
|
|
close(fd);
|
|
--- a/systemd/cpuplugd.service.in
|
|
+++ b/systemd/cpuplugd.service.in
|
|
@@ -13,10 +13,11 @@ Documentation=man:cpuplugd(8) man:cpuplu
|
|
After=remote-fs.target
|
|
|
|
[Service]
|
|
-ExecStart=@usrsbin_path@/cpuplugd -f -c /etc/cpuplugd.conf
|
|
+ExecStart=@usrsbin_path@/cpuplugd -c /etc/cpuplugd.conf
|
|
ExecReload=/bin/kill -HUP $MAINPID
|
|
KillMode=process
|
|
-Type=simple
|
|
+Type=forking
|
|
+PIDFile=/var/run/cpuplugd.pid
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|