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 <neilb@suse.de>
This commit is contained in:
NeilBrown 2014-05-14 16:34:06 +10:00
parent 54ded86fbd
commit 5e76dce1ac
3 changed files with 76 additions and 2 deletions

60
Grow.c
View File

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

View File

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

View File

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