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:
parent
d23534e464
commit
2904b26f05
|
@ -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++;
|
||||
|
|
2
Manage.c
2
Manage.c
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -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
11
sysfs.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue