st->ss->getinfo_super(st, &info, NULL);
+ if (info.container_enough < 0 || (info.container_enough == 0 && c->runstop < 1)) {
+ if (c->export)
+ printf("MD_STARTED=no\n");
+ else if (c->verbose)
+ pr_err("Not enough devices to start the container.\n");
+
+ return 0;
+ }
+
match = conf_match(st, &info, devname, c->verbose, &rv);
if (match == NULL && rv == 2)
return rv;
int container_member; /* for assembling external-metatdata arrays
* This is to be used internally by metadata
* handler only */
+ /**
+ * flag external handlers can set to indicate that subarrays have:
+ * - not enough disks to start (-1),
+ * - enough disks to start (0),
+ * - all expected disks (1).
+ */
+ int container_enough;
char sys_name[32];
struct mdinfo *devs;
struct mdinfo *next;
struct intel_super *super = st->sb;
struct imsm_disk *disk;
int map_disks = info->array.raid_disks;
+ int max_enough = -1;
int i;
struct imsm_super *mpb;
for (i = 0; i < mpb->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
- int j = 0;
+ int failed, enough, j, missing = 0;
struct imsm_map *map;
+ __u8 state;
+ failed = imsm_count_failed(super, dev, MAP_0);
+ state = imsm_check_degraded(super, dev, failed, MAP_0);
map = get_imsm_map(dev, MAP_0);
/* any newly missing disks?
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;
+ if (is_gen_migration(dev) && missing) {
+ /* during general migration we need all disks
+ * that process is running on.
+ * No new missing disk is allowed.
+ */
+ max_enough = -1;
+ enough = -1;
+ /* no more checks necessary
+ */
+ break;
+ }
+ /* in the missing/failed disk case check to see
+ * if at least one array is runnable
+ */
+ max_enough = max(max_enough, enough);
}
+ info->container_enough = max_enough;
+
if (super->disks) {
__u32 reserved = imsm_reserved_sectors(super, super->disks);