]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Document PPL in man md
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index 57db7d454800c6f850608694e27e353aff62017f..cec83886f2c1dfa28952059f9e59afdbe6abaf40 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -197,7 +197,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
        info.disk.minor = minor(rdev);
        info.disk.raid_disk = d;
        info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
-       st->ss->update_super(st, &info, "linear-grow-new", newdev, 0, 0, NULL);
+       if (st->ss->update_super(st, &info, "linear-grow-new", newdev,
+                                0, 0, NULL) != 0) {
+               pr_err("Preparing new metadata failed on %s\n", newdev);
+               close(nfd);
+               return 1;
+       }
 
        if (st->ss->store_super(st, nfd)) {
                pr_err("Cannot store new superblock on %s\n", newdev);
@@ -250,8 +255,12 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                info.array.active_disks = nd+1;
                info.array.working_disks = nd+1;
 
-               st->ss->update_super(st, &info, "linear-grow-update", dv,
-                                    0, 0, NULL);
+               if (st->ss->update_super(st, &info, "linear-grow-update", dv,
+                                    0, 0, NULL) != 0) {
+                       pr_err("Updating metadata failed on %s\n", dv);
+                       close(fd2);
+                       return 1;
+               }
 
                if (st->ss->store_super(st, fd2)) {
                        pr_err("Cannot store new superblock on %s\n", dv);
@@ -931,12 +940,15 @@ int start_reshape(struct mdinfo *sra, int already_running,
        err = err ?: sysfs_set_num(sra, NULL, "sync_max", sync_max_to_set);
        if (!already_running && err == 0) {
                int cnt = 5;
+               int err2;
                do {
                        err = sysfs_set_str(sra, NULL, "sync_action",
                                            "reshape");
-                       if (err)
+                       err2 = sysfs_set_str(sra, NULL, "sync_max",
+                                           "max");
+                       if (err || err2)
                                sleep(1);
-               } while (err && errno == EBUSY && cnt-- > 0);
+               } while (err && err2 && errno == EBUSY && cnt-- > 0);
        }
        return err;
 }
@@ -2982,47 +2994,6 @@ static void catch_term(int sig)
        sigterm = 1;
 }
 
-static int continue_via_systemd(char *devnm)
-{
-       int skipped, i, pid, status;
-       char pathbuf[1024];
-       /* In a systemd/udev world, it is best to get systemd to
-        * run "mdadm --grow --continue" rather than running in the
-        * background.
-        */
-       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", "restart",
-                              pathbuf, NULL);
-               status = execl("/bin/systemctl", "systemctl", "restart",
-                              pathbuf, NULL);
-               exit(1);
-       case -1: /* Just do it ourselves. */
-               break;
-       default: /* parent - good */
-               pid = wait(&status);
-               if (pid >= 0 && status == 0)
-                       return 1;
-       }
-       return 0;
-}
-
 static int reshape_array(char *container, int fd, char *devname,
                         struct supertype *st, struct mdinfo *info,
                         int force, struct mddev_dev *devlist,
@@ -3401,6 +3372,7 @@ static int reshape_array(char *container, int fd, char *devname,
                default: /* parent */
                        return 0;
                case 0:
+                       manage_fork_fds(0);
                        map_fork();
                        break;
                }
@@ -3509,8 +3481,9 @@ started:
                return 1;
        }
 
-       if (!forked && !check_env("MDADM_NO_SYSTEMCTL"))
-               if (continue_via_systemd(container ?: sra->sys_name)) {
+       if (!forked)
+               if (continue_via_systemd(container ?: sra->sys_name,
+                                        GROW_SERVICE)) {
                        free(fdlist);
                        free(offsets);
                        sysfs_free(sra);
@@ -3704,8 +3677,8 @@ int reshape_container(char *container, char *devname,
         */
        ping_monitor(container);
 
-       if (!forked && !freeze_reshape && !check_env("MDADM_NO_SYSTEMCTL"))
-               if (continue_via_systemd(container))
+       if (!forked && !freeze_reshape)
+               if (continue_via_systemd(container, GROW_SERVICE))
                        return 0;
 
        switch (forked ? 0 : fork()) {
@@ -3718,6 +3691,7 @@ int reshape_container(char *container, char *devname,
                        printf("%s: multi-array reshape continues in background\n", Name);
                return 0;
        case 0: /* child */
+               manage_fork_fds(0);
                map_fork();
                break;
        }