diff options
author | pjd <pjd@FreeBSD.org> | 2004-10-05 11:17:08 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2004-10-05 11:17:08 +0000 |
commit | 3f28bf167b410b5d2330580b044126c343455717 (patch) | |
tree | 369a8c654e08270736f00e647008d8e237d8289f /sys | |
parent | aa22b44625263701c2e0a58eba98b997a225b7c7 (diff) | |
download | FreeBSD-src-3f28bf167b410b5d2330580b044126c343455717.zip FreeBSD-src-3f28bf167b410b5d2330580b044126c343455717.tar.gz |
Before root file system is mounted, wait for mirrors in degraded state.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/geom/mirror/g_mirror.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index dd8c584..ff967f8 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -1907,6 +1907,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, boolean_t force) G_MIRROR_BUMP_ON_FIRST_WRITE; } } + wakeup(&g_mirror_class); break; } case G_MIRROR_DEVICE_STATE_RUNNING: @@ -2685,4 +2686,44 @@ g_mirror_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, } } +static int +g_mirror_can_go(void) +{ + struct g_mirror_softc *sc; + struct g_geom *gp; + struct g_provider *pp; + int can_go; + + DROP_GIANT(); + can_go = 1; + g_topology_lock(); + LIST_FOREACH(gp, &g_mirror_class.geom, geom) { + sc = gp->softc; + pp = sc->sc_provider; + if (pp == NULL || pp->error != 0) { + can_go = 0; + break; + } + } + g_topology_unlock(); + PICKUP_GIANT(); + return (can_go); +} + +static void +g_mirror_rootwait(void) +{ + + /* + * Wait for mirrors in degraded state. + */ + for (;;) { + if (g_mirror_can_go()) + break; + tsleep(&g_mirror_class, PRIBIO, "mroot", hz); + } +} + +SYSINIT(g_mirror_root, SI_SUB_RAID, SI_ORDER_FIRST, g_mirror_rootwait, NULL) + DECLARE_GEOM_CLASS(g_mirror_class, g_mirror); |