MISC: add --action option to set or abort check/repair.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2014-05-22 15:55:31 +10:00
parent 1e781e07ab
commit a740cf6432
4 changed files with 73 additions and 0 deletions

View File

@ -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[] =

View File

@ -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

43
mdadm.c
View File

@ -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;
}

View File

@ -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);