diff options
author | Dan Williams <dan.j.williams@intel.com> | 2008-09-15 20:55:34 -0700 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2008-09-15 20:55:34 -0700 |
commit | 8796fdc4cda2fdc4b1359e51388f7bc49e790c68 (patch) | |
tree | 32ac74db2e1232dde347a994a1414d7cefacac41 /super-intel.c | |
parent | 4d7b1503a719fac929f598697f371a2f09f120aa (diff) | |
download | mdadm-8796fdc4cda2fdc4b1359e51388f7bc49e790c68.tar.gz mdadm-8796fdc4cda2fdc4b1359e51388f7bc49e790c68.tar.xz mdadm-8796fdc4cda2fdc4b1359e51388f7bc49e790c68.zip |
imsm: mark failures like the Matrix driver
* Truncate the first character of the serial number
* Set 'scsi_id' to all f's
* Expect to find disk entries with unmatchable serial numbers, i.e.
expect get_imsm_disk() to return NULL in some situations
* Allow discrepencies between mpb->num_disks and len(super->disks)
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'super-intel.c')
-rw-r--r-- | super-intel.c | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/super-intel.c b/super-intel.c index 1dfcfa1..e54871a 100644 --- a/super-intel.c +++ b/super-intel.c @@ -908,7 +908,7 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd) dl->fd = keep_fd ? fd : -1; dl->devname = devname ? strdup(devname) : NULL; strncpy((char *) dl->serial, (char *) serial, MAX_RAID_SERIAL_LEN); - dl->index = -3; + dl->index = -2; } else if (keep_fd) { close(dl->fd); dl->fd = fd; @@ -935,17 +935,11 @@ load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd) dl->index = -1; else dl->index = i; + break; } } - if (dl->index == -3) { - fprintf(stderr, Name ": device %x:%x with serial %s" - " does not belong to this container\n", - dl->major, dl->minor, (char *) serial); - return 2; - } - if (alloc) super->disks = dl; @@ -1629,7 +1623,7 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose) mpb->generation_num = __cpu_to_le32(1UL); for (d = super->disks; d; d = d->next) { - if (d->index >= 0) + if (d->index != -1) continue; mpb->disk[0] = d->disk; @@ -1661,7 +1655,6 @@ static int write_super_imsm(struct intel_super *super, int doclose) __u32 generation; __u32 sum; int spares = 0; - int raid_disks = 0; int i; __u32 mpb_size = sizeof(struct imsm_super) - sizeof(struct imsm_disk); @@ -1671,19 +1664,13 @@ static int write_super_imsm(struct intel_super *super, int doclose) mpb->generation_num = __cpu_to_le32(generation); for (d = super->disks; d; d = d->next) { - if (d->index < 0) + if (d->index == -1) spares++; else { - raid_disks++; mpb->disk[d->index] = d->disk; mpb_size += sizeof(struct imsm_disk); } } - if (raid_disks != mpb->num_disks) { - fprintf(stderr, "%s: expected %d disks only found %d\n", - __func__, mpb->num_disks, raid_disks); - return 1; - } for (i = 0; i < mpb->num_raid_devs; i++) { struct imsm_dev *dev = __get_imsm_dev(mpb, i); @@ -1702,11 +1689,9 @@ static int write_super_imsm(struct intel_super *super, int doclose) for (d = super->disks; d ; d = d->next) { if (d->index < 0) continue; - if (store_imsm_mpb(d->fd, super)) { + if (store_imsm_mpb(d->fd, super)) fprintf(stderr, "%s: failed for device %d:%d %s\n", __func__, d->major, d->minor, strerror(errno)); - return 1; - } if (doclose) { close(d->fd); d->fd = -1; @@ -2220,22 +2205,24 @@ static __u8 imsm_check_degraded(struct intel_super *super, int n, int failed) int device_per_mirror = 2; /* FIXME is this always the case? * and are they always adjacent? */ - int failed = 0; + int r10fail = 0; int i; for (i = 0; i < map->num_members; i++) { int idx = get_imsm_disk_idx(map, i); struct imsm_disk *disk = get_imsm_disk(super, idx); - if (__le32_to_cpu(disk->status) & FAILED_DISK) - failed++; + if (!disk) + r10fail++; + else if (__le32_to_cpu(disk->status) & FAILED_DISK) + r10fail++; - if (failed >= device_per_mirror) + if (r10fail >= device_per_mirror) return IMSM_T_STATE_FAILED; - /* reset 'failed' for next mirror set */ + /* reset 'r10fail' for next mirror set */ if (!((i + 1) % device_per_mirror)) - failed = 0; + r10fail = 0; } return IMSM_T_STATE_DEGRADED; @@ -2263,7 +2250,9 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_map *map) int idx = get_imsm_disk_idx(map, i); disk = get_imsm_disk(super, idx); - if (__le32_to_cpu(disk->status) & FAILED_DISK) + if (!disk) + failed++; + else if (__le32_to_cpu(disk->status) & FAILED_DISK) failed++; else if (!(__le32_to_cpu(disk->status) & USABLE_DISK)) failed++; @@ -2354,6 +2343,8 @@ static void imsm_set_disk(struct active_array *a, int n, int state) if ((state & DS_FAULTY) && !(status & FAILED_DISK)) { status |= FAILED_DISK; disk->status = __cpu_to_le32(status); + disk->scsi_id = __cpu_to_le32(~0UL); + memmove(&disk->serial[0], &disk->serial[1], MAX_RAID_SERIAL_LEN - 1); new_failure = 1; super->updates_pending++; } @@ -2444,7 +2435,7 @@ static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_a if (dl->index == i) break; - if (__le32_to_cpu(dl->disk.status) & FAILED_DISK) + if (dl && __le32_to_cpu(dl->disk.status) & FAILED_DISK) dl = NULL; if (dl) |