]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
Grow: Use 'forked' also for reshape_container in Grow_continue
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index 2f171521d3b143e3858964b35818b43294114671..2de821d0b9d432b8b6945ed417f91d1f6e188a0a 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -24,6 +24,7 @@
 #include       "mdadm.h"
 #include       "dlink.h"
 #include       <sys/mman.h>
+#include       <stddef.h>
 #include       <stdint.h>
 #include       <signal.h>
 #include       <sys/wait.h>
 #include       "md_u.h"
 #include       "md_p.h"
 
-#ifndef offsetof
-#define offsetof(t,f) ((size_t)&(((t*)0)->f))
-#endif
-
 int restore_backup(struct supertype *st,
                   struct mdinfo *content,
                   int working_disks,
@@ -1325,7 +1322,6 @@ char *analyse_change(char *devname, struct mdinfo *info, struct reshape *re)
 
                switch (re->level) {
                case 4:
-                       re->before.layout = 0;
                        re->after.layout = 0;
                        break;
                case 5:
@@ -2753,6 +2749,48 @@ 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",
+                              "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)
+                       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,
@@ -3232,54 +3270,13 @@ 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;
-                       }
+       if (!forked && !check_env("MDADM_NO_SYSTEMCTL"))
+               if (continue_via_systemd(container ?: sra->sys_name)) {
+                       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...
@@ -3474,6 +3471,10 @@ int reshape_container(char *container, char *devname,
         */
        ping_monitor(container);
 
+       if (!forked && !check_env("MDADM_NO_SYSTEMCTL"))
+               if (continue_via_systemd(container))
+                       return 0;
+
        switch (forked ? 0 : fork()) {
        case -1: /* error */
                perror("Cannot fork to complete reshape\n");
@@ -4915,7 +4916,7 @@ int Grow_continue_command(char *devname, int fd,
 
        /* continue reshape
         */
-       ret_val = Grow_continue(fd, st, content, backup_file, 0);
+       ret_val = Grow_continue(fd, st, content, backup_file, 1, 0);
 
 Grow_continue_command_exit:
        if (fd2 > -1)
@@ -4931,7 +4932,7 @@ Grow_continue_command_exit:
 }
 
 int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
-                 char *backup_file, int freeze_reshape)
+                 char *backup_file, int forked, int freeze_reshape)
 {
        int ret_val = 2;
 
@@ -4948,13 +4949,13 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
                close(cfd);
                ret_val = reshape_container(st->container_devnm, NULL, mdfd,
                                            st, info, 0, backup_file,
-                                           0, 1,
+                                           0, forked,
                                            1 | info->reshape_active,
                                            freeze_reshape);
        } else
                ret_val = reshape_array(NULL, mdfd, "array", st, info, 1,
                                        NULL, INVALID_SECTORS,
-                                       backup_file, 0, 1,
+                                       backup_file, 0, forked,
                                        1 | info->reshape_active,
                                        freeze_reshape);