summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid
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 /sys/geom/raid
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.
Diffstat (limited to 'sys/geom/raid')
-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