Incremental.c (mdadm-4.1) | : | Incremental.c (mdadm-4.2) | ||
---|---|---|---|---|
skipping to change at line 403 | skipping to change at line 403 | |||
sprintf(dn, "%d:%d", sra->devs->disk.major, | sprintf(dn, "%d:%d", sra->devs->disk.major, | |||
sra->devs->disk.minor); | sra->devs->disk.minor); | |||
dfd2 = dev_open(dn, O_RDONLY); | dfd2 = dev_open(dn, O_RDONLY); | |||
if (dfd2 < 0) { | if (dfd2 < 0) { | |||
pr_err("unable to open %s\n", devname); | pr_err("unable to open %s\n", devname); | |||
rv = 2; | rv = 2; | |||
goto out_unlock; | goto out_unlock; | |||
} | } | |||
st2 = dup_super(st); | st2 = dup_super(st); | |||
if (st2->ss->load_super(st2, dfd2, NULL) || | if (st2->ss->load_super(st2, dfd2, NULL) || | |||
st->ss->compare_super(st, st2) != 0) { | st->ss->compare_super(st, st2, 1) != 0) { | |||
pr_err("metadata mismatch between %s and chosen a rray %s\n", | pr_err("metadata mismatch between %s and chosen a rray %s\n", | |||
devname, chosen_name); | devname, chosen_name); | |||
close(dfd2); | close(dfd2); | |||
rv = 2; | rv = 2; | |||
goto out_unlock; | goto out_unlock; | |||
} | } | |||
close(dfd2); | close(dfd2); | |||
st2->ss->getinfo_super(st2, &info2, NULL); | st2->ss->getinfo_super(st2, &info2, NULL); | |||
st2->ss->free_super(st2); | st2->ss->free_super(st2); | |||
if (info.array.level != info2.array.level || | if (info.array.level != info2.array.level || | |||
skipping to change at line 483 | skipping to change at line 483 | |||
/* 7/ Is there enough devices to possibly start the array? */ | /* 7/ Is there enough devices to possibly start the array? */ | |||
/* 7a/ if not, finish with success. */ | /* 7a/ if not, finish with success. */ | |||
if (info.array.level == LEVEL_CONTAINER) { | if (info.array.level == LEVEL_CONTAINER) { | |||
char devnm[32]; | char devnm[32]; | |||
/* Try to assemble within the container */ | /* Try to assemble within the container */ | |||
sysfs_uevent(sra, "change"); | sysfs_uevent(sra, "change"); | |||
if (!c->export && c->verbose >= 0) | if (!c->export && c->verbose >= 0) | |||
pr_err("container %s now has %d device%s\n", | pr_err("container %s now has %d device%s\n", | |||
chosen_name, info.array.working_disks, | chosen_name, info.array.working_disks, | |||
info.array.working_disks == 1?"":"s"); | info.array.working_disks == 1?"":"s"); | |||
sysfs_rules_apply(chosen_name, &info); | ||||
wait_for(chosen_name, mdfd); | wait_for(chosen_name, mdfd); | |||
if (st->ss->external) | if (st->ss->external) | |||
strcpy(devnm, fd2devnm(mdfd)); | strcpy(devnm, fd2devnm(mdfd)); | |||
if (st->ss->load_container) | if (st->ss->load_container) | |||
rv = st->ss->load_container(st, mdfd, NULL); | rv = st->ss->load_container(st, mdfd, NULL); | |||
close(mdfd); | close(mdfd); | |||
sysfs_free(sra); | sysfs_free(sra); | |||
if (!rv) | if (!rv) | |||
rv = Incremental_container(st, chosen_name, c, NULL); | rv = Incremental_container(st, chosen_name, c, NULL); | |||
map_unlock(&map); | map_unlock(&map); | |||
skipping to change at line 1083 | skipping to change at line 1084 | |||
return 1; | return 1; | |||
while ((de = readdir(dir)) != NULL) { | while ((de = readdir(dir)) != NULL) { | |||
char *ep; | char *ep; | |||
struct dev_policy *pol2 = NULL; | struct dev_policy *pol2 = NULL; | |||
struct domainlist *domlist = NULL; | struct domainlist *domlist = NULL; | |||
int fd = -1; | int fd = -1; | |||
struct mdinfo info; | struct mdinfo info; | |||
struct supertype *st2 = NULL; | struct supertype *st2 = NULL; | |||
char *devname = NULL; | char *devname = NULL; | |||
unsigned long long devsectors; | unsigned long long devsectors; | |||
char *pathlist[2]; | ||||
if (de->d_ino == 0 || de->d_name[0] == '.' || | if (de->d_ino == 0 || de->d_name[0] == '.' || | |||
(de->d_type != DT_LNK && de->d_type != DT_UNKNOWN)) | (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN)) | |||
goto next; | goto next; | |||
ep = de->d_name + strlen(de->d_name); | ep = de->d_name + strlen(de->d_name); | |||
while (ep > de->d_name && | while (ep > de->d_name && | |||
isdigit(ep[-1])) | isdigit(ep[-1])) | |||
ep--; | ep--; | |||
if (ep > de->d_name + 5 && | if (ep > de->d_name + 5 && | |||
strncmp(ep-5, "-part", 5) == 0) | strncmp(ep-5, "-part", 5) == 0) | |||
/* This is a partition - skip it */ | /* This is a partition - skip it */ | |||
goto next; | goto next; | |||
pol2 = path_policy(de->d_name, type_disk); | pathlist[0] = de->d_name; | |||
pathlist[1] = NULL; | ||||
pol2 = path_policy(pathlist, type_disk); | ||||
domain_merge(&domlist, pol2, st ? st->ss->name : NULL); | domain_merge(&domlist, pol2, st ? st->ss->name : NULL); | |||
if (domain_test(domlist, pol, st ? st->ss->name : NULL) != 1) | if (domain_test(domlist, pol, st ? st->ss->name : NULL) != 1) | |||
/* new device is incompatible with this device. */ | /* new device is incompatible with this device. */ | |||
goto next; | goto next; | |||
domain_free(domlist); | domain_free(domlist); | |||
domlist = NULL; | domlist = NULL; | |||
if (asprintf(&devname, "/dev/disk/by-path/%s", de->d_name) != 1) { | if (asprintf(&devname, "/dev/disk/by-path/%s", de->d_name) != 1) { | |||
skipping to change at line 1345 | skipping to change at line 1349 | |||
container[31] = 0; | container[31] = 0; | |||
sl = strchr(container, '/'); | sl = strchr(container, '/'); | |||
if (sl) | if (sl) | |||
*sl = 0; | *sl = 0; | |||
only = devnm; | only = devnm; | |||
devnm = container; | devnm = container; | |||
goto restart; | goto restart; | |||
} | } | |||
mdfd = open_dev(me->devnm); | mdfd = open_dev(me->devnm); | |||
if (mdfd < 0) | if (!is_fd_valid(mdfd)) | |||
continue; | continue; | |||
if (!isdigit(me->metadata[0])) { | if (!isdigit(me->metadata[0])) { | |||
/* must be a container */ | /* must be a container */ | |||
struct supertype *st = super_by_fd(mdfd, NULL); | struct supertype *st = super_by_fd(mdfd, NULL); | |||
int ret = 0; | int ret = 0; | |||
struct map_ent *map = NULL; | struct map_ent *map = NULL; | |||
if (st && st->ss->load_container) | if (st && st->ss->load_container) | |||
ret = st->ss->load_container(st, mdfd, NULL); | ret = st->ss->load_container(st, mdfd, NULL); | |||
close(mdfd); | close_fd(&mdfd); | |||
if (!ret && st && st->ss->container_content) { | if (!ret && st && st->ss->container_content) { | |||
if (map_lock(&map)) | if (map_lock(&map)) | |||
pr_err("failed to get exclusive lock on m apfile\n"); | pr_err("failed to get exclusive lock on m apfile\n"); | |||
ret = Incremental_container(st, me->path, c, only ); | ret = Incremental_container(st, me->path, c, only ); | |||
map_unlock(&map); | map_unlock(&map); | |||
} | } | |||
if (ret) | if (ret) | |||
rv = 1; | rv = 1; | |||
continue; | continue; | |||
} | } | |||
if (md_array_active(mdfd)) { | if (md_array_active(mdfd)) { | |||
close(mdfd); | close_fd(&mdfd); | |||
continue; | continue; | |||
} | } | |||
/* Ok, we can try this one. Maybe it needs a bitmap */ | /* Ok, we can try this one. Maybe it needs a bitmap */ | |||
for (mddev = devs ; mddev ; mddev = mddev->next) | for (mddev = devs ; mddev ; mddev = mddev->next) | |||
if (mddev->devname && me->path && | if (mddev->devname && me->path && | |||
devname_matches(mddev->devname, me->path)) | devname_matches(mddev->devname, me->path)) | |||
break; | break; | |||
if (mddev && mddev->bitmap_file) { | if (mddev && mddev->bitmap_file) { | |||
/* | /* | |||
* Note: early kernels will wrongly fail this, so it | * Note: early kernels will wrongly fail this, so it | |||
* is a hint only | * is a hint only | |||
*/ | */ | |||
int added = -1; | int added = -1; | |||
int bmfd; | int bmfd; | |||
bmfd = open(mddev->bitmap_file, O_RDWR); | bmfd = open(mddev->bitmap_file, O_RDWR); | |||
if (bmfd >= 0) { | if (is_fd_valid(bmfd)) { | |||
added = ioctl(mdfd, SET_BITMAP_FILE, bmfd); | added = ioctl(mdfd, SET_BITMAP_FILE, bmfd); | |||
close(bmfd); | close_fd(&bmfd); | |||
} | } | |||
if (c->verbose >= 0) { | if (c->verbose >= 0) { | |||
if (added == 0) | if (added == 0) | |||
pr_err("Added bitmap %s to %s\n", | pr_err("Added bitmap %s to %s\n", | |||
mddev->bitmap_file, me->path); | mddev->bitmap_file, me->path); | |||
else if (errno != EEXIST) | else if (errno != EEXIST) | |||
pr_err("Failed to add bitmap to %s: %s\n" , | pr_err("Failed to add bitmap to %s: %s\n" , | |||
me->path, strerror(errno)); | me->path, strerror(errno)); | |||
} | } | |||
} | } | |||
skipping to change at line 1415 | skipping to change at line 1419 | |||
pr_err("started array %s\n", | pr_err("started array %s\n", | |||
me->path ?: me->devnm); | me->path ?: me->devnm); | |||
} else { | } else { | |||
pr_err("failed to start array %s: %s\n", | pr_err("failed to start array %s: %s\n", | |||
me->path ?: me->devnm, | me->path ?: me->devnm, | |||
strerror(errno)); | strerror(errno)); | |||
rv = 1; | rv = 1; | |||
} | } | |||
sysfs_free(sra); | sysfs_free(sra); | |||
} | } | |||
close_fd(&mdfd); | ||||
} | } | |||
map_free(mapl); | map_free(mapl); | |||
return rv; | return rv; | |||
} | } | |||
static char *container2devname(char *devname) | static char *container2devname(char *devname) | |||
{ | { | |||
char *mdname = NULL; | char *mdname = NULL; | |||
if (devname[0] == '/') { | if (devname[0] == '/') { | |||
skipping to change at line 1459 | skipping to change at line 1464 | |||
* array, choose a device name and assemble the array. | * array, choose a device name and assemble the array. | |||
*/ | */ | |||
struct mdinfo *list; | struct mdinfo *list; | |||
struct mdinfo *ra; | struct mdinfo *ra; | |||
struct map_ent *map = NULL; | struct map_ent *map = NULL; | |||
struct mdinfo info; | struct mdinfo info; | |||
int trustworthy; | int trustworthy; | |||
struct mddev_ident *match; | struct mddev_ident *match; | |||
int rv = 0; | int rv = 0; | |||
struct domainlist *domains; | ||||
struct map_ent *smp; | ||||
int suuid[4]; | ||||
int sfd; | ||||
int ra_blocked = 0; | ||||
int ra_all = 0; | ||||
int result = 0; | int result = 0; | |||
st->ss->getinfo_super(st, &info, NULL); | st->ss->getinfo_super(st, &info, NULL); | |||
if ((c->runstop > 0 && info.container_enough >= 0) || | if ((c->runstop > 0 && info.container_enough >= 0) || | |||
info.container_enough > 0) | info.container_enough > 0) | |||
/* pass */; | /* pass */; | |||
else { | else { | |||
if (c->export) { | if (c->export) { | |||
printf("MD_STARTED=no\n"); | printf("MD_STARTED=no\n"); | |||
skipping to change at line 1508 | skipping to change at line 1507 | |||
printf("MD_STARTED=nothing\n"); | printf("MD_STARTED=nothing\n"); | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
for (ra = list ; ra ; ra = ra->next) { | for (ra = list ; ra ; ra = ra->next) { | |||
int mdfd; | int mdfd; | |||
char chosen_name[1024]; | char chosen_name[1024]; | |||
struct map_ent *mp; | struct map_ent *mp; | |||
struct mddev_ident *match = NULL; | struct mddev_ident *match = NULL; | |||
ra_all++; | ||||
/* do not activate arrays blocked by metadata handler */ | /* do not activate arrays blocked by metadata handler */ | |||
if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) { | if (ra->array.state & (1 << MD_SB_BLOCK_VOLUME)) { | |||
pr_err("Cannot activate array %s in %s.\n", | pr_err("Cannot activate array %s in %s.\n", | |||
ra->text_version, devname); | ra->text_version, devname); | |||
ra_blocked++; | ||||
continue; | continue; | |||
} | } | |||
mp = map_by_uuid(&map, ra->uuid); | mp = map_by_uuid(&map, ra->uuid); | |||
if (mp) { | if (mp) { | |||
mdfd = open_dev(mp->devnm); | mdfd = open_dev(mp->devnm); | |||
if (mp->path) | if (mp->path) | |||
strcpy(chosen_name, mp->path); | strcpy(chosen_name, mp->path); | |||
else | else | |||
strcpy(chosen_name, mp->devnm); | strcpy(chosen_name, mp->devnm); | |||
skipping to change at line 1616 | skipping to change at line 1613 | |||
if (result & INCR_ALREADY) { | if (result & INCR_ALREADY) { | |||
printf("%calready", sep); | printf("%calready", sep); | |||
sep = ','; | sep = ','; | |||
} | } | |||
if (result & INCR_YES) { | if (result & INCR_YES) { | |||
printf("%cyes", sep); | printf("%cyes", sep); | |||
sep = ','; | sep = ','; | |||
} | } | |||
printf("\n"); | printf("\n"); | |||
} | } | |||
/* don't move spares to container with volume being activated | ||||
when all volumes are blocked */ | ||||
if (ra_all == ra_blocked) | ||||
return 0; | ||||
/* Now move all suitable spares from spare container */ | ||||
domains = domain_from_array(list, st->ss->name); | ||||
memcpy(suuid, uuid_zero, sizeof(int[4])); | ||||
if (domains && | ||||
(smp = map_by_uuid(&map, suuid)) != NULL && | ||||
(sfd = open(smp->path, O_RDONLY)) >= 0) { | ||||
/* spare container found */ | ||||
struct supertype *sst = | ||||
super_imsm.match_metadata_desc("imsm"); | ||||
struct mdinfo *sinfo; | ||||
if (!sst->ss->load_container(sst, sfd, NULL)) { | ||||
struct spare_criteria sc = {0, 0}; | ||||
if (st->ss->get_spare_criteria) | ||||
st->ss->get_spare_criteria(st, &sc); | ||||
close(sfd); | ||||
sinfo = container_choose_spares(sst, &sc, | ||||
domains, NULL, | ||||
st->ss->name, 0); | ||||
sst->ss->free_super(sst); | ||||
if (sinfo){ | ||||
int count = 0; | ||||
struct mdinfo *disks = sinfo->devs; | ||||
while (disks) { | ||||
/* move spare from spare | ||||
* container to currently | ||||
* assembled one | ||||
*/ | ||||
if (move_spare( | ||||
smp->path, | ||||
devname, | ||||
makedev(disks->disk.major, | ||||
disks->disk.minor))) | ||||
count++; | ||||
disks = disks->next; | ||||
} | ||||
if (count) | ||||
pr_err("Added %d spare%s to %s\n", | ||||
count, count>1?"s":"", devname); | ||||
} | ||||
sysfs_free(sinfo); | ||||
} else | ||||
close(sfd); | ||||
} | ||||
domain_free(domains); | ||||
map_free(map); | ||||
return 0; | return 0; | |||
} | } | |||
static void run_udisks(char *arg1, char *arg2) | static void run_udisks(char *arg1, char *arg2) | |||
{ | { | |||
int pid = fork(); | int pid = fork(); | |||
int status; | int status; | |||
if (pid == 0) { | if (pid == 0) { | |||
manage_fork_fds(1); | ||||
execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); | execl("/usr/bin/udisks", "udisks", arg1, arg2, NULL); | |||
execl("/bin/udisks", "udisks", arg1, arg2, NULL); | execl("/bin/udisks", "udisks", arg1, arg2, NULL); | |||
exit(1); | exit(1); | |||
} | } | |||
while (pid > 0 && wait(&status) != pid) | while (pid > 0 && wait(&status) != pid) | |||
; | ; | |||
} | } | |||
static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose) | static int force_remove(char *devnm, int fd, struct mdinfo *mdi, int verbose) | |||
{ | { | |||
skipping to change at line 1761 | skipping to change at line 1705 | |||
if (!ent) { | if (!ent) { | |||
if (verbose >= 0) | if (verbose >= 0) | |||
pr_err("%s does not appear to be a component of any array \n", devname); | pr_err("%s does not appear to be a component of any array \n", devname); | |||
return 1; | return 1; | |||
} | } | |||
if (sysfs_init(&mdi, -1, ent->devnm)) { | if (sysfs_init(&mdi, -1, ent->devnm)) { | |||
pr_err("unable to initialize sysfs for: %s\n", devname); | pr_err("unable to initialize sysfs for: %s\n", devname); | |||
return 1; | return 1; | |||
} | } | |||
mdfd = open_dev_excl(ent->devnm); | mdfd = open_dev_excl(ent->devnm); | |||
if (mdfd > 0) { | if (is_fd_valid(mdfd)) { | |||
close(mdfd); | close_fd(&mdfd); | |||
if (sysfs_get_str(&mdi, NULL, "array_state", | if (sysfs_get_str(&mdi, NULL, "array_state", | |||
buf, sizeof(buf)) > 0) { | buf, sizeof(buf)) > 0) { | |||
if (strncmp(buf, "active", 6) == 0 || | if (strncmp(buf, "active", 6) == 0 || | |||
strncmp(buf, "clean", 5) == 0) | strncmp(buf, "clean", 5) == 0) | |||
sysfs_set_str(&mdi, NULL, | sysfs_set_str(&mdi, NULL, | |||
"array_state", "read-auto"); | "array_state", "read-auto"); | |||
} | } | |||
} | } | |||
mdfd = open_dev(ent->devnm); | mdfd = open_dev(ent->devnm); | |||
if (mdfd < 0) { | if (mdfd < 0) { | |||
End of changes. 16 change blocks. | ||||
71 lines changed or deleted | 15 lines changed or added |