From 5e76dce1acd906e8fc8af04973c3a129cdc77fd6 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 14 May 2014 16:34:06 +1000 Subject: [PATCH] Grow: try to let "--grow --continue" from systemd complete a reshape. 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 --- Grow.c | 60 +++++++++++++++++++++++++++- Makefile | 1 + systemd/mdadm-grow-continue@.service | 17 ++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 systemd/mdadm-grow-continue@.service diff --git a/Grow.c b/Grow.c index 710c4c1..f6a989d 100644 --- a/Grow.c +++ b/Grow.c @@ -26,6 +26,7 @@ #include #include #include +#include #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); diff --git a/Makefile b/Makefile index b823d85..3af030b 100644 --- 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 index 0000000..314a4fa --- /dev/null +++ b/systemd/mdadm-grow-continue@.service @@ -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