From a740cf6432245d607ee216b5380a3215084f101d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 May 2014 15:55:31 +1000 Subject: [PATCH] MISC: add --action option to set or abort check/repair. Signed-off-by: NeilBrown --- ReadMe.c | 2 ++ mdadm.8.in | 25 +++++++++++++++++++++++++ mdadm.c | 43 +++++++++++++++++++++++++++++++++++++++++++ mdadm.h | 3 +++ 4 files changed, 73 insertions(+) diff --git a/ReadMe.c b/ReadMe.c index 45046ef..bd8c85e 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -166,6 +166,7 @@ struct option long_options[] = { {"no-degraded",0,0, NoDegraded }, {"wait", 0, 0, WaitOpt}, {"wait-clean", 0, 0, Waitclean }, + {"action", 1, 0, Action }, /* For Detail/Examine */ {"brief", 0, 0, Brief}, @@ -506,6 +507,7 @@ char Help_misc[] = " --readwrite -w : mark array as readwrite\n" " --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n" " --wait -W : wait for resync/rebuild/recovery to finish\n" +" --action= : initiate or abort ('idle' or 'frozen') a 'check' or 'repair'.\n" ; char Help_monitor[] = diff --git a/mdadm.8.in b/mdadm.8.in index ced1b50..718bcdb 100644 --- a/mdadm.8.in +++ b/mdadm.8.in @@ -1588,6 +1588,31 @@ successfully waited. For native arrays this returns immediately as the kernel handles dirty-clean transitions at shutdown. No action is taken if safe-mode handling is disabled. +.TP +.B \-\-action= +Set the "sync_action" for all md devices given to one of +.BR idle , +.BR frozen , +.BR check , +.BR repair . +Setting to +.B idle +will abort any currently running action though some actions will +automatically restart. +Setting to +.B frozen +will abort any current action and ensure no other action starts +automatically. + +Details of +.B check +and +.B repair +can be found it +.IR md (4) +under +.BR "SCRUBBING AND MISMATCHES" . + .SH For Incremental Assembly mode: .TP .BR \-\-rebuild\-map ", " \-r diff --git a/mdadm.c b/mdadm.c index f6f5b53..be990b8 100644 --- a/mdadm.c +++ b/mdadm.c @@ -230,6 +230,7 @@ int main(int argc, char *argv[]) case ExamineBB: case Dump: case Restore: + case Action: newmode = MISC; break; @@ -987,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" @@ -995,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 "); @@ -1802,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); @@ -1828,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; +} diff --git a/mdadm.h b/mdadm.h index efe4778..c0726bf 100644 --- a/mdadm.h +++ b/mdadm.h @@ -342,6 +342,7 @@ enum special_options { ExamineBB, Dump, Restore, + Action, }; enum prefix_standard { @@ -415,6 +416,7 @@ struct context { int freeze_reshape; char *backup_file; int invalid_backup; + char *action; }; struct shape { @@ -1237,6 +1239,7 @@ extern int Kill_subarray(char *dev, char *subarray, int verbose); extern int Update_subarray(char *dev, char *subarray, char *update, struct mddev_ident *ident, int quiet); extern int Wait(char *dev); extern int WaitClean(char *dev, int sock, int verbose); +extern int SetAction(char *dev, char *action); extern int Incremental(struct mddev_dev *devlist, struct context *c, struct supertype *st);