Dan Williams: Incremental: honor an 'enough' flag from external handlers
Martin F. Krafft
madduck at alioth.debian.org
Sat Aug 28 18:44:08 UTC 2010
Module: mdadm
Branch: build
Commit: 97b4d0e971b20cea66b4a2dd04968cae79a3c2e6
URL: http://git.debian.org/?p=pkg-mdadm/mdadm.git;a=commit;h=97b4d0e971b20cea66b4a2dd04968cae79a3c2e6
Author: Dan Williams <dan.j.williams at intel.com>
Date: Wed May 26 13:22:36 2010 -0700
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 at intel.com>
---
Incremental.c | 9 +++++
mdadm.h | 4 ++-
super-ddf.c | 1 +
super-intel.c | 99 +++++++++++++++++++++++++++++++++++++++++++++-----------
4 files changed, 92 insertions(+), 21 deletions(-)
diff --git a/Incremental.c b/Incremental.c
index 7ad648a..adef44e 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -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.
*/
diff --git a/mdadm.h b/mdadm.h
index d9d17b0..a0797e8 100644
--- a/mdadm.h
+++ b/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;
diff --git a/super-ddf.c b/super-ddf.c
index 0e6f1e5..b01c68d 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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;
diff --git a/super-intel.c b/super-intel.c
index bdd7a96..88ffb52 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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;
More information about the pkg-mdadm-commits
mailing list