Add continue option to grow command

To allow for reshape continuation '--continue' option is added
to grow command.
Function that will be executed in grow-continue case doesn't require
information about reshape geometry. All required information are read
from metadata.
For external metadata reshape can be run for monitored array/container
only. In case when array/container is not monitored run mdmon for it.

Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
Adam Kwolek 2011-10-03 09:26:48 +11:00 committed by NeilBrown
parent b76b30e0f9
commit 2dddadb0f7
4 changed files with 146 additions and 1 deletions

131
Grow.c
View File

@ -3632,6 +3632,137 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
return 1;
}
int Grow_continue_command(char *devname, int fd,
char *backup_file, int verbose)
{
int ret_val = 0;
struct supertype *st = NULL;
struct mdinfo *content = NULL;
struct mdinfo array;
char *subarray = NULL;
struct mdinfo *cc = NULL;
struct mdstat_ent *mdstat = NULL;
char buf[40];
int cfd = -1;
int fd2 = -1;
dprintf("Grow continue from command line called for %s\n",
devname);
st = super_by_fd(fd, &subarray);
if (!st || !st->ss) {
fprintf(stderr,
Name ": Unable to determine metadata format for %s\n",
devname);
return 1;
}
dprintf("Grow continue is run for ");
if (st->ss->external == 0) {
dprintf("native array (%s)\n", devname);
if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
fprintf(stderr, Name ": %s is not an active md array -"
" aborting\n", devname);
ret_val = 1;
goto Grow_continue_command_exit;
}
content = &array;
sysfs_init(content, fd, st->devnum);
} else {
int container_dev;
if (subarray) {
dprintf("subarray (%s)\n", subarray);
container_dev = st->container_dev;
cfd = open_dev_excl(st->container_dev);
} else {
container_dev = st->devnum;
close(fd);
cfd = open_dev_excl(st->devnum);
dprintf("container (%i)\n", container_dev);
fd = cfd;
}
if (cfd < 0) {
fprintf(stderr, Name ": Unable to open container "
"for %s\n", devname);
ret_val = 1;
goto Grow_continue_command_exit;
}
fmt_devname(buf, container_dev);
/* find in container array under reshape
*/
ret_val = st->ss->load_container(st, cfd, NULL);
if (ret_val) {
fprintf(stderr,
Name ": Cannot read superblock for %s\n",
devname);
ret_val = 1;
goto Grow_continue_command_exit;
}
cc = st->ss->container_content(st, NULL);
for (content = cc; content ; content = content->next) {
char *array;
if (content->reshape_active == 0)
continue;
array = strchr(content->text_version+1, '/')+1;
mdstat = mdstat_by_subdev(array, container_dev);
if (!mdstat)
continue;
break;
}
if (!content) {
fprintf(stderr,
Name ": Unable to determine reshaped "
"array for %s\n", devname);
ret_val = 1;
goto Grow_continue_command_exit;
}
fd2 = open_dev(mdstat->devnum);
if (fd2 < 0) {
fprintf(stderr, Name ": cannot open (md%i)\n",
mdstat->devnum);
ret_val = 1;
goto Grow_continue_command_exit;
}
sysfs_init(content, fd2, mdstat->devnum);
/* start mdmon in case it is not running
*/
if (!mdmon_running(container_dev))
start_mdmon(container_dev);
ping_monitor(buf);
if (mdmon_running(container_dev))
st->update_tail = &st->updates;
else {
fprintf(stderr, Name ": No mdmon found. "
"Grow cannot continue.\n");
ret_val = 1;
goto Grow_continue_command_exit;
}
}
/* continue reshape
*/
ret_val = Grow_continue(fd, st, content, backup_file, 0);
Grow_continue_command_exit:
if (fd2 > -1)
close(fd2);
if (cfd > -1)
close(cfd);
st->ss->free_super(st);
free_mdstat(mdstat);
sysfs_free(cc);
free(subarray);
return ret_val;
}
int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
char *backup_file, int freeze_reshape)
{

View File

@ -191,6 +191,7 @@ struct option long_options[] = {
{"backup-file", 1,0, BackupFile},
{"invalid-backup",0,0,InvalidBackup},
{"array-size", 1, 0, 'Z'},
{"continue", 0, 0, Continue},
/* For Incremental */
{"rebuild-map", 0, 0, RebuildMapOpt},

12
mdadm.c
View File

@ -74,6 +74,7 @@ int main(int argc, char *argv[])
int export = 0;
int assume_clean = 0;
char *symlinks = NULL;
int grow_continue = 0;
/* autof indicates whether and how to create device node.
* bottom 3 bits are style. Rest (when shifted) are number of parts
* 0 - unset
@ -996,6 +997,11 @@ int main(int argc, char *argv[])
backup_file = optarg;
continue;
case O(GROW, Continue):
/* Continue interrupted grow
*/
grow_continue = 1;
continue;
case O(ASSEMBLE, InvalidBackup):
/* Acknowledge that the backupfile is invalid, but ask
* to continue anyway
@ -1649,7 +1655,11 @@ int main(int argc, char *argv[])
delay = DEFAULT_BITMAP_DELAY;
rv = Grow_addbitmap(devlist->devname, mdfd, bitmap_file,
bitmap_chunk, delay, write_behind, force);
} else if (size >= 0 || raiddisks != 0 || layout_str != NULL
} else if (grow_continue)
rv = Grow_continue_command(devlist->devname,
mdfd, backup_file,
verbose);
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,

View File

@ -314,6 +314,7 @@ enum special_options {
InvalidBackup,
UdevRules,
FreezeReshape,
Continue,
};
/* structures read from config file */
@ -1041,6 +1042,8 @@ extern int restore_backup(struct supertype *st,
int spares,
char *backup_file,
int verbose);
extern int Grow_continue_command(char *devname, int fd,
char *backup_file, int verbose);
extern int Assemble(struct supertype *st, char *mddev,
struct mddev_ident *ident,