summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-07-14 12:13:29 +1000
committerNeilBrown <neilb@suse.de>2009-07-14 12:13:29 +1000
commit19678e536d5b7aba8b721a3065f2550b79ddd208 (patch)
tree7537fe1a28214e5fe490b8f8524fb1430c4d26c3
parentd823a6c87225d0c7f96443013798ed4dacf51ff6 (diff)
downloadmdadm-19678e536d5b7aba8b721a3065f2550b79ddd208.tar.gz
mdadm-19678e536d5b7aba8b721a3065f2550b79ddd208.tar.xz
mdadm-19678e536d5b7aba8b721a3065f2550b79ddd208.zip
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>
-rw-r--r--Grow.c38
-rw-r--r--mdadm.85
-rw-r--r--mdadm.c25
-rw-r--r--mdadm.h2
4 files changed, 51 insertions, 19 deletions
diff --git a/Grow.c b/Grow.c
index 15cec5f..65b708a 100644
--- a/Grow.c
+++ b/Grow.c
@@ -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;
diff --git a/mdadm.8 b/mdadm.8
index 079914f..86b974f 100644
--- a/mdadm.8
+++ b/mdadm.8
@@ -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:
diff --git a/mdadm.c b/mdadm.c
index bac0f35..0432622 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -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,
diff --git a/mdadm.h b/mdadm.h
index 170c24b..b2dd730 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -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);