int chunk = 0;
long long size = -1;
+ long long array_size = -1;
int level = UnSet;
int layout = UnSet;
int raiddisks = 0;
char *homehost = NULL;
char sys_hostname[256];
+ int require_homehost = 1;
char *mailaddr = NULL;
char *program = NULL;
int delay = 0;
int rebuild_map = 0;
int auto_update_home = 0;
- int copies;
int print_help = 0;
FILE *outf;
shortopt, long_options,
&option_index)) != -1) {
int newmode = mode;
- /* firstly, some mode-independant options */
+ /* firstly, some mode-independent options */
switch(opt) {
case 'h':
if (option_index > 0 &&
continue;
case HomeHost:
- homehost = optarg;
+ if (strcasecmp(optarg, "<ignore>") == 0)
+ require_homehost = 0;
+ else
+ homehost = optarg;
continue;
case ':':
case O(GROW,'z'):
- case O(CREATE,'z'): /* size */
+ case O(CREATE,'z'):
+ case O(BUILD,'z'): /* size */
if (size >= 0) {
fprintf(stderr, Name ": size may only be specified once. "
"Second value is %s.\n", optarg);
}
continue;
+ case O(GROW,'Z'): /* array size */
+ if (array_size >= 0) {
+ fprintf(stderr, Name ": array-size may only be specified once. "
+ "Second value is %s.\n", optarg);
+ exit(2);
+ }
+ if (strcmp(optarg, "max") == 0)
+ array_size = 0;
+ else {
+ array_size = parse_size(optarg);
+ if (array_size <= 0) {
+ fprintf(stderr, Name ": invalid array size: %s\n",
+ optarg);
+ exit(2);
+ }
+ }
+ continue;
+
case O(GROW,'l'): /* hack - needed to understand layout */
case O(CREATE,'l'):
case O(BUILD,'l'): /* set raid level*/
exit(2);
case 5:
- case 6:
layout = map_name(r5layout, optarg);
if (layout==UnSet) {
fprintf(stderr, Name ": layout %s not understood for raid5.\n",
exit(2);
}
break;
+ case 6:
+ layout = map_name(r6layout, optarg);
+ if (layout==UnSet) {
+ fprintf(stderr, Name ": layout %s not understood for raid6.\n",
+ optarg);
+ exit(2);
+ }
+ break;
case 10:
- /* 'f', 'o' or 'n' followed by a number <= raid_disks */
- if ((optarg[0] != 'n' && optarg[0] != 'f' && optarg[0] != 'o') ||
- (copies = strtoul(optarg+1, &cp, 10)) < 1 ||
- copies > 200 ||
- *cp) {
+ layout = parse_layout_10(optarg);
+ if (layout < 0) {
fprintf(stderr, Name ": layout for raid10 must be 'nNN', 'oNN' or 'fNN' where NN is a number, not %s\n", optarg);
exit(2);
}
- if (optarg[0] == 'n')
- layout = 256 + copies;
- else if (optarg[0] == 'o')
- layout = 0x10000 + (copies<<8) + 1;
- else
- layout = 1 + (copies<<8);
break;
case -5: /* Faulty
* modeNNN
*/
-
- {
- int ln = strcspn(optarg, "0123456789");
- char *m = strdup(optarg);
- int mode;
- m[ln] = 0;
- mode = map_name(faultylayout, m);
- if (mode == UnSet) {
+ layout = parse_layout_faulty(optarg);
+ if (layout == -1) {
fprintf(stderr, Name ": layout %s not understood for faulty.\n",
optarg);
exit(2);
}
- layout = mode | (atoi(optarg+ln)<< ModeShift);
- }
+ break;
}
continue;
}
if (homehost == NULL)
- homehost = conf_get_homehost();
+ homehost = conf_get_homehost(&require_homehost);
if (homehost == NULL || strcmp(homehost, "<system>")==0) {
if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
sys_hostname[sizeof(sys_hostname)-1] = 0;
array_ident->autof = autof;
rv |= Assemble(ss, devlist->devname, array_ident,
NULL, backup_file,
- readonly, runstop, update, homehost, verbose-quiet, force);
+ readonly, runstop, update,
+ homehost, require_homehost,
+ verbose-quiet, force);
}
} else if (!scan)
rv = Assemble(ss, devlist->devname, &ident,
devlist->next, backup_file,
- readonly, runstop, update, homehost, verbose-quiet, force);
+ readonly, runstop, update,
+ homehost, require_homehost,
+ verbose-quiet, force);
else if (devs_found>0) {
if (update && devs_found > 1) {
fprintf(stderr, Name ": can only update a single array at a time\n");
array_ident->autof = autof;
rv |= Assemble(ss, dv->devname, array_ident,
NULL, backup_file,
- readonly, runstop, update, homehost, verbose-quiet, force);
+ readonly, runstop, update,
+ homehost, require_homehost,
+ verbose-quiet, force);
}
} else {
mddev_ident_t array_list = conf_get_ident(NULL);
exit(1);
}
for (; array_list; array_list = array_list->next) {
+ if (array_list->devname &&
+ strcasecmp(array_list->devname, "<ignore>") == 0)
+ continue;
if (array_list->autof == 0)
array_list->autof = autof;
rv |= Assemble(ss, array_list->devname,
array_list,
NULL, NULL,
- readonly, runstop, NULL, homehost, verbose-quiet, force);
+ readonly, runstop, NULL,
+ homehost, require_homehost,
+ verbose-quiet, force);
cnt++;
}
if (homehost && cnt == 0) {
rv2 = Assemble(ss, NULL,
&ident,
devlist, NULL,
- readonly, runstop, NULL, homehost, verbose-quiet, force);
+ readonly, runstop, NULL,
+ homehost, require_homehost,
+ verbose-quiet, force);
if (rv2==0) {
cnt++;
acnt++;
rv2 = Assemble(ss, NULL,
&ident,
NULL, NULL,
- readonly, runstop, "homehost", homehost, verbose-quiet, force);
+ readonly, runstop, "homehost",
+ homehost, require_homehost,
+ verbose-quiet, force);
if (rv2==0) {
cnt++;
acnt++;
rv = Build(devlist->devname, chunk, level, layout,
raiddisks, devlist->next, assume_clean,
bitmap_file, bitmap_chunk, write_behind,
- delay, verbose-quiet, autof);
+ delay, verbose-quiet, autof, size);
break;
case CREATE:
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
*/
struct mdstat_ent *ms = mdstat_read(0, 1);
struct mdstat_ent *e;
+ struct map_ent *map = NULL;
int v = verbose>1?0:verbose+1;
for (e=ms ; e ; e=e->next) {
- char *name = get_md_name(e->devnum);
+ char *name;
+ struct map_ent *me;
+ me = map_by_devnum(&map, e->devnum);
+ if (me && me->path
+ && strcmp(me->path, "/unknown") != 0)
+ name = me->path;
+ else
+ name = get_md_name(e->devnum);
if (!name) {
fprintf(stderr, Name ": cannot find device file for %s\n",
break;
case GROW:
+ if (array_size >= 0) {
+ /* alway impose array size first, independent of
+ * anything else
+ */
+ struct mdinfo sra;
+ int err;
+ sysfs_init(&sra, mdfd, 0);
+ if (array_size == 0)
+ err = sysfs_set_str(&sra, NULL, "array_size", "default");
+ else
+ err = sysfs_set_num(&sra, NULL, "array_size", array_size / 2);
+ if (err < 0) {
+ if (errno == E2BIG)
+ fprintf(stderr, Name ": --array-size setting"
+ " is too large.\n");
+ else
+ fprintf(stderr, Name ": current kernel does"
+ " not support setting --array-size\n");
+ rv = 1;
+ break;
+ }
+ }
if (devs_found > 1) {
/* must be '-a'. */
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
bitmap_chunk, delay, write_behind, force);
- } else
+ } else if (array_size < 0)
fprintf(stderr, Name ": no changes to --grow\n");
break;
case INCREMENTAL:
break;
}
rv = Incremental(devlist->devname, verbose-quiet, runstop,
- ss, homehost, autof);
+ ss, homehost, require_homehost, autof);
break;
case AUTODETECT:
autodetect();