diff --git a/Detail.c b/Detail.c index ab01cfb..001012a 100644 --- a/Detail.c +++ b/Detail.c @@ -122,12 +122,25 @@ int Detail(char *dev, int brief, int export, int test, char *homehost) disk.minor == 0) continue; if ((dv=map_dev(disk.major, disk.minor, 1))) { - if ((!st || !st->sb) && + /* some formats (imsm) have free-floating-spares + * with a uuid of uuid_match_any, they don't + * have very good info about the rest of the + * container, so keep searching when + * encountering such a device. Otherwise, stop + * after the first successful call to + * ->load_super. + */ + int free_spare = memcmp(uuid_match_any, + info.uuid, + sizeof(uuid_match_any)) == 0; + if ((!st || !st->sb || free_spare) && (array.raid_disks == 0 || (disk.state & (1<ss->free_super(st); int fd2 = dev_open(dv, O_RDONLY); if (fd2 >=0 && st && st->ss->load_super(st, fd2, NULL) == 0) { diff --git a/Examine.c b/Examine.c index c79a701..7fbd4ae 100644 --- a/Examine.c +++ b/Examine.c @@ -118,7 +118,8 @@ int Examine(mddev_dev_t devlist, int brief, int export, int scan, st->ss->getinfo_super(st, &ap->info); } else st->ss->getinfo_super(st, &ap->info); - if (!(ap->info.disk.state & (1<loaded_container && + !(ap->info.disk.state & (1<spares++; d = dl_strdup(devlist->devname); dl_add(ap->devs, d); @@ -136,17 +137,23 @@ int Examine(mddev_dev_t devlist, int brief, int export, int scan, for (ap=arrays; ap; ap=ap->next) { char sep='='; char *d; + int newline = 0; + ap->st->ss->brief_examine_super(ap->st, brief > 1); - if (ap->spares) printf(" spares=%d", ap->spares); + if (ap->spares) + newline += printf(" spares=%d", ap->spares); if (brief > 1) { - printf(" devices"); + newline += printf(" devices"); for (d=dl_next(ap->devs); d!= ap->devs; d=dl_next(d)) { printf("%c%s", sep, d); sep=','; } } - if (ap->st->ss->brief_examine_subarrays) + if (ap->st->ss->brief_examine_subarrays) { + if (newline) + printf("\n"); ap->st->ss->brief_examine_subarrays(ap->st, brief > 1); + } ap->st->ss->free_super(ap->st); /* FIXME free ap */ if (ap->spares || brief > 1) diff --git a/mdmon.c b/mdmon.c index 37f97af..31994d8 100644 --- a/mdmon.c +++ b/mdmon.c @@ -395,7 +395,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot) } else pfd[0] = pfd[1] = -1; - container = malloc(sizeof(*container)); + container = calloc(1, sizeof(*container)); container->devnum = devnum; container->devname = devname; container->arrays = NULL; diff --git a/super-intel.c b/super-intel.c index 782519e..07b0b90 100644 --- a/super-intel.c +++ b/super-intel.c @@ -64,7 +64,6 @@ struct imsm_disk { #define SPARE_DISK __cpu_to_le32(0x01) /* Spare */ #define CONFIGURED_DISK __cpu_to_le32(0x02) /* Member of some RaidDev */ #define FAILED_DISK __cpu_to_le32(0x04) /* Permanent failure */ -#define USABLE_DISK __cpu_to_le32(0x08) /* Fully usable unless FAILED_DISK is set */ __u32 status; /* 0xF0 - 0xF3 */ __u32 owner_cfg_num; /* which config 0,1,2... owns this disk */ #define IMSM_DISK_FILLERS 4 @@ -687,10 +686,9 @@ static void print_imsm_disk(struct imsm_super *mpb, int index, __u32 reserved) snprintf(str, MAX_RAID_SERIAL_LEN + 1, "%s", disk->serial); printf(" Disk%02d Serial : %s\n", index, str); s = disk->status; - printf(" State :%s%s%s%s\n", s&SPARE_DISK ? " spare" : "", + printf(" State :%s%s%s\n", s&SPARE_DISK ? " spare" : "", s&CONFIGURED_DISK ? " active" : "", - s&FAILED_DISK ? " failed" : "", - s&USABLE_DISK ? " usable" : ""); + s&FAILED_DISK ? " failed" : ""); printf(" Id : %08x\n", __le32_to_cpu(disk->scsi_id)); sz = __le32_to_cpu(disk->total_blocks) - reserved; printf(" Usable Size : %llu%s\n", (unsigned long long)sz, @@ -1499,18 +1497,17 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst) dv->next = first->devlist; first->devlist = dv; } - if (i <= sec->anchor->num_raid_devs) { + if (i < sec->anchor->num_raid_devs) { /* allocation failure */ free_devlist(first); fprintf(stderr, "imsm: failed to associate spare\n"); return 3; } - for (i = 0; i < sec->anchor->num_raid_devs; i++) - imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i)); - first->anchor->num_raid_devs = sec->anchor->num_raid_devs; first->anchor->orig_family_num = sec->anchor->orig_family_num; first->anchor->family_num = sec->anchor->family_num; + for (i = 0; i < sec->anchor->num_raid_devs; i++) + imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i)); } return 0; @@ -2569,7 +2566,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk, super->anchor->num_disks++; } set_imsm_ord_tbl_ent(map, dk->number, dl->index); - dl->disk.status = CONFIGURED_DISK | USABLE_DISK; + dl->disk.status = CONFIGURED_DISK; /* if we are creating the first raid device update the family number */ if (super->current_vol == 0) { @@ -2637,7 +2634,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk, size /= 512; serialcpy(dd->disk.serial, dd->serial); dd->disk.total_blocks = __cpu_to_le32(size); - dd->disk.status = USABLE_DISK | SPARE_DISK; + dd->disk.status = SPARE_DISK; if (sysfs_disk_to_scsi_id(fd, &id) == 0) dd->disk.scsi_id = __cpu_to_le32(id); else @@ -3463,8 +3460,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st) s = d ? d->disk.status : 0; if (s & FAILED_DISK) skip = 1; - if (!(s & USABLE_DISK)) - skip = 1; if (ord & IMSM_ORD_REBUILD) skip = 1; @@ -3685,6 +3680,7 @@ static int mark_failure(struct imsm_dev *dev, struct imsm_disk *disk, int idx) return 0; disk->status |= FAILED_DISK; + disk->status &= ~CONFIGURED_DISK; set_imsm_ord_tbl_ent(map, slot, idx | IMSM_ORD_REBUILD); if (~map->failed_disk_num == 0) map->failed_disk_num = slot; diff --git a/util.c b/util.c index 2543971..4ccb1bb 100644 --- a/util.c +++ b/util.c @@ -863,6 +863,8 @@ void wait_for(char *dev, int fd) return; usleep(200000); } + if (i == 25) + dprintf("%s: timeout waiting for %s\n", __func__, dev); } struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL };