diff options
Diffstat (limited to 'mdadm.c')
-rw-r--r-- | mdadm.c | 75 |
1 files changed, 64 insertions, 11 deletions
@@ -187,6 +187,7 @@ int main(int argc, char *argv[]) break; case 'a': case Add: + case AddSpare: case 'r': case Remove: case Replace: @@ -229,6 +230,7 @@ int main(int argc, char *argv[]) case ExamineBB: case Dump: case Restore: + case Action: newmode = MISC; break; @@ -915,6 +917,9 @@ int main(int argc, char *argv[]) case O(MANAGE,Add): /* add a drive */ devmode = 'a'; continue; + case O(MANAGE,AddSpare): /* add drive - never re-add */ + devmode = 'S'; + continue; case O(MANAGE,ReAdd): devmode = 'A'; continue; @@ -983,6 +988,7 @@ int main(int argc, char *argv[]) case O(MISC, UpdateSubarray): case O(MISC, Dump): case O(MISC, Restore): + case O(MISC ,Action): if (opt == KillSubarray || opt == UpdateSubarray) { if (c.subarray) { pr_err("subarray can only" @@ -991,6 +997,21 @@ int main(int argc, char *argv[]) } c.subarray = optarg; } + if (opt == Action) { + if (c.action) { + pr_err("Only one --action can be specified\n"); + exit(2); + } + if (strcmp(optarg, "idle") == 0 || + strcmp(optarg, "frozen") == 0 || + strcmp(optarg, "check") == 0 || + strcmp(optarg, "repair") == 0) + c.action = optarg; + else { + pr_err("action must be one of idle, frozen, check, repair\n"); + exit(2); + } + } if (devmode && devmode != opt && (devmode == 'E' || (opt == 'E' && devmode != 'Q'))) { pr_err("--examine/-E cannot be given with "); @@ -1293,7 +1314,7 @@ int main(int argc, char *argv[]) if (!rv && c.readonly < 0) rv = Manage_ro(devlist->devname, mdfd, c.readonly); if (!rv && c.runstop > 0) - rv = Manage_run(devlist->devname, mdfd, c.verbose); + rv = Manage_run(devlist->devname, mdfd, &c); if (!rv && c.runstop < 0) rv = Manage_stop(devlist->devname, mdfd, c.verbose, 0); break; @@ -1527,6 +1548,11 @@ int main(int argc, char *argv[]) RebuildMap(); } if (c.scan) { + rv = 1; + if (devlist) { + pr_err("In --incremental mode, a device cannot be given with --scan.\n"); + break; + } if (c.runstop <= 0) { pr_err("--incremental --scan meaningless without --run.\n"); break; @@ -1535,7 +1561,7 @@ int main(int argc, char *argv[]) pr_err("--incremental --scan --fail not supported.\n"); break; } - rv = IncrementalScan(c.verbose, NULL); + rv = IncrementalScan(&c, NULL); } if (!devlist) { if (!rebuild_map && !c.scan) { @@ -1544,16 +1570,16 @@ int main(int argc, char *argv[]) } break; } - if (devlist->next) { - pr_err("--incremental can only handle one device.\n"); - rv = 1; - break; - } - if (devmode == 'f') + if (devmode == 'f') { + if (devlist->next) { + pr_err("'--incremental --fail' can only handle one device.\n"); + rv = 1; + break; + } rv = IncrementalRemove(devlist->devname, remove_path, c.verbose); - else - rv = Incremental(devlist->devname, &c, ss); + } else + rv = Incremental(devlist, &c, ss); break; case AUTODETECT: autodetect(); @@ -1793,6 +1819,9 @@ static int misc_list(struct mddev_dev *devlist, rv |= Restore_metadata(dv->devname, dump_directory, c, ss, (dv == devlist && dv->next == NULL)); continue; + case Action: + rv |= SetAction(dv->devname, c->action); + continue; } if (dv->devname[0] == '/') mdfd = open_mddev(dv->devname, 1); @@ -1804,7 +1833,8 @@ static int misc_list(struct mddev_dev *devlist, if (mdfd>=0) { switch(dv->disposition) { case 'R': - rv |= Manage_run(dv->devname, mdfd, c->verbose); break; + c->runstop = 1; + rv |= Manage_run(dv->devname, mdfd, c); break; case 'S': rv |= Manage_stop(dv->devname, mdfd, c->verbose, 0); break; case 'o': @@ -1818,3 +1848,26 @@ static int misc_list(struct mddev_dev *devlist, } return rv; } + +int SetAction(char *dev, char *action) +{ + int fd = open(dev, O_RDONLY); + struct mdinfo mdi; + if (fd < 0) { + pr_err("Couldn't open %s: %s\n", dev, strerror(errno)); + return 1; + } + sysfs_init(&mdi, fd, NULL); + close(fd); + if (!mdi.sys_name[0]) { + pr_err("%s is no an md array\n", dev); + return 1; + } + + if (sysfs_set_str(&mdi, NULL, "sync_action", action) < 0) { + pr_err("Count not set action for %s to %s: %s\n", + dev, action, strerror(errno)); + return 1; + } + return 0; +} |