Create new 'struct shape' to pass around array details.
This collects to together many of the args given to create/build/grow Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
3c463be459
commit
e705e81ba6
174
mdadm.c
174
mdadm.c
|
@ -48,26 +48,15 @@ int main(int argc, char *argv[])
|
||||||
int rv;
|
int rv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
int chunk = 0;
|
|
||||||
unsigned long long size = 0;
|
|
||||||
unsigned long long array_size = 0;
|
unsigned long long array_size = 0;
|
||||||
int level = UnSet;
|
|
||||||
int layout = UnSet;
|
|
||||||
char *layout_str = NULL;
|
|
||||||
int raiddisks = 0;
|
|
||||||
int sparedisks = 0;
|
|
||||||
struct mddev_ident ident;
|
struct mddev_ident ident;
|
||||||
char *configfile = NULL;
|
char *configfile = NULL;
|
||||||
int devmode = 0;
|
int devmode = 0;
|
||||||
int write_behind = 0;
|
|
||||||
int bitmap_fd = -1;
|
int bitmap_fd = -1;
|
||||||
char *bitmap_file = NULL;
|
|
||||||
int bitmap_chunk = UnSet;
|
|
||||||
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 assume_clean = 0;
|
|
||||||
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.
|
||||||
|
@ -83,6 +72,11 @@ int main(int argc, char *argv[])
|
||||||
struct context c = {
|
struct context c = {
|
||||||
.require_homehost = 1,
|
.require_homehost = 1,
|
||||||
};
|
};
|
||||||
|
struct shape s = {
|
||||||
|
.level = UnSet,
|
||||||
|
.layout = UnSet,
|
||||||
|
.bitmap_chunk = UnSet,
|
||||||
|
};
|
||||||
|
|
||||||
char sys_hostname[256];
|
char sys_hostname[256];
|
||||||
char *mailaddr = NULL;
|
char *mailaddr = NULL;
|
||||||
|
@ -365,19 +359,19 @@ int main(int argc, char *argv[])
|
||||||
case O(CREATE,ChunkSize):
|
case O(CREATE,ChunkSize):
|
||||||
case O(BUILD,'c'): /* chunk or rounding */
|
case O(BUILD,'c'): /* chunk or rounding */
|
||||||
case O(BUILD,ChunkSize): /* chunk or rounding */
|
case O(BUILD,ChunkSize): /* chunk or rounding */
|
||||||
if (chunk) {
|
if (s.chunk) {
|
||||||
pr_err("chunk/rounding may only be specified once. "
|
pr_err("chunk/rounding may only be specified once. "
|
||||||
"Second value is %s.\n", optarg);
|
"Second value is %s.\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
chunk = parse_size(optarg);
|
s.chunk = parse_size(optarg);
|
||||||
if (chunk < 8 || (chunk&1)) {
|
if (s.chunk < 8 || (s.chunk&1)) {
|
||||||
pr_err("invalid chunk/rounding value: %s\n",
|
pr_err("invalid chunk/rounding value: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/* Convert sectors to K */
|
/* Convert sectors to K */
|
||||||
chunk /= 2;
|
s.chunk /= 2;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(INCREMENTAL, 'e'):
|
case O(INCREMENTAL, 'e'):
|
||||||
|
@ -416,22 +410,22 @@ int main(int argc, char *argv[])
|
||||||
case O(GROW,'z'):
|
case O(GROW,'z'):
|
||||||
case O(CREATE,'z'):
|
case O(CREATE,'z'):
|
||||||
case O(BUILD,'z'): /* size */
|
case O(BUILD,'z'): /* size */
|
||||||
if (size > 0) {
|
if (s.size > 0) {
|
||||||
pr_err("size may only be specified once. "
|
pr_err("size may only be specified once. "
|
||||||
"Second value is %s.\n", optarg);
|
"Second value is %s.\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (strcmp(optarg, "max")==0)
|
if (strcmp(optarg, "max")==0)
|
||||||
size = MAX_SIZE;
|
s.size = MAX_SIZE;
|
||||||
else {
|
else {
|
||||||
size = parse_size(optarg);
|
s.size = parse_size(optarg);
|
||||||
if (size < 8) {
|
if (s.size < 8) {
|
||||||
pr_err("invalid size: %s\n",
|
pr_err("invalid size: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
/* convert sectors to K */
|
/* convert sectors to K */
|
||||||
size /= 2;
|
s.size /= 2;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -456,41 +450,41 @@ int main(int argc, char *argv[])
|
||||||
case O(GROW,'l'):
|
case O(GROW,'l'):
|
||||||
case O(CREATE,'l'):
|
case O(CREATE,'l'):
|
||||||
case O(BUILD,'l'): /* set raid level*/
|
case O(BUILD,'l'): /* set raid level*/
|
||||||
if (level != UnSet) {
|
if (s.level != UnSet) {
|
||||||
pr_err("raid level may only be set once. "
|
pr_err("raid level may only be set once. "
|
||||||
"Second value is %s.\n", optarg);
|
"Second value is %s.\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
level = map_name(pers, optarg);
|
s.level = map_name(pers, optarg);
|
||||||
if (level == UnSet) {
|
if (s.level == UnSet) {
|
||||||
pr_err("invalid raid level: %s\n",
|
pr_err("invalid raid level: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (level != 0 && level != LEVEL_LINEAR && level != 1 &&
|
if (s.level != 0 && s.level != LEVEL_LINEAR && s.level != 1 &&
|
||||||
level != LEVEL_MULTIPATH && level != LEVEL_FAULTY &&
|
s.level != LEVEL_MULTIPATH && s.level != LEVEL_FAULTY &&
|
||||||
level != 10 &&
|
s.level != 10 &&
|
||||||
mode == BUILD) {
|
mode == BUILD) {
|
||||||
pr_err("Raid level %s not permitted with --build.\n",
|
pr_err("Raid level %s not permitted with --build.\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (sparedisks > 0 && level < 1 && level >= -1) {
|
if (s.sparedisks > 0 && s.level < 1 && s.level >= -1) {
|
||||||
pr_err("raid level %s is incompatible with spare-devices setting.\n",
|
pr_err("raid level %s is incompatible with spare-devices setting.\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
ident.level = level;
|
ident.level = s.level;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(GROW, 'p'): /* new layout */
|
case O(GROW, 'p'): /* new layout */
|
||||||
case O(GROW, Layout):
|
case O(GROW, Layout):
|
||||||
if (layout_str) {
|
if (s.layout_str) {
|
||||||
pr_err("layout may only be sent once. "
|
pr_err("layout may only be sent once. "
|
||||||
"Second value was %s\n", optarg);
|
"Second value was %s\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
layout_str = optarg;
|
s.layout_str = optarg;
|
||||||
/* 'Grow' will parse the value */
|
/* 'Grow' will parse the value */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -498,31 +492,31 @@ int main(int argc, char *argv[])
|
||||||
case O(CREATE,Layout):
|
case O(CREATE,Layout):
|
||||||
case O(BUILD,'p'): /* faulty layout */
|
case O(BUILD,'p'): /* faulty layout */
|
||||||
case O(BUILD,Layout):
|
case O(BUILD,Layout):
|
||||||
if (layout != UnSet) {
|
if (s.layout != UnSet) {
|
||||||
pr_err("layout may only be sent once. "
|
pr_err("layout may only be sent once. "
|
||||||
"Second value was %s\n", optarg);
|
"Second value was %s\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
switch(level) {
|
switch(s.level) {
|
||||||
default:
|
default:
|
||||||
pr_err("layout not meaningful for %s arrays.\n",
|
pr_err("layout not meaningful for %s arrays.\n",
|
||||||
map_num(pers, level));
|
map_num(pers, s.level));
|
||||||
exit(2);
|
exit(2);
|
||||||
case UnSet:
|
case UnSet:
|
||||||
pr_err("raid level must be given before layout.\n");
|
pr_err("raid level must be given before layout.\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
layout = map_name(r5layout, optarg);
|
s.layout = map_name(r5layout, optarg);
|
||||||
if (layout==UnSet) {
|
if (s.layout==UnSet) {
|
||||||
pr_err("layout %s not understood for raid5.\n",
|
pr_err("layout %s not understood for raid5.\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
layout = map_name(r6layout, optarg);
|
s.layout = map_name(r6layout, optarg);
|
||||||
if (layout==UnSet) {
|
if (s.layout==UnSet) {
|
||||||
pr_err("layout %s not understood for raid6.\n",
|
pr_err("layout %s not understood for raid6.\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -530,8 +524,8 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
layout = parse_layout_10(optarg);
|
s.layout = parse_layout_10(optarg);
|
||||||
if (layout < 0) {
|
if (s.layout < 0) {
|
||||||
pr_err("layout for raid10 must be 'nNN', 'oNN' or 'fNN' where NN is a number, not %s\n", optarg);
|
pr_err("layout for raid10 must be 'nNN', 'oNN' or 'fNN' where NN is a number, not %s\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
@ -540,8 +534,8 @@ int main(int argc, char *argv[])
|
||||||
/* Faulty
|
/* Faulty
|
||||||
* modeNNN
|
* modeNNN
|
||||||
*/
|
*/
|
||||||
layout = parse_layout_faulty(optarg);
|
s.layout = parse_layout_faulty(optarg);
|
||||||
if (layout == -1) {
|
if (s.layout == -1) {
|
||||||
pr_err("layout %s not understood for faulty.\n",
|
pr_err("layout %s not understood for faulty.\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -553,39 +547,39 @@ int main(int argc, char *argv[])
|
||||||
case O(CREATE,AssumeClean):
|
case O(CREATE,AssumeClean):
|
||||||
case O(BUILD,AssumeClean): /* assume clean */
|
case O(BUILD,AssumeClean): /* assume clean */
|
||||||
case O(GROW,AssumeClean):
|
case O(GROW,AssumeClean):
|
||||||
assume_clean = 1;
|
s.assume_clean = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(GROW,'n'):
|
case O(GROW,'n'):
|
||||||
case O(CREATE,'n'):
|
case O(CREATE,'n'):
|
||||||
case O(BUILD,'n'): /* number of raid disks */
|
case O(BUILD,'n'): /* number of raid disks */
|
||||||
if (raiddisks) {
|
if (s.raiddisks) {
|
||||||
pr_err("raid-devices set twice: %d and %s\n",
|
pr_err("raid-devices set twice: %d and %s\n",
|
||||||
raiddisks, optarg);
|
s.raiddisks, optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
raiddisks = parse_num(optarg);
|
s.raiddisks = parse_num(optarg);
|
||||||
if (raiddisks <= 0) {
|
if (s.raiddisks <= 0) {
|
||||||
pr_err("invalid number of raid devices: %s\n",
|
pr_err("invalid number of raid devices: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
ident.raid_disks = raiddisks;
|
ident.raid_disks = s.raiddisks;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(CREATE,'x'): /* number of spare (eXtra) disks */
|
case O(CREATE,'x'): /* number of spare (eXtra) disks */
|
||||||
if (sparedisks) {
|
if (s.sparedisks) {
|
||||||
pr_err("spare-devices set twice: %d and %s\n",
|
pr_err("spare-devices set twice: %d and %s\n",
|
||||||
sparedisks, optarg);
|
s.sparedisks, optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (level != UnSet && level <= 0 && level >= -1) {
|
if (s.level != UnSet && s.level <= 0 && s.level >= -1) {
|
||||||
pr_err("spare-devices setting is incompatible with raid level %d\n",
|
pr_err("spare-devices setting is incompatible with raid level %d\n",
|
||||||
level);
|
s.level);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
sparedisks = parse_num(optarg);
|
s.sparedisks = parse_num(optarg);
|
||||||
if (sparedisks < 0) {
|
if (s.sparedisks < 0) {
|
||||||
pr_err("invalid number of spare-devices: %s\n",
|
pr_err("invalid number of spare-devices: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -1043,7 +1037,7 @@ int main(int argc, char *argv[])
|
||||||
if (strcmp(optarg, "internal")== 0 ||
|
if (strcmp(optarg, "internal")== 0 ||
|
||||||
strcmp(optarg, "none")== 0 ||
|
strcmp(optarg, "none")== 0 ||
|
||||||
strchr(optarg, '/') != NULL) {
|
strchr(optarg, '/') != NULL) {
|
||||||
bitmap_file = optarg;
|
s.bitmap_file = optarg;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* probable typo */
|
/* probable typo */
|
||||||
|
@ -1054,24 +1048,24 @@ int main(int argc, char *argv[])
|
||||||
case O(GROW,BitmapChunk):
|
case O(GROW,BitmapChunk):
|
||||||
case O(BUILD,BitmapChunk):
|
case O(BUILD,BitmapChunk):
|
||||||
case O(CREATE,BitmapChunk): /* bitmap chunksize */
|
case O(CREATE,BitmapChunk): /* bitmap chunksize */
|
||||||
bitmap_chunk = parse_size(optarg);
|
s.bitmap_chunk = parse_size(optarg);
|
||||||
if (bitmap_chunk <= 0 ||
|
if (s.bitmap_chunk <= 0 ||
|
||||||
bitmap_chunk & (bitmap_chunk - 1)) {
|
s.bitmap_chunk & (s.bitmap_chunk - 1)) {
|
||||||
pr_err("invalid bitmap chunksize: %s\n",
|
pr_err("invalid bitmap chunksize: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
bitmap_chunk = bitmap_chunk * 512;
|
s.bitmap_chunk = s.bitmap_chunk * 512;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(GROW, WriteBehind):
|
case O(GROW, WriteBehind):
|
||||||
case O(BUILD, WriteBehind):
|
case O(BUILD, WriteBehind):
|
||||||
case O(CREATE, WriteBehind): /* write-behind mode */
|
case O(CREATE, WriteBehind): /* write-behind mode */
|
||||||
write_behind = DEFAULT_MAX_WRITE_BEHIND;
|
s.write_behind = DEFAULT_MAX_WRITE_BEHIND;
|
||||||
if (optarg) {
|
if (optarg) {
|
||||||
write_behind = parse_num(optarg);
|
s.write_behind = parse_num(optarg);
|
||||||
if (write_behind < 0 ||
|
if (s.write_behind < 0 ||
|
||||||
write_behind > 16383) {
|
s.write_behind > 16383) {
|
||||||
pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", optarg);
|
pr_err("Invalid value for maximum outstanding write-behind writes: %s.\n\tMust be between 0 and 16383.\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
@ -1188,8 +1182,8 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raiddisks) {
|
if (s.raiddisks) {
|
||||||
if (raiddisks == 1 && !c.force && level != LEVEL_FAULTY) {
|
if (s.raiddisks == 1 && !c.force && s.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");
|
||||||
|
@ -1297,49 +1291,49 @@ int main(int argc, char *argv[])
|
||||||
case BUILD:
|
case BUILD:
|
||||||
if (c.delay == 0)
|
if (c.delay == 0)
|
||||||
c.delay = DEFAULT_BITMAP_DELAY;
|
c.delay = DEFAULT_BITMAP_DELAY;
|
||||||
if (write_behind && !bitmap_file) {
|
if (s.write_behind && !s.bitmap_file) {
|
||||||
pr_err("write-behind mode requires a bitmap.\n");
|
pr_err("write-behind mode requires a bitmap.\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (raiddisks == 0) {
|
if (s.raiddisks == 0) {
|
||||||
pr_err("no raid-devices specified.\n");
|
pr_err("no raid-devices specified.\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap_file) {
|
if (s.bitmap_file) {
|
||||||
if (strcmp(bitmap_file, "internal")==0) {
|
if (strcmp(s.bitmap_file, "internal")==0) {
|
||||||
pr_err("'internal' bitmaps not supported with --build\n");
|
pr_err("'internal' bitmaps not supported with --build\n");
|
||||||
rv |= 1;
|
rv |= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv = Build(devlist->devname, chunk, level, layout,
|
rv = Build(devlist->devname, s.chunk, s.level, s.layout,
|
||||||
raiddisks, devlist->next, assume_clean,
|
s.raiddisks, devlist->next, s.assume_clean,
|
||||||
bitmap_file, bitmap_chunk, write_behind,
|
s.bitmap_file, s.bitmap_chunk, s.write_behind,
|
||||||
&c, size);
|
&c, s.size);
|
||||||
break;
|
break;
|
||||||
case CREATE:
|
case CREATE:
|
||||||
if (c.delay == 0)
|
if (c.delay == 0)
|
||||||
c.delay = DEFAULT_BITMAP_DELAY;
|
c.delay = DEFAULT_BITMAP_DELAY;
|
||||||
if (write_behind && !bitmap_file) {
|
if (s.write_behind && !s.bitmap_file) {
|
||||||
pr_err("write-behind mode requires a bitmap.\n");
|
pr_err("write-behind mode requires a bitmap.\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (raiddisks == 0) {
|
if (s.raiddisks == 0) {
|
||||||
pr_err("no raid-devices specified.\n");
|
pr_err("no raid-devices specified.\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = Create(ss, devlist->devname, chunk, level, layout, size,
|
rv = Create(ss, devlist->devname, s.chunk, s.level, s.layout, s.size,
|
||||||
raiddisks, sparedisks, ident.name,
|
s.raiddisks, s.sparedisks, ident.name,
|
||||||
ident.uuid_set ? ident.uuid : NULL,
|
ident.uuid_set ? ident.uuid : NULL,
|
||||||
devs_found-1, devlist->next,
|
devs_found-1, devlist->next,
|
||||||
assume_clean,
|
s.assume_clean,
|
||||||
bitmap_file, bitmap_chunk, write_behind, &c);
|
s.bitmap_file, s.bitmap_chunk, s.write_behind, &c);
|
||||||
break;
|
break;
|
||||||
case MISC:
|
case MISC:
|
||||||
if (devmode == 'E') {
|
if (devmode == 'E') {
|
||||||
|
@ -1405,7 +1399,7 @@ int main(int argc, char *argv[])
|
||||||
*/
|
*/
|
||||||
struct mdinfo sra;
|
struct mdinfo sra;
|
||||||
int err;
|
int err;
|
||||||
if (raiddisks || level != UnSet) {
|
if (s.raiddisks || s.level != UnSet) {
|
||||||
pr_err("cannot change array size in same operation "
|
pr_err("cannot change array size in same operation "
|
||||||
"as changing raiddisks or level.\n"
|
"as changing raiddisks or level.\n"
|
||||||
" Change size first, then check that data is still intact.\n");
|
" Change size first, then check that data is still intact.\n");
|
||||||
|
@ -1428,9 +1422,9 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (devs_found > 1 && raiddisks == 0) {
|
if (devs_found > 1 && s.raiddisks == 0) {
|
||||||
/* must be '-a'. */
|
/* must be '-a'. */
|
||||||
if (size > 0 || chunk || layout_str != NULL || bitmap_file) {
|
if (s.size > 0 || s.chunk || s.layout_str != NULL || s.bitmap_file) {
|
||||||
pr_err("--add cannot be used with "
|
pr_err("--add cannot be used with "
|
||||||
"other geometry changes in --grow mode\n");
|
"other geometry changes in --grow mode\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
|
@ -1442,9 +1436,9 @@ int main(int argc, char *argv[])
|
||||||
if (rv)
|
if (rv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (bitmap_file) {
|
} else if (s.bitmap_file) {
|
||||||
if (size > 0 || raiddisks || chunk ||
|
if (s.size > 0 || s.raiddisks || s.chunk ||
|
||||||
layout_str != NULL || devs_found > 1) {
|
s.layout_str != NULL || devs_found > 1) {
|
||||||
pr_err("--bitmap changes cannot be "
|
pr_err("--bitmap changes cannot be "
|
||||||
"used with other geometry changes "
|
"used with other geometry changes "
|
||||||
"in --grow mode\n");
|
"in --grow mode\n");
|
||||||
|
@ -1453,18 +1447,18 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (c.delay == 0)
|
if (c.delay == 0)
|
||||||
c.delay = DEFAULT_BITMAP_DELAY;
|
c.delay = DEFAULT_BITMAP_DELAY;
|
||||||
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
|
rv = Grow_addbitmap(devlist->devname, mdfd, s.bitmap_file,
|
||||||
bitmap_chunk, c.delay, write_behind, c.force);
|
s.bitmap_chunk, c.delay, s.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, c.backup_file,
|
mdfd, c.backup_file,
|
||||||
c.verbose);
|
c.verbose);
|
||||||
else if (size > 0 || raiddisks != 0 || layout_str != NULL
|
else if (s.size > 0 || s.raiddisks || s.layout_str != NULL
|
||||||
|| chunk != 0 || level != UnSet) {
|
|| s.chunk != 0 || s.level != UnSet) {
|
||||||
rv = Grow_reshape(devlist->devname, mdfd, c.verbose, c.backup_file,
|
rv = Grow_reshape(devlist->devname, mdfd, c.verbose, c.backup_file,
|
||||||
size, level, layout_str, chunk, raiddisks,
|
s.size, s.level, s.layout_str, s.chunk, s.raiddisks,
|
||||||
devlist->next,
|
devlist->next,
|
||||||
assume_clean, c.force);
|
s.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;
|
||||||
|
|
14
mdadm.h
14
mdadm.h
|
@ -396,6 +396,20 @@ struct context {
|
||||||
int invalid_backup;
|
int invalid_backup;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct shape {
|
||||||
|
int raiddisks;
|
||||||
|
int sparedisks;
|
||||||
|
int level;
|
||||||
|
int layout;
|
||||||
|
char *layout_str;
|
||||||
|
int chunk;
|
||||||
|
int bitmap_chunk;
|
||||||
|
char *bitmap_file;
|
||||||
|
int assume_clean;
|
||||||
|
int write_behind;
|
||||||
|
unsigned long long size;
|
||||||
|
};
|
||||||
|
|
||||||
/* List of device names - wildcards expanded */
|
/* List of device names - wildcards expanded */
|
||||||
struct mddev_dev {
|
struct mddev_dev {
|
||||||
char *devname;
|
char *devname;
|
||||||
|
|
Loading…
Reference in New Issue