]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add support for launching mdmon via systemctl instead of fork/exec
authorJes Sorensen <Jes.Sorensen@redhat.com>
Fri, 1 Feb 2013 15:15:18 +0000 (16:15 +0100)
committerNeilBrown <neilb@suse.de>
Tue, 5 Feb 2013 04:40:38 +0000 (15:40 +1100)
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>
Makefile
systemd/mdmon@.service [new file with mode: 0644]
util.c

index b9787d641cded558ef7bdc0bdb05fafb78b640b6..b6edb23d4f03c520759030a203c0ec5e5427105d 100644 (file)
--- 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 (file)
index 0000000..ddb475f
--- /dev/null
@@ -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 e75b75493c4c0ff0d80604a5335676552a077d33..01af0b5e580fbb948e5088b92757b9ed889a4d42 100644 (file)
--- 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?? */