Grow: pass layout as a string rather than a number.

This allows the layout to be parsed after the current level of the
array is know, so that the level doesn't need to be given (otherwise
pointlessly) on the command line.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2009-07-14 12:13:29 +10:00
parent d823a6c872
commit 19678e536d
4 changed files with 51 additions and 19 deletions

38
Grow.c
View File

@ -410,7 +410,7 @@ int bsb_csum(char *buf, int len)
int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
long long size,
int level, int layout, int chunksize, int raid_disks)
int level, char *layout_str, int chunksize, int raid_disks)
{
/* Make some changes in the shape of an array.
* The kernel must support the change.
@ -468,10 +468,15 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
devname);
return 1;
}
if (layout == UnSet)
if (layout_str == NULL)
return 0; /* nothing to do.... */
array.layout = layout;
array.layout = parse_layout_faulty(layout_str);
if (array.layout < 0) {
fprintf(stderr, Name ": %s: layout %s not understood for 'faulty' array\n",
devname, layout_str);
return 1;
}
if (ioctl(fd, SET_ARRAY_INFO, &array) != 0) {
fprintf(stderr, Name ": Cannot set layout for %s: %s\n",
devname, strerror(errno));
@ -488,7 +493,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
devname);
return 1;
}
if (chunksize || layout != UnSet) {
if (chunksize || layout_str != NULL) {
fprintf(stderr, Name ": %s: Cannot change chunk size of layout for a RAID1 array.\n",
devname);
return 1;
@ -529,7 +534,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
*/
if (size >= 0) {
/* Cannot change other details as well.. */
if (layout != UnSet ||
if (layout_str != NULL ||
chunksize != 0 ||
raid_disks != 0 ||
level != UnSet) {
@ -586,7 +591,28 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
if (level != UnSet) nlevel = level;
if (chunksize) nchunk = chunksize;
if (layout != UnSet) nlayout = layout;
if (layout_str != NULL)
switch(nlevel) {
case 4: /* ignore layout */
break;
case 5:
nlayout = map_name(r5layout, layout_str);
if (nlayout == UnSet) {
fprintf(stderr, Name ": layout %s not understood for raid5.\n",
layout_str);
return 1;
}
break;
case 6:
nlayout = map_name(r6layout, layout_str);
if (nlayout == UnSet) {
fprintf(stderr, Name ": layout %s not understood for raid6.\n",
layout_str);
return 1;
}
break;
}
if (raid_disks) ndisks = raid_disks;
odata = odisks-1;

View File

@ -482,11 +482,6 @@ option to set subsequent failure modes.
"clear" or "none" will remove any pending or periodic failure modes,
and "flush" will clear any persistent faults.
To set the parity with
.BR \-\-grow ,
the level of the array ("faulty")
must be specified before the fault mode is specified.
Finally, the layout options for RAID10 are one of 'n', 'o' or 'f' followed
by a small number. The default is 'n2'. The supported options are:

25
mdadm.c
View File

@ -49,6 +49,7 @@ int main(int argc, char *argv[])
long long array_size = -1;
int level = UnSet;
int layout = UnSet;
char *layout_str = NULL;
int raiddisks = 0;
int max_disks = MD_SB_DISKS; /* just a default */
int sparedisks = 0;
@ -442,9 +443,18 @@ int main(int argc, char *argv[])
ident.level = level;
continue;
case O(GROW, 'p'): /* new layout */
if (layout_str) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
exit(2);
}
layout_str = optarg;
/* 'Grow' will parse the value */
continue;
case O(CREATE,'p'): /* raid5 layout */
case O(BUILD,'p'): /* faulty layout */
case O(GROW, 'p'): /* faulty reconfig */
if (layout != UnSet) {
fprintf(stderr,Name ": layout may only be sent once. "
"Second value was %s\n", optarg);
@ -483,9 +493,10 @@ int main(int argc, char *argv[])
exit(2);
}
break;
case -5: /* Faulty
* modeNNN
*/
case LEVEL_FAULTY:
/* Faulty
* modeNNN
*/
layout = parse_layout_faulty(optarg);
if (layout == -1) {
fprintf(stderr, Name ": layout %s not understood for faulty.\n",
@ -1409,13 +1420,13 @@ int main(int argc, char *argv[])
if (rv)
break;
}
} else if ((size >= 0) + (raiddisks != 0) + (layout != UnSet) + (bitmap_file != NULL)> 1) {
} else if ((size >= 0) + (raiddisks != 0) + (layout_str != NULL) + (bitmap_file != NULL)> 1) {
fprintf(stderr, Name ": can change at most one of size, raiddisks, bitmap, and layout\n");
rv = 1;
break;
} else if (size >= 0 || raiddisks || layout != UnSet)
} else if (size >= 0 || raiddisks || layout_str != NULL)
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
size, level, layout, chunk, raiddisks);
size, level, layout_str, chunk, raiddisks);
else if (bitmap_file) {
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,

View File

@ -714,7 +714,7 @@ extern int Grow_Add_device(char *devname, int fd, char *newdev);
extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force);
extern int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
long long size,
int level, int layout, int chunksize, int raid_disks);
int level, char *layout_str, int chunksize, int raid_disks);
extern int Grow_restart(struct supertype *st, struct mdinfo *info,
int *fdlist, int cnt, char *backup_file);