Handle extra 'grow' variations.

UNFINISHED
This commit is contained in:
NeilBrown 2009-08-11 13:02:49 +10:00
parent a628848379
commit 7236ee7ad4
5 changed files with 974 additions and 335 deletions

1245
Grow.c

File diff suppressed because it is too large Load Diff

28
mdadm.c
View File

@ -329,6 +329,7 @@ int main(int argc, char *argv[])
* could depend on the mode */ * could depend on the mode */
#define O(a,b) ((a<<8)|b) #define O(a,b) ((a<<8)|b)
switch (O(mode,opt)) { switch (O(mode,opt)) {
case O(GROW,'c'):
case O(CREATE,'c'): case O(CREATE,'c'):
case O(BUILD,'c'): /* chunk or rounding */ case O(BUILD,'c'): /* chunk or rounding */
if (chunk) { if (chunk) {
@ -418,7 +419,7 @@ int main(int argc, char *argv[])
} }
continue; continue;
case O(GROW,'l'): /* hack - needed to understand layout */ 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 (level != UnSet) {
@ -1412,8 +1413,8 @@ int main(int argc, char *argv[])
if (devs_found > 1) { if (devs_found > 1) {
/* must be '-a'. */ /* must be '-a'. */
if (size >= 0 || raiddisks) { if (size >= 0 || raiddisks || chunk || layout_str != NULL || bitmap_file) {
fprintf(stderr, Name ": --size, --raiddisks, and --add are exclusing in --grow mode\n"); fprintf(stderr, Name ": --add cannot be used with other geometry changes in --grow mode\n");
rv = 1; rv = 1;
break; break;
} }
@ -1422,17 +1423,20 @@ int main(int argc, char *argv[])
if (rv) if (rv)
break; break;
} }
} else if ((size >= 0) + (raiddisks != 0) + (layout_str != NULL) + (bitmap_file != NULL)> 1) { } else if (bitmap_file) {
fprintf(stderr, Name ": can change at most one of size, raiddisks, bitmap, and layout\n"); if (size >= 0 || raiddisks || chunk || layout_str != NULL) {
rv = 1; fprintf(stderr, Name ": --bitmap changes cannot be used with other geometry changes in --grow mode\n");
break; rv = 1;
} else if (size >= 0 || raiddisks || layout_str != NULL) break;
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file, }
size, level, layout_str, chunk, raiddisks); if (delay == 0)
else if (bitmap_file) { delay = DEFAULT_BITMAP_DELAY;
if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file, rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
bitmap_chunk, delay, write_behind, force); bitmap_chunk, delay, write_behind, force);
} else if (size >= 0 || raiddisks != 0 || layout_str != NULL
|| chunk != 0 || level != UnSet) {
rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
size, level, layout_str, chunk, raiddisks);
} else if (array_size < 0) } else if (array_size < 0)
fprintf(stderr, Name ": no changes to --grow\n"); fprintf(stderr, Name ": no changes to --grow\n");
break; break;

View File

@ -370,8 +370,12 @@ extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev, extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long val); char *name, unsigned long long val);
extern int sysfs_uevent(struct mdinfo *sra, char *event); extern int sysfs_uevent(struct mdinfo *sra, char *event);
extern int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev,
char *name);
extern int sysfs_fd_get_ll(int fd, unsigned long long *val);
extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev, extern int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
char *name, unsigned long long *val); char *name, unsigned long long *val);
extern int sysfs_fd_get_str(int fd, char *val, int size);
extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev, extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size); char *name, char *val, int size);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms); extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);

View File

@ -418,15 +418,16 @@ int save_stripes(int *source, unsigned long long *offsets,
for (disk = 0; disk < raid_disks ; disk++) { for (disk = 0; disk < raid_disks ; disk++) {
unsigned long long offset; unsigned long long offset;
int dnum; int dnum;
len = chunk_size;
offset = (start/chunk_size/data_disks)*chunk_size; offset = (start/chunk_size/data_disks)*chunk_size;
dnum = geo_map(disk < data_disks ? disk : data_disks - disk - 1, dnum = geo_map(disk < data_disks ? disk : data_disks - disk - 1,
start/chunk_size/data_disks, start/chunk_size/data_disks,
raid_disks, level, layout); raid_disks, level, layout);
if (dnum < 0) abort();
if (source[dnum] < 0 || if (source[dnum] < 0 ||
lseek64(source[dnum], offsets[disk]+offset, 0) < 0 || lseek64(source[dnum], offsets[disk]+offset, 0) < 0 ||
read(source[dnum], buf+disk * chunk_size, len) != len) read(source[dnum], buf+disk * chunk_size, chunk_size)
!= chunk_size)
if (failed <= 2) { if (failed <= 2) {
fdisk[failed] = dnum; fdisk[failed] = dnum;
fblock[failed] = disk; fblock[failed] = disk;

27
sysfs.c
View File

@ -487,25 +487,32 @@ int sysfs_get_ll(struct mdinfo *sra, struct mdinfo *dev,
return n; return n;
} }
int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev, int sysfs_fd_get_str(int fd, char *val, int size)
char *name, char *val, int size)
{ {
char fname[50];
int n; int n;
int fd;
sprintf(fname, "/sys/block/%s/md/%s/%s", lseek(fd, 0, 0);
sra->sys_name, dev?dev->sys_name:"", name);
fd = open(fname, O_RDONLY);
if (fd < 0)
return -1;
n = read(fd, val, size); n = read(fd, val, size);
close(fd);
if (n <= 0) if (n <= 0)
return -1; return -1;
val[n] = 0; val[n] = 0;
return n; return n;
} }
int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size)
{
int n;
int fd;
fd = sysfs_get_fd(sra, dev, name);
if (fd < 0)
return -1;
n = sysfs_fd_get_str(fd, val, size);
close(fd);
return n;
}
int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms) int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms)
{ {
unsigned long sec; unsigned long sec;