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 <Jes.Sorensen@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Jes Sorensen 2013-02-01 16:15:18 +01:00 committed by NeilBrown
parent 3e23ba9d7b
commit 0f7bdf8946
3 changed files with 50 additions and 0 deletions

View File

@ -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

18
systemd/mdmon@.service Normal file
View File

@ -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

28
util.c
View File

@ -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?? */