summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-01-13 14:30:37 +0000
committermav <mav@FreeBSD.org>2013-01-13 14:30:37 +0000
commit6157d3ce336dcb3c28c81507cac6d3daae7d87ff (patch)
tree13c8908bb714be2727e6e96f206709d1ffe420b8
parentdf2fc90f0e744447190cbd4a0d67474ddadfa96c (diff)
downloadFreeBSD-src-6157d3ce336dcb3c28c81507cac6d3daae7d87ff.zip
FreeBSD-src-6157d3ce336dcb3c28c81507cac6d3daae7d87ff.tar.gz
Improve support for disabled disks. If disabled disk disconnected and then
reconnected back, leave it as disconnected. If new disk inserted instead of disabled, rebuild it and leave as enabled.
-rw-r--r--sys/geom/raid/g_raid.c2
-rw-r--r--sys/geom/raid/md_intel.c42
2 files changed, 23 insertions, 21 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index 87760da..91d14c3 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -538,7 +538,7 @@ g_raid_report_disk_state(struct g_raid_disk *disk)
if (disk->d_consumer == NULL)
return;
if (disk->d_state == G_RAID_DISK_S_DISABLED) {
- ;
+ s = G_STATE_ACTIVE; /* XXX */
} else if (disk->d_state == G_RAID_DISK_S_FAILED ||
disk->d_state == G_RAID_DISK_S_STALE_FAILED) {
s = G_STATE_FAILED;
diff --git a/sys/geom/raid/md_intel.c b/sys/geom/raid/md_intel.c
index 4a6fdf6..a9434ab 100644
--- a/sys/geom/raid/md_intel.c
+++ b/sys/geom/raid/md_intel.c
@@ -787,13 +787,9 @@ g_raid_md_intel_start_disk(struct g_raid_disk *disk)
disk_pos = intel_meta_find_disk(meta, pd->pd_disk_meta.serial);
if (disk_pos < 0) {
G_RAID_DEBUG1(1, sc, "Unknown, probably new or stale disk");
- /* Disabled disk is useless for us. */
- if (pd->pd_disk_meta.flags & INTEL_F_DISABLED) {
- g_raid_change_disk_state(disk, G_RAID_DISK_S_DISABLED);
- return (0);
- }
/* Failed stale disk is useless for us. */
- if (pd->pd_disk_meta.flags & INTEL_F_FAILED) {
+ if ((pd->pd_disk_meta.flags & INTEL_F_FAILED) &&
+ !(pd->pd_disk_meta.flags & INTEL_F_DISABLED)) {
g_raid_change_disk_state(disk, G_RAID_DISK_S_STALE_FAILED);
return (0);
}
@@ -884,10 +880,11 @@ nofit:
}
/* Welcome the new disk. */
- if (resurrection)
- g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
- else if (meta->disk[disk_pos].flags & INTEL_F_DISABLED)
+ if ((meta->disk[disk_pos].flags & INTEL_F_DISABLED) &&
+ !(pd->pd_disk_meta.flags & INTEL_F_SPARE))
g_raid_change_disk_state(disk, G_RAID_DISK_S_DISABLED);
+ else if (resurrection)
+ g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
else if (meta->disk[disk_pos].flags & INTEL_F_FAILED)
g_raid_change_disk_state(disk, G_RAID_DISK_S_FAILED);
else if (meta->disk[disk_pos].flags & INTEL_F_SPARE)
@@ -910,14 +907,15 @@ nofit:
migr_global = 0;
}
- if (resurrection) {
- /* Stale disk, almost same as new. */
- g_raid_change_subdisk_state(sd,
- G_RAID_SUBDISK_S_NEW);
- } else if (meta->disk[disk_pos].flags & INTEL_F_DISABLED) {
+ if ((meta->disk[disk_pos].flags & INTEL_F_DISABLED) &&
+ !(pd->pd_disk_meta.flags & INTEL_F_SPARE)) {
/* Disabled disk, useless. */
g_raid_change_subdisk_state(sd,
G_RAID_SUBDISK_S_NONE);
+ } else if (resurrection) {
+ /* Stale disk, almost same as new. */
+ g_raid_change_subdisk_state(sd,
+ G_RAID_SUBDISK_S_NEW);
} else if (meta->disk[disk_pos].flags & INTEL_F_FAILED) {
/* Failed disk, almost useless. */
g_raid_change_subdisk_state(sd,
@@ -1021,7 +1019,8 @@ nofit:
/* Update status of our need for spare. */
if (mdi->mdio_started) {
mdi->mdio_incomplete =
- (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) <
+ (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) +
+ g_raid_ndisks(sc, G_RAID_DISK_S_DISABLED) <
meta->total_disks);
}
@@ -1053,7 +1052,8 @@ g_raid_md_intel_refill(struct g_raid_softc *sc)
update = 0;
do {
/* Make sure we miss anything. */
- na = g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE);
+ na = g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) +
+ g_raid_ndisks(sc, G_RAID_DISK_S_DISABLED);
if (na == meta->total_disks)
break;
@@ -1065,7 +1065,8 @@ g_raid_md_intel_refill(struct g_raid_softc *sc)
TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_state == G_RAID_DISK_S_STALE) {
update += g_raid_md_intel_start_disk(disk);
- if (disk->d_state == G_RAID_DISK_S_ACTIVE)
+ if (disk->d_state == G_RAID_DISK_S_ACTIVE ||
+ disk->d_state == G_RAID_DISK_S_DISABLED)
break;
}
}
@@ -1089,8 +1090,8 @@ g_raid_md_intel_refill(struct g_raid_softc *sc)
}
/* Update status of our need for spare. */
- mdi->mdio_incomplete = (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) <
- meta->total_disks);
+ mdi->mdio_incomplete = (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) +
+ g_raid_ndisks(sc, G_RAID_DISK_S_DISABLED) < meta->total_disks);
/* Request retaste hoping to find spare. */
if (mdi->mdio_incomplete) {
@@ -2242,7 +2243,8 @@ g_raid_md_write_intel(struct g_raid_md_object *md, struct g_raid_volume *tvol,
pd->pd_disk_meta.flags = INTEL_F_FAILED |
INTEL_F_ASSIGNED | INTEL_F_DISABLED;
} else {
- pd->pd_disk_meta.flags = INTEL_F_ASSIGNED;
+ if (!(pd->pd_disk_meta.flags & INTEL_F_DISABLED))
+ pd->pd_disk_meta.flags = INTEL_F_ASSIGNED;
if (pd->pd_disk_meta.id != 0xffffffff) {
pd->pd_disk_meta.id = 0xffffffff;
len = strlen(pd->pd_disk_meta.serial);
OpenPOWER on IntegriCloud