Create 'struct context' for ad hoc context option.

Rather than passing a long list of little flags etc to various
functions we will soon pass a small collection of structures.

This first step combines a collection of variables local to
'main' into a single structure.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2012-07-09 17:17:33 +10:00
parent 7986889004
commit 9e33d55609
2 changed files with 175 additions and 168 deletions

320
mdadm.c
View File

@ -64,30 +64,16 @@ int main(int argc, char *argv[])
int sparedisks = 0; int sparedisks = 0;
struct mddev_ident ident; struct mddev_ident ident;
char *configfile = NULL; char *configfile = NULL;
char *update = NULL;
int scan = 0;
int devmode = 0; int devmode = 0;
int runstop = 0;
int readonly = 0;
int write_behind = 0; int write_behind = 0;
int bitmap_fd = -1; int bitmap_fd = -1;
char *bitmap_file = NULL; char *bitmap_file = NULL;
char *backup_file = NULL;
int invalid_backup = 0;
int bitmap_chunk = UnSet; int bitmap_chunk = UnSet;
int SparcAdjust = 0;
struct mddev_dev *devlist = NULL; struct mddev_dev *devlist = NULL;
struct mddev_dev **devlistend = & devlist; struct mddev_dev **devlistend = & devlist;
struct mddev_dev *dv; struct mddev_dev *dv;
int devs_found = 0; int devs_found = 0;
int verbose = 0;
int quiet = 0;
int brief = 0;
int force = 0;
int test = 0;
int export = 0;
int assume_clean = 0; int assume_clean = 0;
char *prefer = NULL;
char *symlinks = NULL; char *symlinks = NULL;
int grow_continue = 0; int grow_continue = 0;
/* autof indicates whether and how to create device node. /* autof indicates whether and how to create device node.
@ -100,15 +86,14 @@ int main(int argc, char *argv[])
* 5 - default to md if not is_standard (md in config file) * 5 - default to md if not is_standard (md in config file)
* 6 - default to mdp if not is_standard (part, or mdp in config file) * 6 - default to mdp if not is_standard (part, or mdp in config file)
*/ */
int autof = 0; struct context c = {
.require_homehost = 1,
};
char *homehost = NULL;
char sys_hostname[256]; char sys_hostname[256];
int require_homehost = 1;
char *mailaddr = NULL; char *mailaddr = NULL;
char *program = NULL; char *program = NULL;
int increments = 20; int increments = 20;
int delay = 0;
int daemonise = 0; int daemonise = 0;
char *pidfile = NULL; char *pidfile = NULL;
int oneshot = 0; int oneshot = 0;
@ -118,7 +103,6 @@ int main(int argc, char *argv[])
char *shortopt = short_options; char *shortopt = short_options;
int dosyslog = 0; int dosyslog = 0;
int rebuild_map = 0; int rebuild_map = 0;
char *subarray = NULL;
char *remove_path = NULL; char *remove_path = NULL;
char *udev_filename = NULL; char *udev_filename = NULL;
@ -127,8 +111,6 @@ int main(int argc, char *argv[])
int mdfd = -1; int mdfd = -1;
int freeze_reshape = 0;
srandom(time(0) ^ getpid()); srandom(time(0) ^ getpid());
ident.uuid_set=0; ident.uuid_set=0;
@ -163,10 +145,10 @@ int main(int argc, char *argv[])
fputs(Version, stderr); fputs(Version, stderr);
exit(0); exit(0);
case 'v': verbose++; case 'v': c.verbose++;
continue; continue;
case 'q': quiet++; case 'q': c.quiet++;
continue; continue;
case 'b': case 'b':
@ -175,17 +157,17 @@ int main(int argc, char *argv[])
|| mode == MANAGE) || mode == MANAGE)
break; /* b means bitmap */ break; /* b means bitmap */
case Brief: case Brief:
brief = 1; c.brief = 1;
continue; continue;
case 'Y': export++; case 'Y': c.export++;
continue; continue;
case HomeHost: case HomeHost:
if (strcasecmp(optarg, "<ignore>") == 0) if (strcasecmp(optarg, "<ignore>") == 0)
require_homehost = 0; c.require_homehost = 0;
else else
homehost = optarg; c.homehost = optarg;
continue; continue;
/* /*
@ -199,10 +181,10 @@ int main(int argc, char *argv[])
continue; continue;
case Prefer: case Prefer:
if (prefer) if (c.prefer)
free(prefer); free(c.prefer);
if (asprintf(&prefer, "/%s/", optarg) <= 0) if (asprintf(&c.prefer, "/%s/", optarg) <= 0)
prefer = NULL; c.prefer = NULL;
continue; continue;
case ':': case ':':
@ -624,7 +606,7 @@ int main(int argc, char *argv[])
case O(INCREMENTAL,Auto): case O(INCREMENTAL,Auto):
case O(ASSEMBLE,'a'): case O(ASSEMBLE,'a'):
case O(ASSEMBLE,Auto): /* auto-creation of device node */ case O(ASSEMBLE,Auto): /* auto-creation of device node */
autof = parse_auto(optarg, "--auto flag", 0); c.autof = parse_auto(optarg, "--auto flag", 0);
continue; continue;
case O(CREATE,Symlinks): case O(CREATE,Symlinks):
@ -644,13 +626,13 @@ int main(int argc, char *argv[])
case O(MISC,'f'): /* force zero */ case O(MISC,'f'): /* force zero */
case O(MISC,Force): /* force zero */ case O(MISC,Force): /* force zero */
case O(MANAGE,Force): /* add device which is too large */ case O(MANAGE,Force): /* add device which is too large */
force=1; c.force=1;
continue; continue;
/* now for the Assemble options */ /* now for the Assemble options */
case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during case O(ASSEMBLE, FreezeReshape): /* Freeze reshape during
* initrd phase */ * initrd phase */
case O(INCREMENTAL, FreezeReshape): case O(INCREMENTAL, FreezeReshape):
freeze_reshape = 1; c.freeze_reshape = 1;
continue; continue;
case O(CREATE,'u'): /* uuid of array */ case O(CREATE,'u'): /* uuid of array */
case O(ASSEMBLE,'u'): /* uuid of array */ case O(ASSEMBLE,'u'): /* uuid of array */
@ -675,7 +657,7 @@ int main(int argc, char *argv[])
"Second value %s.\n", optarg); "Second value %s.\n", optarg);
exit(2); exit(2);
} }
if (mode == MISC && !subarray) { if (mode == MISC && !c.subarray) {
pr_err("-N/--name only valid with --update-subarray in misc mode\n"); pr_err("-N/--name only valid with --update-subarray in misc mode\n");
exit(2); exit(2);
} }
@ -708,42 +690,42 @@ int main(int argc, char *argv[])
case O(ASSEMBLE,'o'): case O(ASSEMBLE,'o'):
case O(MANAGE,'o'): case O(MANAGE,'o'):
case O(CREATE,'o'): case O(CREATE,'o'):
readonly = 1; c.readonly = 1;
continue; continue;
case O(ASSEMBLE,'U'): /* update the superblock */ case O(ASSEMBLE,'U'): /* update the superblock */
case O(MISC,'U'): case O(MISC,'U'):
if (update) { if (c.update) {
pr_err("Can only update one aspect" pr_err("Can only update one aspect"
" of superblock, both %s and %s given.\n", " of superblock, both %s and %s given.\n",
update, optarg); c.update, optarg);
exit(2); exit(2);
} }
if (mode == MISC && !subarray) { if (mode == MISC && !c.subarray) {
pr_err("Only subarrays can be" pr_err("Only subarrays can be"
" updated in misc mode\n"); " updated in misc mode\n");
exit(2); exit(2);
} }
update = optarg; c.update = optarg;
if (strcmp(update, "sparc2.2")==0) if (strcmp(c.update, "sparc2.2")==0)
continue; continue;
if (strcmp(update, "super-minor") == 0) if (strcmp(c.update, "super-minor") == 0)
continue; continue;
if (strcmp(update, "summaries")==0) if (strcmp(c.update, "summaries")==0)
continue; continue;
if (strcmp(update, "resync")==0) if (strcmp(c.update, "resync")==0)
continue; continue;
if (strcmp(update, "uuid")==0) if (strcmp(c.update, "uuid")==0)
continue; continue;
if (strcmp(update, "name")==0) if (strcmp(c.update, "name")==0)
continue; continue;
if (strcmp(update, "homehost")==0) if (strcmp(c.update, "homehost")==0)
continue; continue;
if (strcmp(update, "devicesize")==0) if (strcmp(c.update, "devicesize")==0)
continue; continue;
if (strcmp(update, "no-bitmap")==0) if (strcmp(c.update, "no-bitmap")==0)
continue; continue;
if (strcmp(update, "byteorder")==0) { if (strcmp(c.update, "byteorder")==0) {
if (ss) { if (ss) {
pr_err("must not set metadata" pr_err("must not set metadata"
" type with --update=byteorder.\n"); " type with --update=byteorder.\n");
@ -760,15 +742,15 @@ int main(int argc, char *argv[])
continue; continue;
} }
if (strcmp(update,"?") == 0 || if (strcmp(c.update,"?") == 0 ||
strcmp(update, "help") == 0) { strcmp(c.update, "help") == 0) {
outf = stdout; outf = stdout;
fprintf(outf, Name ": "); fprintf(outf, Name ": ");
} else { } else {
outf = stderr; outf = stderr;
fprintf(outf, fprintf(outf,
Name ": '--update=%s' is invalid. ", Name ": '--update=%s' is invalid. ",
update); c.update);
} }
fprintf(outf, "Valid --update options are:\n" fprintf(outf, "Valid --update options are:\n"
" 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n" " 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
@ -783,14 +765,14 @@ int main(int argc, char *argv[])
" allowed with --re-add.\n"); " allowed with --re-add.\n");
exit(1); exit(1);
} }
if (update) { if (c.update) {
pr_err("Can only update one aspect" pr_err("Can only update one aspect"
" of superblock, both %s and %s given.\n", " of superblock, both %s and %s given.\n",
update, optarg); c.update, optarg);
exit(2); exit(2);
} }
update = optarg; c.update = optarg;
if (strcmp(update, "devicesize") != 0) { if (strcmp(c.update, "devicesize") != 0) {
pr_err("only 'devicesize' can be" pr_err("only 'devicesize' can be"
" updated with --re-add\n"); " updated with --re-add\n");
exit(2); exit(2);
@ -800,8 +782,8 @@ int main(int argc, char *argv[])
case O(INCREMENTAL,NoDegraded): case O(INCREMENTAL,NoDegraded):
pr_err("--no-degraded is deprecated in Incremental mode\n"); pr_err("--no-degraded is deprecated in Incremental mode\n");
case O(ASSEMBLE,NoDegraded): /* --no-degraded */ case O(ASSEMBLE,NoDegraded): /* --no-degraded */
runstop = -1; /* --stop isn't allowed for --assemble, c.runstop = -1; /* --stop isn't allowed for --assemble,
* so we overload slightly */ * so we overload slightly */
continue; continue;
case O(ASSEMBLE,'c'): case O(ASSEMBLE,'c'):
@ -825,7 +807,7 @@ int main(int argc, char *argv[])
case O(MISC,'s'): case O(MISC,'s'):
case O(MONITOR,'s'): case O(MONITOR,'s'):
case O(INCREMENTAL,'s'): case O(INCREMENTAL,'s'):
scan = 1; c.scan = 1;
continue; continue;
case O(MONITOR,'m'): /* mail address */ case O(MONITOR,'m'): /* mail address */
@ -859,12 +841,12 @@ int main(int argc, char *argv[])
case O(GROW, 'd'): case O(GROW, 'd'):
case O(BUILD,'d'): /* delay for bitmap updates */ case O(BUILD,'d'): /* delay for bitmap updates */
case O(CREATE,'d'): case O(CREATE,'d'):
if (delay) if (c.delay)
pr_err("only specify delay once. %s ignored.\n", pr_err("only specify delay once. %s ignored.\n",
optarg); optarg);
else { else {
delay = parse_num(optarg); c.delay = parse_num(optarg);
if (delay<1) { if (c.delay < 1) {
pr_err("invalid delay: %s\n", pr_err("invalid delay: %s\n",
optarg); optarg);
exit(2); exit(2);
@ -887,7 +869,7 @@ int main(int argc, char *argv[])
spare_sharing = 0; spare_sharing = 0;
continue; continue;
case O(MONITOR,'t'): /* test */ case O(MONITOR,'t'): /* test */
test = 1; c.test = 1;
continue; continue;
case O(MONITOR,'y'): /* log messages to syslog */ case O(MONITOR,'y'): /* log messages to syslog */
openlog("mdadm", LOG_PID, SYSLOG_FACILITY); openlog("mdadm", LOG_PID, SYSLOG_FACILITY);
@ -927,21 +909,21 @@ int main(int argc, char *argv[])
case O(ASSEMBLE,'R'): case O(ASSEMBLE,'R'):
case O(BUILD,'R'): case O(BUILD,'R'):
case O(CREATE,'R'): /* Run the array */ case O(CREATE,'R'): /* Run the array */
if (runstop < 0) { if (c.runstop < 0) {
pr_err("Cannot both Stop and Run an array\n"); pr_err("Cannot both Stop and Run an array\n");
exit(2); exit(2);
} }
runstop = 1; c.runstop = 1;
continue; continue;
case O(MANAGE,'S'): case O(MANAGE,'S'):
if (runstop > 0) { if (c.runstop > 0) {
pr_err("Cannot both Run and Stop an array\n"); pr_err("Cannot both Run and Stop an array\n");
exit(2); exit(2);
} }
runstop = -1; c.runstop = -1;
continue; continue;
case O(MANAGE,'t'): case O(MANAGE,'t'):
test = 1; c.test = 1;
continue; continue;
case O(MISC,'Q'): case O(MISC,'Q'):
@ -960,12 +942,12 @@ int main(int argc, char *argv[])
case O(MISC, KillSubarray): case O(MISC, KillSubarray):
case O(MISC, UpdateSubarray): case O(MISC, UpdateSubarray):
if (opt == KillSubarray || opt == UpdateSubarray) { if (opt == KillSubarray || opt == UpdateSubarray) {
if (subarray) { if (c.subarray) {
pr_err("subarray can only" pr_err("subarray can only"
" be specified once\n"); " be specified once\n");
exit(2); exit(2);
} }
subarray = optarg; c.subarray = optarg;
} }
if (devmode && devmode != opt && if (devmode && devmode != opt &&
(devmode == 'E' || (opt == 'E' && devmode != 'Q'))) { (devmode == 'E' || (opt == 'E' && devmode != 'Q'))) {
@ -999,7 +981,7 @@ int main(int argc, char *argv[])
devmode = opt; devmode = opt;
continue; continue;
case O(MISC,'t'): case O(MISC,'t'):
test = 1; c.test = 1;
continue; continue;
case O(MISC, Sparc22): case O(MISC, Sparc22):
@ -1007,7 +989,7 @@ int main(int argc, char *argv[])
pr_err("--sparc2.2 only allowed with --examine\n"); pr_err("--sparc2.2 only allowed with --examine\n");
exit(2); exit(2);
} }
SparcAdjust = 1; c.SparcAdjust = 1;
continue; continue;
case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */ case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
@ -1033,11 +1015,11 @@ int main(int argc, char *argv[])
/* Specify a file into which grow might place a backup, /* Specify a file into which grow might place a backup,
* or from which assemble might recover a backup * or from which assemble might recover a backup
*/ */
if (backup_file) { if (c.backup_file) {
pr_err("backup file already specified, rejecting %s\n", optarg); pr_err("backup file already specified, rejecting %s\n", optarg);
exit(2); exit(2);
} }
backup_file = optarg; c.backup_file = optarg;
continue; continue;
case O(GROW, Continue): case O(GROW, Continue):
@ -1049,7 +1031,7 @@ int main(int argc, char *argv[])
/* Acknowledge that the backupfile is invalid, but ask /* Acknowledge that the backupfile is invalid, but ask
* to continue anyway * to continue anyway
*/ */
invalid_backup = 1; c.invalid_backup = 1;
continue; continue;
case O(BUILD,'b'): case O(BUILD,'b'):
@ -1171,12 +1153,12 @@ int main(int argc, char *argv[])
if (mode == MANAGE || mode == BUILD || mode == CREATE if (mode == MANAGE || mode == BUILD || mode == CREATE
|| mode == GROW || mode == GROW
|| (mode == ASSEMBLE && ! scan)) { || (mode == ASSEMBLE && ! c.scan)) {
if (devs_found < 1) { if (devs_found < 1) {
pr_err("an md device must be given in this mode\n"); pr_err("an md device must be given in this mode\n");
exit(2); exit(2);
} }
if ((int)ident.super_minor == -2 && autof) { if ((int)ident.super_minor == -2 && c.autof) {
pr_err("--super-minor=dev is incompatible with --auto\n"); pr_err("--super-minor=dev is incompatible with --auto\n");
exit(2); exit(2);
} }
@ -1213,7 +1195,7 @@ int main(int argc, char *argv[])
} }
if (raiddisks) { if (raiddisks) {
if (raiddisks == 1 && !force && level != LEVEL_FAULTY) { if (raiddisks == 1 && !c.force && level != LEVEL_FAULTY) {
pr_err("'1' is an unusual number of drives for an array, so it is probably\n" pr_err("'1' is an unusual number of drives for an array, so it is probably\n"
" a mistake. If you really mean it you will need to specify --force before\n" " a mistake. If you really mean it you will need to specify --force before\n"
" setting the number of drives.\n"); " setting the number of drives.\n");
@ -1221,17 +1203,17 @@ int main(int argc, char *argv[])
} }
} }
if (homehost == NULL) if (c.homehost == NULL)
homehost = conf_get_homehost(&require_homehost); c.homehost = conf_get_homehost(&c.require_homehost);
if (homehost == NULL || strcasecmp(homehost, "<system>")==0) { if (c.homehost == NULL || strcasecmp(c.homehost, "<system>")==0) {
if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) { if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
sys_hostname[sizeof(sys_hostname)-1] = 0; sys_hostname[sizeof(sys_hostname)-1] = 0;
homehost = sys_hostname; c.homehost = sys_hostname;
} }
} }
if (homehost && (!homehost[0] || strcasecmp(homehost, "<none>") == 0)) { if (c.homehost && (!c.homehost[0] || strcasecmp(c.homehost, "<none>") == 0)) {
homehost = NULL; c.homehost = NULL;
require_homehost = 0; c.require_homehost = 0;
} }
if ((mode == MISC && devmode == 'E') if ((mode == MISC && devmode == 'E')
@ -1242,26 +1224,26 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
ident.autof = autof; ident.autof = c.autof;
rv = 0; rv = 0;
switch(mode) { switch(mode) {
case MANAGE: case MANAGE:
/* readonly, add/remove, readwrite, runstop */ /* readonly, add/remove, readwrite, runstop */
if (readonly>0) if (c.readonly > 0)
rv = Manage_ro(devlist->devname, mdfd, readonly); rv = Manage_ro(devlist->devname, mdfd, c.readonly);
if (!rv && devs_found>1) if (!rv && devs_found>1)
rv = Manage_subdevs(devlist->devname, mdfd, rv = Manage_subdevs(devlist->devname, mdfd,
devlist->next, verbose-quiet, test, devlist->next, c.verbose-c.quiet, c.test,
update, force); c.update, c.force);
if (!rv && readonly < 0) if (!rv && c.readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, readonly); rv = Manage_ro(devlist->devname, mdfd, c.readonly);
if (!rv && runstop) if (!rv && c.runstop)
rv = Manage_runstop(devlist->devname, mdfd, runstop, quiet); rv = Manage_runstop(devlist->devname, mdfd, c.runstop, c.quiet);
break; break;
case ASSEMBLE: case ASSEMBLE:
if (devs_found == 1 && ident.uuid_set == 0 && if (devs_found == 1 && ident.uuid_set == 0 &&
ident.super_minor == UnSet && ident.name[0] == 0 && !scan ) { ident.super_minor == UnSet && ident.name[0] == 0 && !c.scan ) {
/* Only a device has been given, so get details from config file */ /* Only a device has been given, so get details from config file */
struct mddev_ident *array_ident = conf_get_ident(devlist->devname); struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
if (array_ident == NULL) { if (array_ident == NULL) {
@ -1272,27 +1254,27 @@ int main(int argc, char *argv[])
close(mdfd); close(mdfd);
} else { } else {
if (array_ident->autof == 0) if (array_ident->autof == 0)
array_ident->autof = autof; array_ident->autof = c.autof;
rv |= Assemble(ss, devlist->devname, array_ident, rv |= Assemble(ss, devlist->devname, array_ident,
NULL, backup_file, invalid_backup, NULL, c.backup_file, c.invalid_backup,
readonly, runstop, update, c.readonly, c.runstop, c.update,
homehost, require_homehost, c.homehost, c.require_homehost,
verbose-quiet, force, c.verbose-c.quiet, c.force,
freeze_reshape); c.freeze_reshape);
} }
} else if (!scan) } else if (!c.scan)
rv = Assemble(ss, devlist->devname, &ident, rv = Assemble(ss, devlist->devname, &ident,
devlist->next, backup_file, invalid_backup, devlist->next, c.backup_file, c.invalid_backup,
readonly, runstop, update, c.readonly, c.runstop, c.update,
homehost, require_homehost, c.homehost, c.require_homehost,
verbose-quiet, force, c.verbose-c.quiet, c.force,
freeze_reshape); c.freeze_reshape);
else if (devs_found > 0) { else if (devs_found > 0) {
if (update && devs_found > 1) { if (c.update && devs_found > 1) {
pr_err("can only update a single array at a time\n"); pr_err("can only update a single array at a time\n");
exit(1); exit(1);
} }
if (backup_file && devs_found > 1) { if (c.backup_file && devs_found > 1) {
pr_err("can only assemble a single array when providing a backup file.\n"); pr_err("can only assemble a single array when providing a backup file.\n");
exit(1); exit(1);
} }
@ -1305,33 +1287,34 @@ int main(int argc, char *argv[])
continue; continue;
} }
if (array_ident->autof == 0) if (array_ident->autof == 0)
array_ident->autof = autof; array_ident->autof = c.autof;
rv |= Assemble(ss, dv->devname, array_ident, rv |= Assemble(ss, dv->devname, array_ident,
NULL, backup_file, invalid_backup, NULL, c.backup_file, c.invalid_backup,
readonly, runstop, update, c.readonly, c.runstop, c.update,
homehost, require_homehost, c.homehost, c.require_homehost,
verbose-quiet, force, c.verbose-c.quiet, c.force,
freeze_reshape); c.freeze_reshape);
} }
} else { } else {
if (update) { if (c.update) {
pr_err("--update not meaningful with a --scan assembly.\n"); pr_err("--update not meaningful with a --scan assembly.\n");
exit(1); exit(1);
} }
if (backup_file) { if (c.backup_file) {
pr_err("--backup_file not meaningful with a --scan assembly.\n"); pr_err("--backup_file not meaningful with a --scan assembly.\n");
exit(1); exit(1);
} }
rv = scan_assemble(autof, ss, readonly, runstop, rv = scan_assemble(c.autof, ss, c.readonly, c.runstop,
&ident, homehost, &ident, c.homehost,
require_homehost, c.require_homehost,
verbose - quiet, c.verbose - c.quiet,
force, freeze_reshape); c.force, c.freeze_reshape);
} }
break; break;
case BUILD: case BUILD:
if (delay == 0) delay = DEFAULT_BITMAP_DELAY; if (c.delay == 0)
c.delay = DEFAULT_BITMAP_DELAY;
if (write_behind && !bitmap_file) { if (write_behind && !bitmap_file) {
pr_err("write-behind mode requires a bitmap.\n"); pr_err("write-behind mode requires a bitmap.\n");
rv = 1; rv = 1;
@ -1353,10 +1336,11 @@ int main(int argc, char *argv[])
rv = Build(devlist->devname, chunk, level, layout, rv = Build(devlist->devname, chunk, level, layout,
raiddisks, devlist->next, assume_clean, raiddisks, devlist->next, assume_clean,
bitmap_file, bitmap_chunk, write_behind, bitmap_file, bitmap_chunk, write_behind,
delay, verbose-quiet, autof, size); c.delay, c.verbose-c.quiet, c.autof, size);
break; break;
case CREATE: case CREATE:
if (delay == 0) delay = DEFAULT_BITMAP_DELAY; if (c.delay == 0)
c.delay = DEFAULT_BITMAP_DELAY;
if (write_behind && !bitmap_file) { if (write_behind && !bitmap_file) {
pr_err("write-behind mode requires a bitmap.\n"); pr_err("write-behind mode requires a bitmap.\n");
rv = 1; rv = 1;
@ -1369,15 +1353,15 @@ int main(int argc, char *argv[])
} }
rv = Create(ss, devlist->devname, chunk, level, layout, size<0 ? 0 : size, rv = Create(ss, devlist->devname, chunk, level, layout, size<0 ? 0 : size,
raiddisks, sparedisks, ident.name, homehost, raiddisks, sparedisks, ident.name, c.homehost,
ident.uuid_set ? ident.uuid : NULL, ident.uuid_set ? ident.uuid : NULL,
devs_found-1, devlist->next, runstop, devs_found-1, devlist->next, c.runstop,
readonly, verbose-quiet, force, assume_clean, c.readonly, c.verbose-c.quiet, c.force, assume_clean,
bitmap_file, bitmap_chunk, write_behind, delay, autof); bitmap_file, bitmap_chunk, write_behind, c.delay, c.autof);
break; break;
case MISC: case MISC:
if (devmode == 'E') { if (devmode == 'E') {
if (devlist == NULL && !scan) { if (devlist == NULL && !c.scan) {
pr_err("No devices to examine\n"); pr_err("No devices to examine\n");
exit(2); exit(2);
} }
@ -1387,19 +1371,19 @@ int main(int argc, char *argv[])
pr_err("No devices listed in %s\n", configfile?configfile:DefaultConfFile); pr_err("No devices listed in %s\n", configfile?configfile:DefaultConfFile);
exit(1); exit(1);
} }
if (brief && verbose) if (c.brief && c.verbose)
brief = 2; c.brief = 2;
rv = Examine(devlist, scan?(verbose>1?0:verbose+1):brief, rv = Examine(devlist, c.scan?(c.verbose>1?0:c.verbose+1):c.brief,
export, scan, c.export, c.scan,
SparcAdjust, ss, homehost); c.SparcAdjust, ss, c.homehost);
} else if (devmode == DetailPlatform) { } else if (devmode == DetailPlatform) {
rv = Detail_Platform(ss ? ss->ss : NULL, ss ? scan : 1, verbose); rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose);
} else if (devlist == NULL) { } else if (devlist == NULL) {
if (devmode == 'S' && scan) if (devmode == 'S' && c.scan)
rv = stop_scan(quiet); rv = stop_scan(c.quiet);
else if ((devmode == 'D' || devmode == Waitclean) && scan) else if ((devmode == 'D' || devmode == Waitclean) && c.scan)
rv = misc_scan(devmode, verbose, export, rv = misc_scan(devmode, c.verbose, c.export,
test, homehost, prefer); c.test, c.homehost, c.prefer);
else if (devmode == UdevRules) else if (devmode == UdevRules)
rv = Write_rules(udev_filename); rv = Write_rules(udev_filename);
else { else {
@ -1407,13 +1391,13 @@ int main(int argc, char *argv[])
exit(2); exit(2);
} }
} else } else
rv = misc_list(devlist, brief, verbose, export, test, rv = misc_list(devlist, c.brief, c.verbose, c.export, c.test,
homehost, prefer, subarray, update, c.homehost, c.prefer, c.subarray, c.update,
&ident, &ident,
ss, force, quiet); ss, c.force, c.quiet);
break; break;
case MONITOR: case MONITOR:
if (!devlist && !scan) { if (!devlist && !c.scan) {
pr_err("Cannot monitor: need --scan or at least one device\n"); pr_err("Cannot monitor: need --scan or at least one device\n");
rv = 1; rv = 1;
break; break;
@ -1423,17 +1407,17 @@ int main(int argc, char *argv[])
rv = 1; rv = 1;
break; break;
} }
if (delay == 0) { if (c.delay == 0) {
if (get_linux_version() > 2006016) if (get_linux_version() > 2006016)
/* mdstat responds to poll */ /* mdstat responds to poll */
delay = 1000; c.delay = 1000;
else else
delay = 60; c.delay = 60;
} }
rv= Monitor(devlist, mailaddr, program, rv= Monitor(devlist, mailaddr, program,
delay?delay:60, daemonise, scan, oneshot, c.delay?c.delay:60, daemonise, c.scan, oneshot,
dosyslog, test, pidfile, increments, dosyslog, c.test, pidfile, increments,
spare_sharing, prefer); spare_sharing, c.prefer);
break; break;
case GROW: case GROW:
@ -1491,20 +1475,20 @@ int main(int argc, char *argv[])
rv = 1; rv = 1;
break; break;
} }
if (delay == 0) if (c.delay == 0)
delay = DEFAULT_BITMAP_DELAY; c.delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file, rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
bitmap_chunk, delay, write_behind, force); bitmap_chunk, c.delay, write_behind, c.force);
} else if (grow_continue) } else if (grow_continue)
rv = Grow_continue_command(devlist->devname, rv = Grow_continue_command(devlist->devname,
mdfd, backup_file, mdfd, c.backup_file,
verbose); c.verbose);
else if (size >= 0 || raiddisks != 0 || layout_str != NULL else if (size >= 0 || raiddisks != 0 || layout_str != NULL
|| chunk != 0 || level != UnSet) { || chunk != 0 || level != UnSet) {
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file, rv = Grow_reshape(devlist->devname, mdfd, c.quiet, c.backup_file,
size, level, layout_str, chunk, raiddisks, size, level, layout_str, chunk, raiddisks,
devlist->next, devlist->next,
assume_clean, force); assume_clean, c.force);
} else if (array_size < 0) } else if (array_size < 0)
pr_err("no changes to --grow\n"); pr_err("no changes to --grow\n");
break; break;
@ -1512,8 +1496,8 @@ int main(int argc, char *argv[])
if (rebuild_map) { if (rebuild_map) {
RebuildMap(); RebuildMap();
} }
if (scan) { if (c.scan) {
if (runstop <= 0) { if (c.runstop <= 0) {
pr_err("--incremental --scan meaningless without --run.\n"); pr_err("--incremental --scan meaningless without --run.\n");
break; break;
} }
@ -1521,10 +1505,10 @@ int main(int argc, char *argv[])
pr_err("--incremental --scan --fail not supported.\n"); pr_err("--incremental --scan --fail not supported.\n");
break; break;
} }
rv = IncrementalScan(verbose); rv = IncrementalScan(c.verbose);
} }
if (!devlist) { if (!devlist) {
if (!rebuild_map && !scan) { if (!rebuild_map && !c.scan) {
pr_err("--incremental requires a device.\n"); pr_err("--incremental requires a device.\n");
rv = 1; rv = 1;
} }
@ -1537,12 +1521,12 @@ int main(int argc, char *argv[])
} }
if (devmode == 'f') if (devmode == 'f')
rv = IncrementalRemove(devlist->devname, remove_path, rv = IncrementalRemove(devlist->devname, remove_path,
verbose-quiet); c.verbose-c.quiet);
else else
rv = Incremental(devlist->devname, verbose-quiet, rv = Incremental(devlist->devname, c.verbose-c.quiet,
runstop, ss, homehost, c.runstop, ss, c.homehost,
require_homehost, autof, c.require_homehost, c.autof,
freeze_reshape); c.freeze_reshape);
break; break;
case AUTODETECT: case AUTODETECT:
autodetect(); autodetect();

23
mdadm.h
View File

@ -374,6 +374,29 @@ struct mddev_ident {
}; };
}; };
struct context {
int readonly;
int runstop;
int verbose;
int quiet;
int brief;
int force;
char *homehost;
int require_homehost;
char *prefer;
int export;
int test;
char *subarray;
char *update;
int scan;
int SparcAdjust;
int autof;
int delay;
int freeze_reshape;
char *backup_file;
int invalid_backup;
};
/* List of device names - wildcards expanded */ /* List of device names - wildcards expanded */
struct mddev_dev { struct mddev_dev {
char *devname; char *devname;