int chunk = 0;
int size = 0;
- int level = -10;
- int layout = -1;
+ int level = UnSet;
+ int layout = UnSet;
int raiddisks = 0;
int sparedisks = 0;
struct mddev_ident_s ident;
int verbose = 0;
int brief = 0;
int force = 0;
+ int test = 0;
char *mailaddr = NULL;
char *program = NULL;
int delay = 0;
+ int daemonise = 0;
+ int oneshot = 0;
int mdfd = -1;
ident.uuid_set=0;
- ident.level = -10;
- ident.raid_disks = -1;
- ident.super_minor= -1;
+ ident.level = UnSet;
+ ident.raid_disks = UnSet;
+ ident.super_minor= UnSet;
ident.devices=0;
while ((option_index = -1) ,
switch(opt) {
case 'h':
help_text = Help;
- switch (mode) {
- case ASSEMBLE : help_text = Help_assemble; break;
- case BUILD : help_text = Help_build; break;
- case CREATE : help_text = Help_create; break;
- case MANAGE : help_text = Help_manage; break;
- case MISC : help_text = Help_misc; break;
- case MONITOR : help_text = Help_monitor; break;
- }
+ if (option_index > 0 &&
+ strcmp(long_options[option_index].name, "help-options")==0)
+ help_text = OptionHelp;
+ else
+ switch (mode) {
+ case ASSEMBLE : help_text = Help_assemble; break;
+ case BUILD : help_text = Help_build; break;
+ case CREATE : help_text = Help_create; break;
+ case MANAGE : help_text = Help_manage; break;
+ case MISC : help_text = Help_misc; break;
+ case MONITOR : help_text = Help_monitor; break;
+ }
fputs(help_text,stderr);
exit(0);
case O(CREATE,'l'):
case O(BUILD,'l'): /* set raid level*/
- if (level != -10) {
+ if (level != UnSet) {
fprintf(stderr, Name ": raid level may only be set once. "
"Second value is %s.\n", optarg);
exit(2);
}
level = map_name(pers, optarg);
- if (level == -10) {
+ if (level == UnSet) {
fprintf(stderr, Name ": invalid raid level: %s\n",
optarg);
exit(2);
fprintf(stderr, Name ": layout not meaningful for %s arrays.\n",
map_num(pers, level));
exit(2);
- case -10:
+ case UnSet:
fprintf(stderr, Name ": raid level must be given before layout.\n");
exit(2);
case 5:
+ case 6:
layout = map_name(r5layout, optarg);
- if (layout==-10) {
+ if (layout==UnSet) {
fprintf(stderr, Name ": layout %s not understood for raid5.\n",
optarg);
exit(2);
optarg);
exit(2);
}
+ if (raiddisks == 1 && !force) {
+ fprintf(stderr, Name ": '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"
+ " setting the number of drives.\n");
+ exit(2);
+ }
ident.raid_disks = raiddisks;
continue;
sparedisks, optarg);
exit(2);
}
- if (level > -10 && level <= 0 && level >= -1) {
+ if (level != UnSet && level <= 0 && level >= -1) {
fprintf(stderr, Name ": spare-devices setting is incompatible with raid level %d\n",
level);
exit(2);
exit(2);
}
continue;
+ case O(BUILD,'f'): /* force honouring '-n 1' */
case O(CREATE,'f'): /* force honouring of device list */
case O(ASSEMBLE,'f'): /* force assembly */
case O(MISC,'f'): /* force zero */
continue;
case O(ASSEMBLE,'m'): /* super-minor for array */
- if (ident.super_minor >= 0) {
+ if (ident.super_minor != UnSet) {
fprintf(stderr, Name ": super-minor cannot be set twice. "
"Second value: %s.\n", optarg);
exit(2);
}
- ident.super_minor = strtoul(optarg, &cp, 10);
- if (!optarg[0] || *cp) {
- fprintf(stderr, Name ": Bad super-minor number: %s.\n", optarg);
- exit(2);
+ if (strcmp(optarg, "dev")==0)
+ ident.super_minor = -2;
+ else {
+ ident.super_minor = strtoul(optarg, &cp, 10);
+ if (!optarg[0] || *cp) {
+ fprintf(stderr, Name ": Bad super-minor number: %s.\n", optarg);
+ exit(2);
+ }
}
continue;
if (strcmp(update, "sparc2.2")==0) continue;
if (strcmp(update, "super-minor") == 0)
continue;
- fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2' or 'super-minor' supported\n",update);
+ if (strcmp(update, "summaries")==0)
+ continue;
+ fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2', 'super-minor' or 'summaries' supported\n",update);
exit(2);
case O(ASSEMBLE,'c'): /* config file */
}
}
continue;
-
+ case O(MONITOR,'f'): /* daemonise */
+ daemonise = 1;
+ continue;
+ case O(MONITOR,'1'): /* oneshot */
+ oneshot = 1;
+ continue;
+ case O(MONITOR,'t'): /* test */
+ test = 1;
+ continue;
/* now the general management options. Some are applicable
* to other modes. None have arguments.
}
devmode = opt;
continue;
+ case O(MISC,'t'):
+ test = 1;
+ continue;
case O(MISC, 22):
if (devmode != 'E') {
mdfd = open_mddev(devlist->devname);
if (mdfd < 0)
exit(1);
+ if ((int)ident.super_minor == -2) {
+ struct stat stb;
+ fstat(mdfd, &stb);
+ ident.super_minor = MINOR(stb.st_rdev);
+ }
}
rv = 0;
rv = Manage_runstop(devlist->devname, mdfd, runstop);
break;
case ASSEMBLE:
- if (!scan)
+ if (devs_found == 1 && ident.uuid_set == 0 &&
+ ident.super_minor == UnSet && !scan ) {
+ /* Only a device has been given, so get details from config file */
+ mddev_ident_t array_ident = conf_get_ident(configfile, devlist->devname);
+ mdfd = open_mddev(devlist->devname);
+ if (mdfd < 0)
+ rv |= 1;
+ else {
+ if (array_ident == NULL) {
+ fprintf(stderr, Name ": %s not identified in config file.\n",
+ devlist->devname);
+ rv |= 1;
+ }
+ else
+ rv |= Assemble(devlist->devname, mdfd, array_ident, configfile,
+ NULL,
+ readonly, runstop, update, verbose, force);
+ }
+ } else if (!scan)
rv = Assemble(devlist->devname, mdfd, &ident, configfile,
devlist->next,
readonly, runstop, update, verbose, force);
continue;
}
if (devmode == 'D')
- rv |= Detail(name, !verbose);
+ rv |= Detail(name, !verbose, test);
else if (devmode=='S') {
mdfd = open_mddev(name);
if (mdfd >= 0)
for (dv=devlist ; dv; dv=dv->next) {
switch(dv->disposition) {
case 'D':
- rv |= Detail(dv->devname, brief); continue;
+ rv |= Detail(dv->devname, brief, test); continue;
case 'K': /* Zero superblock */
rv |= Kill(dv->devname, force); continue;
case 'Q':
}
break;
case MONITOR:
-/*
if (!devlist && !scan) {
fprintf(stderr, Name ": Cannot monitor: need --scan or at least one device\n");
rv = 1;
break;
}
-*/ rv= Monitor(devlist, mailaddr, program,
- delay?delay:60, scan, configfile);
+ rv= Monitor(devlist, mailaddr, program,
+ delay?delay:60, daemonise, scan, oneshot, configfile, test);
break;
}
exit(rv);