Support external metadata recovery-resume

Minimal changes needed to permit reassembling partially recovered
external metadata arrays.  The biggest logical change is that
->container_content() can now surface partially rebuilt members rather
than omitting them from the disk list.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Dan Williams 2009-12-21 12:51:57 -07:00
parent d23534e464
commit 2904b26f05
6 changed files with 15 additions and 6 deletions

View File

@ -1286,7 +1286,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
sysfs_free(sra);
for (dev = content->devs; dev; dev = dev->next)
if (sysfs_add_disk(content, dev) == 0)
if (sysfs_add_disk(content, dev, 1) == 0)
working++;
else if (errno == EEXIST)
preexist++;

View File

@ -697,7 +697,7 @@ int Manage_subdevs(char *devname, int fd,
new_mdi.disk.major = disc.major;
new_mdi.disk.minor = disc.minor;
new_mdi.recovery_start = 0;
if (sysfs_add_disk(sra, &new_mdi) != 0) {
if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
fprintf(stderr, Name ": add new device to external metadata"
" failed for %s\n", dv->devname);
close(container_fd);

View File

@ -410,7 +410,7 @@ static void manage_member(struct mdstat_ent *mdstat,
newd = malloc(sizeof(*newd));
if (!newd)
continue;
if (sysfs_add_disk(&newa->info, d) < 0) {
if (sysfs_add_disk(&newa->info, d, 0) < 0) {
free(newd);
continue;
}

View File

@ -385,7 +385,7 @@ extern int sysfs_get_str(struct mdinfo *sra, struct mdinfo *dev,
char *name, char *val, int size);
extern int sysfs_set_safemode(struct mdinfo *sra, unsigned long ms);
extern int sysfs_set_array(struct mdinfo *info, int vers);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd);
extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
extern int sysfs_unique_holder(int devnum, long rdev);
extern int load_sys(char *path, char *buf);

11
sysfs.c
View File

@ -572,7 +572,7 @@ int sysfs_set_array(struct mdinfo *info, int vers)
return rv;
}
int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
{
char dv[100];
char nm[100];
@ -595,6 +595,13 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
strcpy(sd->sys_name, "dev-");
strcpy(sd->sys_name+4, dname);
/* test write to see if 'recovery_start' is available */
if (resume && sd->recovery_start < MaxSector &&
sysfs_set_num(sra, sd, "recovery_start", 0)) {
sysfs_set_str(sra, sd, "state", "remove");
return -1;
}
rv = sysfs_set_num(sra, sd, "offset", sd->data_offset);
rv |= sysfs_set_num(sra, sd, "size", (sd->component_size+1) / 2);
if (sra->array.level != LEVEL_CONTAINER) {
@ -604,6 +611,8 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd)
*/
sysfs_set_str(sra, sd, "state", "insync");
rv |= sysfs_set_num(sra, sd, "slot", sd->disk.raid_disk);
if (resume)
sysfs_set_num(sra, sd, "recovery_start", sd->recovery_start);
}
return rv;
}

2
util.c
View File

@ -1166,7 +1166,7 @@ int add_disk(int mdfd, struct supertype *st,
info->recovery_start = MaxSector;
else
info->recovery_start = 0;
rv = sysfs_add_disk(sra, info);
rv = sysfs_add_disk(sra, info, 0);
if (! rv) {
struct mdinfo *sd2;
for (sd2 = sra->devs; sd2; sd2=sd2->next)