/*
* mdadm - Intel(R) Matrix Storage Manager Support
*
- * Copyright (C) 2002-2007 Intel Corporation
+ * Copyright (C) 2002-2008 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
}
#ifndef MDASSEMBLE
+static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info);
+
static void print_imsm_dev(struct imsm_dev *dev, int index)
{
__u64 sz;
__u32 ord;
printf("\n");
- printf("[%s]:\n", dev->volume);
+ printf("[%.16s]:\n", dev->volume);
printf(" RAID Level : %d\n", get_imsm_raid_level(map));
printf(" Members : %d\n", map->num_members);
for (slot = 0; slot < map->num_members; slot++)
struct imsm_super *mpb = super->anchor;
char str[MAX_SIGNATURE_LENGTH];
int i;
+ struct mdinfo info;
+ char nbuf[64];
__u32 sum;
__u32 reserved = imsm_reserved_sectors(super, super->disks);
+
snprintf(str, MPB_SIG_LEN, "%s", mpb->sig);
printf(" Magic : %s\n", str);
snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
printf(" Version : %s\n", get_imsm_version(mpb));
printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
+ getinfo_super_imsm(st, &info);
+ fname_from_uuid(st, &info, nbuf,'-');
+ printf(" UUID : %s\n", nbuf + 5);
sum = __le32_to_cpu(mpb->check_sum);
printf(" Checksum : %08x %s\n", sum,
__gen_imsm_checksum(mpb) == sum ? "correct" : "incorrect");
static void brief_examine_super_imsm(struct supertype *st)
{
- /* We just write a generic DDF ARRAY entry
- */
+ /* We just write a generic IMSM ARRAY entry */
struct mdinfo info;
char nbuf[64];
+ struct intel_super *super = st->sb;
+ int i;
+
+ if (!super->anchor->num_raid_devs)
+ return;
getinfo_super_imsm(st, &info);
fname_from_uuid(st, &info, nbuf,'-');
- printf("ARRAY /dev/imsm metadata=imsm UUID=%s\n", nbuf + 5);
+ printf("ARRAY /dev/imsm metadata=imsm auto=md UUID=%s\n", nbuf + 5);
+ for (i = 0; i < super->anchor->num_raid_devs; i++) {
+ struct imsm_dev *dev = get_imsm_dev(super, i);
+
+ super->current_vol = i;
+ getinfo_super_imsm(st, &info);
+ fname_from_uuid(st, &info, nbuf,'-');
+ printf("ARRAY /dev/md/%.16s container=/dev/imsm member=%d auto=mdp UUID=%s\n",
+ dev->volume, i, nbuf + 5);
+ }
}
static void detail_super_imsm(struct supertype *st, char *homehost)
__u32 reserved = imsm_reserved_sectors(super, super->disks);
disk = &super->disks->disk;
- info->disk.number = super->disks->index;
- info->disk.raid_disk = super->disks->index;
info->data_offset = __le32_to_cpu(disk->total_blocks) - reserved;
info->component_size = reserved;
s = __le32_to_cpu(disk->status);
info->disk.state = s & CONFIGURED_DISK ? (1 << MD_DISK_ACTIVE) : 0;
info->disk.state |= s & FAILED_DISK ? (1 << MD_DISK_FAULTY) : 0;
- info->disk.state |= s & USABLE_DISK ? (1 << MD_DISK_SYNC) : 0;
+ info->disk.state |= s & SPARE_DISK ? 0 : (1 << MD_DISK_SYNC);
}
- uuid_from_super_imsm(st, info->uuid);
+
+ /* only call uuid_from_super_imsm when this disk is part of a populated container,
+ * ->compare_super may have updated the 'num_raid_devs' field for spares
+ */
+ if (info->disk.state & (1 << MD_DISK_SYNC) || super->anchor->num_raid_devs)
+ uuid_from_super_imsm(st, info->uuid);
+ else
+ memcpy(info->uuid, uuid_match_any, sizeof(int[4]));
}
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
*/
if (first->anchor->num_raid_devs == 0 &&
sec->anchor->num_raid_devs > 0) {
+ int i;
+
+ /* we need to copy raid device info from sec if an allocation
+ * fails here we don't associate the spare
+ */
+ for (i = 0; i < sec->anchor->num_raid_devs; i++) {
+ first->dev_tbl[i] = malloc(sizeof(struct imsm_dev));
+ if (!first->dev_tbl) {
+ while (--i >= 0) {
+ free(first->dev_tbl[i]);
+ first->dev_tbl[i] = NULL;
+ }
+ fprintf(stderr, "imsm: failed to associate spare\n");
+ return 3;
+ }
+ *first->dev_tbl[i] = *sec->dev_tbl[i];
+ }
+
first->anchor->num_raid_devs = sec->anchor->num_raid_devs;
first->anchor->family_num = sec->anchor->family_num;
}
}
}
+ /* no match, maybe a stale failed drive */
+ if (i == super->anchor->num_disks && dl->index >= 0) {
+ dl->disk = *__get_imsm_disk(super->anchor, dl->index);
+ if (__le32_to_cpu(dl->disk.status) & FAILED_DISK)
+ dl->index = -2;
+ }
+
if (alloc)
super->disks = dl;
/* found a usable disk with enough space */
di = malloc(sizeof(*di));
+ if (!di)
+ continue;
memset(di, 0, sizeof(*di));
/* dl->index will be -1 in the case we are activating a
* disk_ord_tbl for the array
*/
mu = malloc(sizeof(*mu));
- mu->buf = malloc(sizeof(struct imsm_update_activate_spare) * num_spares);
+ if (mu) {
+ mu->buf = malloc(sizeof(struct imsm_update_activate_spare) * num_spares);
+ if (mu->buf == NULL) {
+ free(mu);
+ mu = NULL;
+ }
+ }
+ if (!mu) {
+ while (rv) {
+ struct mdinfo *n = rv->next;
+
+ free(rv);
+ rv = n;
+ }
+ return NULL;
+ }
+
mu->space = NULL;
mu->len = sizeof(struct imsm_update_activate_spare) * num_spares;
mu->next = *updates;
* being added */
if (super->add) {
struct active_array *a;
+
+ super->updates_pending++;
for (a = st->arrays; a; a = a->next)
a->check_degraded = 1;
}