]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: try to let "--grow --continue" from systemd complete a reshape.
authorNeilBrown <neilb@suse.de>
Wed, 14 May 2014 06:34:06 +0000 (16:34 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 15 May 2014 04:23:21 +0000 (14:23 +1000)
If "--assemble" or "--incremental" is started by udev, then
monitoring the reshape in the background won't work.

So try asking systemd to start a grow-continue.

If that fails, just do it the old way.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c
Makefile
systemd/mdadm-grow-continue@.service [new file with mode: 0644]

diff --git a/Grow.c b/Grow.c
index 710c4c112b13d10829dad1111bbc0aada67527a0..f6a989daf411d044e77577b57d3c63f758c38be9 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -26,6 +26,7 @@
 #include       <sys/mman.h>
 #include       <stdint.h>
 #include       <signal.h>
+#include       <sys/wait.h>
 
 #if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
 #error no endian defined
@@ -3231,6 +3232,55 @@ started:
                return 1;
        }
 
+       if (!forked && !check_env("MDADM_NO_SYSTEMCTL")) {
+               int skipped, i, pid, status;
+               char pathbuf[1024];
+               char *devnm;
+               /* In a systemd/udev world, it is best to get systemd to
+                * run "mdadm --grow --continue" rather than running in the
+                * background.
+                */
+               if (container)
+                       devnm = container;
+               else
+                       devnm = sra->sys_name;
+               switch(fork()) {
+               case  0:
+                       /* FIXME yuk. CLOSE_EXEC?? */
+                       skipped = 0;
+                       for (i = 3; skipped < 20; i++)
+                               if (close(i) < 0)
+                                       skipped++;
+                               else
+                                       skipped = 0;
+
+                       /* Don't want to see error messages from
+                        * systemctl.  If the service doesn't exist,
+                        * we fork ourselves.
+                        */
+                       close(2);
+                       open("/dev/null", O_WRONLY);
+                       snprintf(pathbuf, sizeof(pathbuf), "mdadm-grow-continue@%s.service",
+                                devnm);
+                       status = execl("/usr/bin/systemctl", "systemctl",
+                                      "start",
+                                      pathbuf, NULL);
+                       status = execl("/bin/systemctl", "systemctl", "start",
+                                      pathbuf, NULL);
+                       exit(1);
+               case -1: /* Just do it ourselves. */
+                       break;
+               default: /* parent - good */
+                       pid = wait(&status);
+                       if (pid >= 0 && status == 0) {
+                               free(fdlist);
+                               free(offsets);
+                               sysfs_free(sra);
+                               return 0;
+                       }
+               }
+       }
+
        /* Now we just need to kick off the reshape and watch, while
         * handling backups of the data...
         * This is all done by a forked background process.
@@ -3312,12 +3362,18 @@ started:
 
        if (backup_file && done) {
                char *bul;
-               unlink(backup_file);
                bul = make_backup(sra->sys_name);
                if (bul) {
+                       char buf[1024];
+                       int l = readlink(bul, buf, sizeof(buf));
+                       if (l > 0) {
+                               buf[l]=0;
+                               unlink(buf);
+                       }
                        unlink(bul);
                        free(bul);
                }
+               unlink(backup_file);
        }
        if (!done) {
                abort_reshape(sra);
@@ -4898,7 +4954,7 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
        } else
                ret_val = reshape_array(NULL, mdfd, "array", st, info, 1,
                                        NULL, INVALID_SECTORS,
-                                       backup_file, 0, 0,
+                                       backup_file, 0, 1,
                                        1 | info->reshape_active,
                                        freeze_reshape);
 
index b823d85f89e313c6095f9e4d312fb3817aa58e74..3af030b56590e932abc50026b03ce1b836631c27 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -288,6 +288,7 @@ install-systemd: systemd/mdmon@.service
        $(INSTALL) -D -m 644 systemd/mdmonitor.service $(DESTDIR)$(SYSTEMD_DIR)/mdmonitor.service
        $(INSTALL) -D -m 644 systemd/mdadm-last-resort@.timer $(DESTDIR)$(SYSTEMD_DIR)/mdadm-last-resort@.timer
        $(INSTALL) -D -m 644 systemd/mdadm-last-resort@.service $(DESTDIR)$(SYSTEMD_DIR)/mdadm-last-resort@.service
+       $(INSTALL) -D -m 644 systemd/mdadm-grow-continue@.service $(DESTDIR)$(SYSTEMD_DIR)/mdadm-grow-continue@.service
        $(INSTALL) -D -m 755 systemd/mdadm.shutdown $(DESTDIR)$(SYSTEMD_DIR)-shutdown/mdadm.shutdown
        if [ -f /etc/SuSE-release -o -n "$(SUSE)" ] ;then $(INSTALL) -D -m 755 systemd/SUSE-mdadm_env.sh $(DESTDIR)$(SYSTEMD_DIR)/../scripts/mdadm_env.sh ;fi
 
diff --git a/systemd/mdadm-grow-continue@.service b/systemd/mdadm-grow-continue@.service
new file mode 100644 (file)
index 0000000..314a4fa
--- /dev/null
@@ -0,0 +1,17 @@
+#  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=Manage MD Reshape on /dev/%I
+DefaultDependencies=no
+
+[Service]
+ExecStart=/sbin/mdadm --grow --continue /dev/%I
+StandardInput=null
+StandardOutput=null
+StandardError=null
+KillMode=none