Incremental: honor an 'enough' flag from external handlers
This is needed for imsm where: 1/ we want to report raid_disks as zero to allow mdadm -As to incorporate all spares 2/ we can't determine stale disks by looking at the event counts. 3/ we can't see per-subarray expectations with the info returned from the container level ->getinfo_super() Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
4460f8f7c3
commit
97b4d0e971
|
@ -258,6 +258,15 @@ int Incremental(char *devname, int verbose, int runstop,
|
|||
autof = ci->autof;
|
||||
|
||||
if (st->ss->container_content && st->loaded_container) {
|
||||
if ((runstop > 0 && info.container_enough >= 0) ||
|
||||
info.container_enough > 0)
|
||||
/* pass */;
|
||||
else {
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": not enough devices to start the container\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This is a pre-built container array, so we do something
|
||||
* rather different.
|
||||
*/
|
||||
|
|
4
mdadm.h
4
mdadm.h
|
@ -205,7 +205,9 @@ struct mdinfo {
|
|||
int container_member; /* for assembling external-metatdata arrays
|
||||
* This is to be used internally by metadata
|
||||
* handler only */
|
||||
|
||||
int container_enough; /* flag external handlers can set to
|
||||
* indicate that subarrays have not enough (-1),
|
||||
* enough to start (0), or all expected disks (1) */
|
||||
char sys_name[20];
|
||||
struct mdinfo *devs;
|
||||
struct mdinfo *next;
|
||||
|
|
|
@ -1357,6 +1357,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
|
|||
(ddf->anchor.guid+16));
|
||||
info->array.utime = 0;
|
||||
info->array.chunk_size = 0;
|
||||
info->container_enough = 0;
|
||||
|
||||
|
||||
info->disk.major = 0;
|
||||
|
|
|
@ -344,7 +344,6 @@ static struct imsm_disk *__get_imsm_disk(struct imsm_super *mpb, __u8 index)
|
|||
return &mpb->disk[index];
|
||||
}
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
/* retrieve a disk from the parsed metadata */
|
||||
static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
|
||||
{
|
||||
|
@ -356,7 +355,6 @@ static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* generate a checksum directly from the anchor when the anchor is known to be
|
||||
* up-to-date, currently only at load or write_super after coalescing
|
||||
|
@ -1528,6 +1526,20 @@ static void fixup_container_spare_uuid(struct mdinfo *inf)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed);
|
||||
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev);
|
||||
|
||||
static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
|
||||
{
|
||||
struct dl *d;
|
||||
|
||||
for (d = super->missing; d; d = d->next)
|
||||
if (d->index == index)
|
||||
return &d->disk;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
|
@ -1562,6 +1574,53 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
|||
info->name[0] = 0;
|
||||
info->recovery_start = MaxSector;
|
||||
|
||||
/* do we have the all the insync disks that we expect? */
|
||||
if (st->loaded_container) {
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
int max_enough = -1, i;
|
||||
|
||||
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||
int failed, enough, j, missing = 0;
|
||||
struct imsm_map *map;
|
||||
__u8 state;
|
||||
|
||||
failed = imsm_count_failed(super, dev);
|
||||
state = imsm_check_degraded(super, dev, failed);
|
||||
map = get_imsm_map(dev, dev->vol.migr_state);
|
||||
|
||||
/* any newly missing disks?
|
||||
* (catches single-degraded vs double-degraded)
|
||||
*/
|
||||
for (j = 0; j < map->num_members; j++) {
|
||||
__u32 ord = get_imsm_ord_tbl_ent(dev, i);
|
||||
__u32 idx = ord_to_idx(ord);
|
||||
|
||||
if (!(ord & IMSM_ORD_REBUILD) &&
|
||||
get_imsm_missing(super, idx)) {
|
||||
missing = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == IMSM_T_STATE_FAILED)
|
||||
enough = -1;
|
||||
else if (state == IMSM_T_STATE_DEGRADED &&
|
||||
(state != map->map_state || missing))
|
||||
enough = 0;
|
||||
else /* we're normal, or already degraded */
|
||||
enough = 1;
|
||||
|
||||
/* in the missing/failed disk case check to see
|
||||
* if at least one array is runnable
|
||||
*/
|
||||
max_enough = max(max_enough, enough);
|
||||
}
|
||||
dprintf("%s: enough: %d\n", __func__, max_enough);
|
||||
info->container_enough = max_enough;
|
||||
} else
|
||||
info->container_enough = -1;
|
||||
|
||||
if (super->disks) {
|
||||
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
||||
|
||||
|
@ -4175,24 +4234,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
|
|||
}
|
||||
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
static int imsm_open_new(struct supertype *c, struct active_array *a,
|
||||
char *inst)
|
||||
{
|
||||
struct intel_super *super = c->sb;
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
|
||||
if (atoi(inst) >= mpb->num_raid_devs) {
|
||||
fprintf(stderr, "%s: subarry index %d, out of range\n",
|
||||
__func__, atoi(inst));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dprintf("imsm: open_new %s\n", inst);
|
||||
a->info.container_member = atoi(inst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
|
||||
{
|
||||
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||
|
@ -4291,6 +4332,24 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev)
|
|||
return failed;
|
||||
}
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
static int imsm_open_new(struct supertype *c, struct active_array *a,
|
||||
char *inst)
|
||||
{
|
||||
struct intel_super *super = c->sb;
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
|
||||
if (atoi(inst) >= mpb->num_raid_devs) {
|
||||
fprintf(stderr, "%s: subarry index %d, out of range\n",
|
||||
__func__, atoi(inst));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
dprintf("imsm: open_new %s\n", inst);
|
||||
a->info.container_member = atoi(inst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_resyncing(struct imsm_dev *dev)
|
||||
{
|
||||
struct imsm_map *migr_map;
|
||||
|
|
Loading…
Reference in New Issue