From 0f7bdf8946316548500858303549e396655450c5 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 1 Feb 2013 16:15:18 +0100 Subject: [PATCH] Add support for launching mdmon via systemctl instead of fork/exec If launching mdmon via systemctl fails, we fall back to the old method of fork/exec. This allows for having mdmon launched via systemctl which avoids problems with it getting killed by systemd due to it ending up in the parent's cgroup (udev). Signed-off-by: Jes Sorensen Signed-off-by: NeilBrown --- Makefile | 4 ++++ systemd/mdmon@.service | 18 ++++++++++++++++++ util.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 systemd/mdmon@.service diff --git a/Makefile b/Makefile index b9787d64..b6edb23d 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,7 @@ MAP_PATH = $(MAP_DIR)/$(MAP_FILE) MDMON_DIR = $(MAP_DIR) # place for autoreplace cookies FAILED_SLOTS_DIR = /run/mdadm/failed-slots +SYSTEMD_DIR=/lib/systemd/system DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\" DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\" DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\" @@ -264,6 +265,9 @@ install-man: mdadm.8 md.4 mdadm.conf.5 mdmon.8 install-udev: udev-md-raid.rules $(INSTALL) -D -m 644 udev-md-raid.rules $(DESTDIR)$(UDEVDIR)/rules.d/64-md-raid.rules +install-systemd: systemd/mdmon@.service + $(INSTALL) -D -m 644 systemd/mdmon@.service $(DESTDIR)$(SYSTEMD_DIR)/mdmon@.service + uninstall: rm -f $(DESTDIR)$(MAN8DIR)/mdadm.8 $(DESTDIR)$(MAN8DIR)/mdmon.8 $(DESTDIR)$(MAN4DIR)/md.4 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5 $(DESTDIR)$(BINDIR)/mdadm diff --git a/systemd/mdmon@.service b/systemd/mdmon@.service new file mode 100644 index 00000000..ddb475f2 --- /dev/null +++ b/systemd/mdmon@.service @@ -0,0 +1,18 @@ +# This file is part of mdadm. +# +# mdadm is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +[Unit] +Description=MD Metadata Monitor on /dev/%I +DefaultDependencies=no +Before=initrd-switch-root.target + +[Service] +ExecStart=/sbin/mdmon %I +StandardInput=null +StandardOutput=null +StandardError=null +KillMode=none diff --git a/util.c b/util.c index e75b7549..01af0b5e 100644 --- a/util.c +++ b/util.c @@ -1660,6 +1660,34 @@ int start_mdmon(int devnum) } else pathbuf[0] = '\0'; + /* First try to run systemctl */ + switch(fork()) { + case 0: + /* FIXME yuk. CLOSE_EXEC?? */ + skipped = 0; + for (i = 3; skipped < 20; i++) + if (close(i) < 0) + skipped++; + else + skipped = 0; + + snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service", + devnum2devname(devnum)); + status = execl("/usr/bin/systemctl", "systemctl", "start", + pathbuf, NULL); + status = execl("/bin/systemctl", "systemctl", "start", + pathbuf, NULL); + exit(1); + case -1: pr_err("cannot run mdmon. " + "Array remains readonly\n"); + return -1; + default: /* parent - good */ + pid = wait(&status); + if (pid >= 0 && status == 0) + return 0; + } + + /* That failed, try running mdmon directly */ switch(fork()) { case 0: /* FIXME yuk. CLOSE_EXEC?? */ -- 2.39.2