X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=blobdiff_plain;f=mdadm.c;h=fd64e0e31610f18c1a94822dc6dd2911f872b26d;hp=d3cf0fad87bf94f1910854e397c47bcfba0799ae;hb=1ade5cc15a61c6fe3084c5170934e05e9a574843;hpb=9eaf410feda4ad112d3cee0c0b5b4edf05fc63bf diff --git a/mdadm.c b/mdadm.c index d3cf0fad..fd64e0e3 100644 --- a/mdadm.c +++ b/mdadm.c @@ -38,6 +38,7 @@ static int misc_list(struct mddev_dev *devlist, struct mddev_ident *ident, char *dump_directory, struct supertype *ss, struct context *c); +const char Name[] = "mdadm"; int main(int argc, char *argv[]) { @@ -187,6 +188,7 @@ int main(int argc, char *argv[]) break; case 'a': case Add: + case AddSpare: case 'r': case Remove: case Replace: @@ -229,6 +231,7 @@ int main(int argc, char *argv[]) case ExamineBB: case Dump: case Restore: + case Action: newmode = MISC; break; @@ -769,17 +772,19 @@ int main(int argc, char *argv[]) if (strcmp(c.update,"?") == 0 || strcmp(c.update, "help") == 0) { outf = stdout; - fprintf(outf, Name ": "); + fprintf(outf, "%s: ", Name); } else { outf = stderr; fprintf(outf, - Name ": '--update=%s' is invalid. ", - c.update); + "%s: '--update=%s' is invalid. ", + Name, c.update); } fprintf(outf, "Valid --update options are:\n" " 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n" " 'summaries', 'homehost', 'byteorder', 'devicesize',\n" - " 'no-bitmap', 'metadata', 'revert-reshape'\n"); + " 'no-bitmap', 'metadata', 'revert-reshape'\n" + " 'bbl', 'no-bbl'\n" + ); exit(outf == stdout ? 0 : 2); case O(MANAGE,'U'): @@ -915,6 +920,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 +991,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 +1000,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 "); @@ -1549,16 +1573,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(); @@ -1593,9 +1617,7 @@ static int scan_assemble(struct supertype *ss, a->autof = c->autof; } if (map_lock(&map)) - pr_err("%s: failed to get " - "exclusive lock on mapfile\n", - __func__); + pr_err("failed to get exclusive lock on mapfile\n"); do { failures = 0; successes = 0; @@ -1798,6 +1820,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); @@ -1824,3 +1849,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; +}