Use one function chosing spares from container
container_chose_spares in Monitor.c and get_spares_for_grow in super-intel.c do the same thing: search for spares in a container. Another version will also be needed for Incremental so a more general solution is presented here and applied in two previous contexts. Normally domlist==NULL would lead an empty list but this is typically checked earlier so here it is interpreted as "do not test domains". Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
ed7fc6b4d9
commit
326727d9c9
51
Monitor.c
51
Monitor.c
|
@ -828,59 +828,34 @@ static dev_t container_choose_spare(struct state *from, struct state *to,
|
|||
/* This is similar to choose_spare, but we cannot trust devstate,
|
||||
* so we need to read the metadata instead
|
||||
*/
|
||||
|
||||
struct mdinfo *list;
|
||||
struct supertype *st = from->metadata;
|
||||
int fd = open(from->devname, O_RDONLY);
|
||||
int err;
|
||||
struct mdinfo *disks, *d;
|
||||
dev_t dev = 0;
|
||||
|
||||
if (fd < 0)
|
||||
return 0;
|
||||
if (!st->ss->getinfo_super_disks)
|
||||
if (!st->ss->getinfo_super_disks) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = st->ss->load_container(st, fd, NULL);
|
||||
close(fd);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
disks = st->ss->getinfo_super_disks(st);
|
||||
st->ss->free_super(st);
|
||||
|
||||
if (!disks)
|
||||
return 0;
|
||||
|
||||
for (d = disks->devs ; d && !dev ; d = d->next) {
|
||||
if (d->disk.state == 0) {
|
||||
struct dev_policy *pol;
|
||||
unsigned long long dev_size;
|
||||
dev = makedev(d->disk.major,d->disk.minor);
|
||||
|
||||
if (min_size &&
|
||||
dev_size_from_id(dev, &dev_size) &&
|
||||
dev_size < min_size) {
|
||||
dev = 0;
|
||||
continue;
|
||||
}
|
||||
if (from == to)
|
||||
/* Just checking if destination already has
|
||||
* a spare, no need to check policy, we are
|
||||
* done.
|
||||
*/
|
||||
break;
|
||||
|
||||
pol = devnum_policy(dev);
|
||||
if (from->spare_group)
|
||||
pol_add(&pol, pol_domain,
|
||||
from->spare_group, NULL);
|
||||
if (!domain_test(domlist, pol, to->metadata->ss->name))
|
||||
dev = 0;
|
||||
|
||||
dev_policy_free(pol);
|
||||
}
|
||||
/* We only need one spare so full list not needed */
|
||||
list = container_choose_spares(st, min_size, domlist, from->spare_group,
|
||||
to->metadata->ss->name, 1);
|
||||
if (list) {
|
||||
struct mdinfo *disks = list->devs;
|
||||
if (disks)
|
||||
dev = makedev(disks->disk.major, disks->disk.minor);
|
||||
sysfs_free(list);
|
||||
}
|
||||
sysfs_free(disks);
|
||||
st->ss->free_super(st);
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
|
6
mdadm.h
6
mdadm.h
|
@ -1095,7 +1095,11 @@ extern void append_metadata_update(struct supertype *st, void *buf, int len);
|
|||
extern int assemble_container_content(struct supertype *st, int mdfd,
|
||||
struct mdinfo *content, int runstop,
|
||||
char *chosen_name, int verbose);
|
||||
|
||||
extern struct mdinfo *container_choose_spares(struct supertype *st,
|
||||
unsigned long long min_size,
|
||||
struct domainlist *domlist,
|
||||
char *spare_group,
|
||||
const char *metadata, int get_one);
|
||||
extern int add_disk(int mdfd, struct supertype *st,
|
||||
struct mdinfo *sra, struct mdinfo *info);
|
||||
extern int remove_disk(int mdfd, struct supertype *st,
|
||||
|
|
|
@ -6241,42 +6241,8 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
|
|||
*/
|
||||
static struct mdinfo *get_spares_for_grow(struct supertype *st)
|
||||
{
|
||||
dev_t dev = 0;
|
||||
struct mdinfo *disks, *d, **dp;
|
||||
unsigned long long min_size = min_acceptable_spare_size_imsm(st);
|
||||
|
||||
/* get list of alldisks in container */
|
||||
disks = getinfo_super_disks_imsm(st);
|
||||
|
||||
if (!disks)
|
||||
return NULL;
|
||||
/* find spare devices on the list */
|
||||
dp = &disks->devs;
|
||||
disks->array.spare_disks = 0;
|
||||
while (*dp) {
|
||||
int found = 0;
|
||||
d = *dp;
|
||||
if (d->disk.state == 0) {
|
||||
/* check if size is acceptable */
|
||||
unsigned long long dev_size;
|
||||
dev = makedev(d->disk.major,d->disk.minor);
|
||||
if (min_size &&
|
||||
dev_size_from_id(dev, &dev_size) &&
|
||||
dev_size >= min_size) {
|
||||
dev = 0;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
dp = &d->next;
|
||||
disks->array.spare_disks++;
|
||||
} else {
|
||||
*dp = d->next;
|
||||
d->next = NULL;
|
||||
sysfs_free(d);
|
||||
}
|
||||
}
|
||||
return disks;
|
||||
return container_choose_spares(st, min_size, NULL, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
60
util.c
60
util.c
|
@ -1909,3 +1909,63 @@ int experimental(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Pick all spares matching given criteria from a container
|
||||
* if min_size == 0 do not check size
|
||||
* if domlist == NULL do not check domains
|
||||
* if spare_group given add it to domains of each spare
|
||||
* metadata allows to test domains using metadata of destination array */
|
||||
struct mdinfo *container_choose_spares(struct supertype *st,
|
||||
unsigned long long min_size,
|
||||
struct domainlist *domlist,
|
||||
char *spare_group,
|
||||
const char *metadata, int get_one)
|
||||
{
|
||||
struct mdinfo *d, **dp, *disks = NULL;
|
||||
|
||||
/* get list of all disks in container */
|
||||
if (st->ss->getinfo_super_disks)
|
||||
disks = st->ss->getinfo_super_disks(st);
|
||||
|
||||
if (!disks)
|
||||
return disks;
|
||||
/* find spare devices on the list */
|
||||
dp = &disks->devs;
|
||||
disks->array.spare_disks = 0;
|
||||
while (*dp) {
|
||||
int found = 0;
|
||||
d = *dp;
|
||||
if (d->disk.state == 0) {
|
||||
/* check if size is acceptable */
|
||||
unsigned long long dev_size;
|
||||
dev_t dev = makedev(d->disk.major,d->disk.minor);
|
||||
|
||||
if (!min_size ||
|
||||
(dev_size_from_id(dev, &dev_size) &&
|
||||
dev_size >= min_size))
|
||||
found = 1;
|
||||
/* check if domain matches */
|
||||
if (found && domlist) {
|
||||
struct dev_policy *pol = devnum_policy(dev);
|
||||
if (spare_group)
|
||||
pol_add(&pol, pol_domain,
|
||||
spare_group, NULL);
|
||||
if (!domain_test(domlist, pol, metadata))
|
||||
found = 0;
|
||||
dev_policy_free(pol);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
dp = &d->next;
|
||||
disks->array.spare_disks++;
|
||||
if (get_one) {
|
||||
sysfs_free(*dp);
|
||||
d->next = NULL;
|
||||
}
|
||||
} else {
|
||||
*dp = d->next;
|
||||
d->next = NULL;
|
||||
sysfs_free(d);
|
||||
}
|
||||
}
|
||||
return disks;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue