X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=Grow.c;h=5c2512f6318026bcfae2975fd07758f889172f29;hb=4ae96c802203ec3c;hp=4436a4d6bd4cdff4fe3ebe03c2a1f3eebdf33196;hpb=84d88fd885de05a5f126a1f3661687c541001e39;p=thirdparty%2Fmdadm.git diff --git a/Grow.c b/Grow.c index 4436a4d6..5c2512f6 100644 --- a/Grow.c +++ b/Grow.c @@ -446,7 +446,7 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s) if (offset_setable) { st->ss->getinfo_super(st, mdi, NULL); if (sysfs_init(mdi, fd, NULL)) { - pr_err("failed to intialize sysfs.\n"); + pr_err("failed to initialize sysfs.\n"); free(mdi); } rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location", @@ -931,12 +931,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; } @@ -1196,7 +1199,8 @@ unsigned long compute_backup_blocks(int nchunk, int ochunk, /* Find GCD */ a = GCD(a, b); /* LCM == product / GCD */ - blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a; + blocks = (unsigned long)(ochunk/512) * (unsigned long)(nchunk/512) * + odata * ndata / a; return blocks; } @@ -2177,7 +2181,7 @@ size_change_error: memset(&info, 0, sizeof(info)); info.array = array; if (sysfs_init(&info, fd, NULL)) { - pr_err("failed to intialize sysfs.\n"); + pr_err("failed to initialize sysfs.\n"); rv = 1; goto release; } @@ -2612,8 +2616,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st, goto release; } if (data_offset != INVALID_SECTORS && - data_offset < sd->data_offset - min) { - pr_err("--data-offset too small on %s\n", + data_offset > sd->data_offset - min) { + pr_err("--data-offset too large on %s\n", dn); goto release; } @@ -2902,7 +2906,7 @@ static int impose_level(int fd, int level, char *devname, int verbose) struct mdinfo info; if (sysfs_init(&info, fd, NULL)) { - pr_err("failed to intialize sysfs.\n"); + pr_err("failed to initialize sysfs.\n"); return 1; } @@ -2981,47 +2985,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, @@ -3285,7 +3248,7 @@ static int reshape_array(char *container, int fd, char *devname, goto release; } else if (verbose >= 0) printf("chunk size for %s set to %d\n", - devname, array.chunk_size); + devname, info->new_chunk); } unfreeze(st); return 0; @@ -3400,6 +3363,7 @@ static int reshape_array(char *container, int fd, char *devname, default: /* parent */ return 0; case 0: + manage_fork_fds(0); map_fork(); break; } @@ -3508,14 +3472,16 @@ 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); return 0; } + close(fd); /* 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. @@ -3568,7 +3534,6 @@ started: mdstat_wait(30 - (delayed-1) * 25); } while (delayed); mdstat_close(); - close(fd); if (check_env("MDADM_GROW_VERIFY")) fd = open(devname, O_RDONLY | O_DIRECT); else @@ -3703,8 +3668,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()) { @@ -3717,6 +3682,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; }