Grow: support --array-size changes
With 2.6.30 it is possible to tell the md driver to clip an array to a size smaller than the real size of the array. This option gives access to that feature. The size change does not persist across restarts. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
e0d95aac96
commit
84e11361aa
9
ReadMe.c
9
ReadMe.c
|
@ -86,11 +86,11 @@ char Version[] = Name " - v3.0-rc1 - 11th May 2009\n";
|
|||
* At the time if writing, there is only minimal support.
|
||||
*/
|
||||
|
||||
char short_options[]="-ABCDEFGIQhVXWvqbc:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:";
|
||||
char short_options[]="-ABCDEFGIQhVXWZvqbc:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:";
|
||||
char short_bitmap_options[]=
|
||||
"-ABCDEFGIQhVXWvqb:c:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:";
|
||||
"-ABCDEFGIQhVXWZvqb:c:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:";
|
||||
char short_bitmap_auto_options[]=
|
||||
"-ABCDEFGIQhVXWvqb:c:i:l:p:m:n:x:u:c:d:z:U:sa:rfRSow1tye:";
|
||||
"-ABCDEFGIQhVXWZvqb:c:i:l:p:m:n:x:u:c:d:z:U:sa:rfRSow1tye:";
|
||||
|
||||
struct option long_options[] = {
|
||||
{"manage", 0, 0, '@'},
|
||||
|
@ -182,6 +182,7 @@ struct option long_options[] = {
|
|||
{"syslog", 0, 0, 'y'},
|
||||
/* For Grow */
|
||||
{"backup-file", 1,0, BackupFile},
|
||||
{"array-size", 1, 0, 'Z'},
|
||||
|
||||
/* For Incremental */
|
||||
{"rebuild-map", 0, 0, 'r'},
|
||||
|
@ -525,6 +526,8 @@ char Help_grow[] =
|
|||
" --backup-file= file : A file on a differt device to store data for a\n"
|
||||
" : short time while increasing raid-devices on a\n"
|
||||
" : RAID4/5/6 array. Not needed when a spare is present.\n"
|
||||
" --array-size= -Z : Change visible size of array. This does not change\n"
|
||||
" : any data on the device, and is not stable across restarts.\n"
|
||||
;
|
||||
|
||||
char Help_incr[] =
|
||||
|
|
15
mdadm.8
15
mdadm.8
|
@ -593,6 +593,21 @@ raid-devices in a RAID5 if there are no spare devices available.
|
|||
See the section below on RAID_DEVICE CHANGES. The file should be
|
||||
stored on a separate device, not on the raid array being reshaped.
|
||||
|
||||
.TP
|
||||
.BR \-\-array-size= ", " \-Z
|
||||
Set the size of the array which is seen by users of the device such as
|
||||
filesystems. This can be less that the real size, but never greater.
|
||||
The size set this way does not persist across restarts of the array.
|
||||
|
||||
This is most useful when reducing the number of devices in a RAID5 or
|
||||
RAID6. Such arrays require the array-size to be reduced before a
|
||||
reshape can be performed that reduces the real size.
|
||||
|
||||
A value of
|
||||
.B max
|
||||
restores the apparent size of the array to be whatever the real
|
||||
amount of available space is.
|
||||
|
||||
.TP
|
||||
.BR \-N ", " \-\-name=
|
||||
Set a
|
||||
|
|
43
mdadm.c
43
mdadm.c
|
@ -46,6 +46,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
int chunk = 0;
|
||||
long long size = -1;
|
||||
long long array_size = -1;
|
||||
int level = UnSet;
|
||||
int layout = UnSet;
|
||||
int raiddisks = 0;
|
||||
|
@ -397,6 +398,24 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
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*/
|
||||
|
@ -1372,6 +1391,28 @@ int main(int argc, char *argv[])
|
|||
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'. */
|
||||
|
@ -1398,7 +1439,7 @@ int main(int argc, char *argv[])
|
|||
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:
|
||||
|
|
1
mdadm.h
1
mdadm.h
|
@ -774,6 +774,7 @@ extern unsigned long bitmap_sectors(struct bitmap_super_s *bsb);
|
|||
|
||||
extern int md_get_version(int fd);
|
||||
extern int get_linux_version(void);
|
||||
extern long long parse_size(char *size);
|
||||
extern int parse_uuid(char *str, int uuid[4]);
|
||||
extern int check_ext2(int fd, char *name);
|
||||
extern int check_reiser(int fd, char *name);
|
||||
|
|
31
util.c
31
util.c
|
@ -154,6 +154,37 @@ int get_linux_version()
|
|||
return (a*1000000)+(b*1000)+c;
|
||||
}
|
||||
|
||||
long long parse_size(char *size)
|
||||
{
|
||||
/* parse 'size' which should be a number optionally
|
||||
* followed by 'K', 'M', or 'G'.
|
||||
* Without a suffix, K is assumed.
|
||||
* Number returned is in sectors (half-K)
|
||||
*/
|
||||
char *c;
|
||||
long long s = strtoll(size, &c, 10);
|
||||
if (s > 0) {
|
||||
switch (*c) {
|
||||
case 'K':
|
||||
c++;
|
||||
default:
|
||||
s *= 2;
|
||||
break;
|
||||
case 'M':
|
||||
c++;
|
||||
s *= 1024 * 2;
|
||||
break;
|
||||
case 'G':
|
||||
c++;
|
||||
s *= 1024 * 1024 * 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*c)
|
||||
s = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
void remove_partitions(int fd)
|
||||
{
|
||||
/* remove partitions from this block devices.
|
||||
|
|
Loading…
Reference in New Issue