svn commit: r341672 - in head: sys/geom/mirror tests/sys/geom/class/mirror
Conrad Meyer
cem at FreeBSD.org
Fri Dec 7 00:47:07 UTC 2018
Author: cem
Date: Fri Dec 7 00:47:05 2018
New Revision: 341672
URL: https://svnweb.freebsd.org/changeset/base/341672
Log:
Revert r341665 due to tinderbox breakage
I didn't notice that some format strings were non-portable. Will fix and
re-commit later.
Deleted:
head/tests/sys/geom/class/mirror/component_selection.sh
Modified:
head/sys/geom/mirror/g_mirror.c
head/sys/geom/mirror/g_mirror.h
head/tests/sys/geom/class/mirror/Makefile
head/tests/sys/geom/class/mirror/conf.sh
Modified: head/sys/geom/mirror/g_mirror.c
==============================================================================
--- head/sys/geom/mirror/g_mirror.c Fri Dec 7 00:39:34 2018 (r341671)
+++ head/sys/geom/mirror/g_mirror.c Fri Dec 7 00:47:05 2018 (r341672)
@@ -59,11 +59,6 @@ static SYSCTL_NODE(_kern_geom, OID_AUTO, mirror, CTLFL
int g_mirror_debug = 0;
SYSCTL_INT(_kern_geom_mirror, OID_AUTO, debug, CTLFLAG_RWTUN, &g_mirror_debug, 0,
"Debug level");
-bool g_launch_mirror_before_timeout = true;
-SYSCTL_BOOL(_kern_geom_mirror, OID_AUTO, launch_mirror_before_timeout,
- CTLFLAG_RWTUN, &g_launch_mirror_before_timeout, 0,
- "If false, force gmirror to wait out the full kern.geom.mirror.timeout "
- "before launching mirrors");
static u_int g_mirror_timeout = 4;
SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, timeout, CTLFLAG_RWTUN, &g_mirror_timeout,
0, "Time to wait on all mirror components");
@@ -115,8 +110,6 @@ static int g_mirror_update_disk(struct g_mirror_disk *
static void g_mirror_update_device(struct g_mirror_softc *sc, bool force);
static void g_mirror_dumpconf(struct sbuf *sb, const char *indent,
struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp);
-static int g_mirror_refresh_device(struct g_mirror_softc *sc,
- const struct g_provider *pp, const struct g_mirror_metadata *md);
static void g_mirror_sync_reinit(const struct g_mirror_disk *disk,
struct bio *bp, off_t offset);
static void g_mirror_sync_stop(struct g_mirror_disk *disk, int type);
@@ -479,10 +472,6 @@ g_mirror_init_disk(struct g_mirror_softc *sc, struct g
disk->d_sync.ds_update_ts = time_uptime;
disk->d_genid = md->md_genid;
disk->d_sync.ds_syncid = md->md_syncid;
- disk->d_init_ndisks = md->md_all;
- disk->d_init_slice = md->md_slice;
- disk->d_init_balance = md->md_balance;
- disk->d_init_mediasize = md->md_mediasize;
if (errorp != NULL)
*errorp = 0;
return (disk);
@@ -2373,74 +2362,17 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
case G_MIRROR_DEVICE_STATE_STARTING:
{
struct g_mirror_disk *pdisk, *tdisk;
- const char *mismatch;
- uintmax_t found, newest;
- u_int dirty, ndisks;
+ u_int dirty, ndisks, genid, syncid;
+ bool broken;
- /* Pre-flight checks */
- LIST_FOREACH_SAFE(disk, &sc->sc_disks, d_next, tdisk) {
- /*
- * Confirm we already detected the newest genid.
- */
- KASSERT(sc->sc_genid >= disk->d_genid,
- ("%s: found newer genid %u (sc:%p had %u).", __func__,
- disk->d_genid, sc, sc->sc_genid));
-
- /* Kick out any previously tasted stale components. */
- if (disk->d_genid < sc->sc_genid) {
- G_MIRROR_DEBUG(0, "Stale 'genid' field on %s "
- "(device %s) (component=%u latest=%u), skipping.",
- g_mirror_get_diskname(disk), sc->sc_name,
- disk->d_genid, sc->sc_genid);
- g_mirror_destroy_disk(disk);
- sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID;
- continue;
- }
-
- /*
- * Confirm we already detected the newest syncid.
- */
- KASSERT(sc->sc_syncid >= disk->d_sync.ds_syncid,
- ("%s: found newer syncid %u (sc:%p had %u).",
- __func__, disk->d_sync.ds_syncid, sc,
- sc->sc_syncid));
-
-#define DETECT_MISMATCH(field, name) \
- if (mismatch == NULL && \
- disk->d_init_ ## field != sc->sc_ ## field) { \
- mismatch = name; \
- found = (intmax_t)disk->d_init_ ## field; \
- newest = (intmax_t)sc->sc_ ## field; \
- }
- mismatch = NULL;
- DETECT_MISMATCH(ndisks, "md_all");
- DETECT_MISMATCH(balance, "md_balance");
- DETECT_MISMATCH(slice, "md_slice");
- DETECT_MISMATCH(mediasize, "md_mediasize");
-#undef DETECT_MISMATCH
- if (mismatch != NULL) {
- G_MIRROR_DEBUG(0, "Found a mismatching '%s' "
- "field on %s (device %s) (found=%ju "
- "newest=%ju).", mismatch,
- g_mirror_get_diskname(disk), sc->sc_name,
- found, newest);
- g_mirror_destroy_disk(disk);
- sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID;
- continue;
- }
- }
-
KASSERT(sc->sc_provider == NULL,
("Non-NULL provider in STARTING state (%s).", sc->sc_name));
/*
- * Are we ready? If the timeout (force is true) has expired, and
- * any disks are present, then yes. If we're permitted to launch
- * before the timeout has expired and the expected number of
- * current-generation mirror disks have been tasted, then yes.
+ * Are we ready? We are, if all disks are connected or
+ * if we have any disks and 'force' is true.
*/
ndisks = g_mirror_ndisks(sc, -1);
- if ((force && ndisks > 0) ||
- (g_launch_mirror_before_timeout && ndisks == sc->sc_ndisks)) {
+ if (sc->sc_ndisks == ndisks || (force && ndisks > 0)) {
;
} else if (ndisks == 0) {
/*
@@ -2488,6 +2420,42 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
}
/*
+ * Find the biggest genid.
+ */
+ genid = 0;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_genid > genid)
+ genid = disk->d_genid;
+ }
+ sc->sc_genid = genid;
+ /*
+ * Remove all disks without the biggest genid.
+ */
+ broken = false;
+ LIST_FOREACH_SAFE(disk, &sc->sc_disks, d_next, tdisk) {
+ if (disk->d_genid < genid) {
+ G_MIRROR_DEBUG(0,
+ "Component %s (device %s) broken, skipping.",
+ g_mirror_get_diskname(disk), sc->sc_name);
+ g_mirror_destroy_disk(disk);
+ /*
+ * Bump the syncid in case we discover a healthy
+ * replacement disk after starting the mirror.
+ */
+ broken = true;
+ }
+ }
+
+ /*
+ * Find the biggest syncid.
+ */
+ syncid = 0;
+ LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+ if (disk->d_sync.ds_syncid > syncid)
+ syncid = disk->d_sync.ds_syncid;
+ }
+
+ /*
* Here we need to look for dirty disks and if all disks
* with the biggest syncid are dirty, we have to choose
* one with the biggest priority and rebuild the rest.
@@ -2500,7 +2468,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
dirty = ndisks = 0;
pdisk = NULL;
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
- if (disk->d_sync.ds_syncid != sc->sc_syncid)
+ if (disk->d_sync.ds_syncid != syncid)
continue;
if ((disk->d_flags &
G_MIRROR_DISK_FLAG_SYNCHRONIZING) != 0) {
@@ -2527,7 +2495,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
"master disk for synchronization.",
g_mirror_get_diskname(pdisk), sc->sc_name);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
- if (disk->d_sync.ds_syncid != sc->sc_syncid)
+ if (disk->d_sync.ds_syncid != syncid)
continue;
if ((disk->d_flags &
G_MIRROR_DISK_FLAG_SYNCHRONIZING) != 0) {
@@ -2548,7 +2516,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
* We have some non-dirty disks.
*/
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
- if (disk->d_sync.ds_syncid != sc->sc_syncid)
+ if (disk->d_sync.ds_syncid != syncid)
continue;
if ((disk->d_flags &
G_MIRROR_DISK_FLAG_SYNCHRONIZING) != 0) {
@@ -2564,7 +2532,8 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool
/* Reset hint. */
sc->sc_hint = NULL;
- if (force) {
+ sc->sc_syncid = syncid;
+ if (force || broken) {
/* Remember to bump syncid on first write. */
sc->sc_bump_id |= G_MIRROR_BUMP_SYNCID;
}
@@ -2901,23 +2870,37 @@ g_mirror_check_metadata(struct g_mirror_softc *sc, str
struct g_mirror_metadata *md)
{
- G_MIRROR_DEBUG(2, "%s: md_did 0x%u disk %s device %s md_all 0x%x "
- "sc_ndisks 0x%x md_slice 0x%x sc_slice 0x%x md_balance 0x%x "
- "sc_balance 0x%x sc_mediasize 0x%lx pp_mediasize 0x%lx "
- "md_sectorsize 0x%x sc_sectorsize 0x%x md_mflags 0x%lx "
- "md_dflags 0x%lx md_syncid 0x%x md_genid 0x%x md_priority 0x%x "
- "sc_state 0x%x.",
- __func__, md->md_did, pp->name, sc->sc_name, md->md_all,
- sc->sc_ndisks, md->md_slice, sc->sc_slice, md->md_balance,
- sc->sc_balance, sc->sc_mediasize, pp->mediasize, md->md_sectorsize,
- sc->sc_sectorsize, md->md_mflags, md->md_dflags, md->md_syncid,
- md->md_genid, md->md_priority, sc->sc_state);
-
if (g_mirror_id2disk(sc, md->md_did) != NULL) {
G_MIRROR_DEBUG(1, "Disk %s (id=%u) already exists, skipping.",
pp->name, md->md_did);
return (EEXIST);
}
+ if (md->md_all != sc->sc_ndisks) {
+ G_MIRROR_DEBUG(1,
+ "Invalid '%s' field on disk %s (device %s), skipping.",
+ "md_all", pp->name, sc->sc_name);
+ return (EINVAL);
+ }
+ if (md->md_slice != sc->sc_slice) {
+ G_MIRROR_DEBUG(1,
+ "Invalid '%s' field on disk %s (device %s), skipping.",
+ "md_slice", pp->name, sc->sc_name);
+ return (EINVAL);
+ }
+ if (md->md_balance != sc->sc_balance) {
+ G_MIRROR_DEBUG(1,
+ "Invalid '%s' field on disk %s (device %s), skipping.",
+ "md_balance", pp->name, sc->sc_name);
+ return (EINVAL);
+ }
+#if 0
+ if (md->md_mediasize != sc->sc_mediasize) {
+ G_MIRROR_DEBUG(1,
+ "Invalid '%s' field on disk %s (device %s), skipping.",
+ "md_mediasize", pp->name, sc->sc_name);
+ return (EINVAL);
+ }
+#endif
if (sc->sc_mediasize > pp->mediasize) {
G_MIRROR_DEBUG(1,
"Invalid size of disk %s (device %s), skipping.", pp->name,
@@ -2964,21 +2947,12 @@ g_mirror_add_disk(struct g_mirror_softc *sc, struct g_
error = g_mirror_check_metadata(sc, pp, md);
if (error != 0)
return (error);
-
- if (md->md_genid < sc->sc_genid) {
+ if (sc->sc_state == G_MIRROR_DEVICE_STATE_RUNNING &&
+ md->md_genid < sc->sc_genid) {
G_MIRROR_DEBUG(0, "Component %s (device %s) broken, skipping.",
pp->name, sc->sc_name);
return (EINVAL);
}
-
- /*
- * If the component disk we're tasting has newer metadata than the
- * STARTING gmirror device, refresh the device from the component.
- */
- error = g_mirror_refresh_device(sc, pp, md);
- if (error != 0)
- return (error);
-
disk = g_mirror_init_disk(sc, pp, md, &error);
if (disk == NULL)
return (error);
@@ -3055,21 +3029,6 @@ end:
return (error);
}
-static void
-g_mirror_reinit_from_metadata(struct g_mirror_softc *sc,
- const struct g_mirror_metadata *md)
-{
-
- sc->sc_genid = md->md_genid;
- sc->sc_syncid = md->md_syncid;
-
- sc->sc_slice = md->md_slice;
- sc->sc_balance = md->md_balance;
- sc->sc_mediasize = md->md_mediasize;
- sc->sc_ndisks = md->md_all;
- sc->sc_flags = md->md_mflags;
-}
-
struct g_geom *
g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md,
u_int type)
@@ -3097,8 +3056,12 @@ g_mirror_create(struct g_class *mp, const struct g_mir
sc->sc_type = type;
sc->sc_id = md->md_mid;
- g_mirror_reinit_from_metadata(sc, md);
+ sc->sc_slice = md->md_slice;
+ sc->sc_balance = md->md_balance;
+ sc->sc_mediasize = md->md_mediasize;
sc->sc_sectorsize = md->md_sectorsize;
+ sc->sc_ndisks = md->md_all;
+ sc->sc_flags = md->md_mflags;
sc->sc_bump_id = 0;
sc->sc_idle = 1;
sc->sc_last_write = time_uptime;
@@ -3519,52 +3482,6 @@ g_mirror_fini(struct g_class *mp)
if (g_mirror_post_sync != NULL)
EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_mirror_post_sync);
-}
-
-/*
- * Refresh the mirror device's metadata when gmirror encounters a newer
- * generation as the individual components are being added to the mirror set.
- */
-static int
-g_mirror_refresh_device(struct g_mirror_softc *sc, const struct g_provider *pp,
- const struct g_mirror_metadata *md)
-{
-
- g_topology_assert_not();
- sx_assert(&sc->sc_lock, SX_XLOCKED);
-
- KASSERT(sc->sc_genid <= md->md_genid,
- ("%s: attempted to refresh from stale component %s (device %s) "
- "(%u < %u).", __func__, pp->name, sc->sc_name, md->md_genid,
- sc->sc_genid));
-
- if (sc->sc_genid > md->md_genid || (sc->sc_genid == md->md_genid &&
- sc->sc_syncid >= md->md_syncid))
- return (0);
-
- G_MIRROR_DEBUG(0, "Found newer version for device %s (genid: curr=%u "
- "new=%u; syncid: curr=%u new=%u; ndisks: curr=%u new=%u; "
- "provider=%s).", sc->sc_name, sc->sc_genid, md->md_genid,
- sc->sc_syncid, md->md_syncid, sc->sc_ndisks, md->md_all, pp->name);
-
- if (sc->sc_state != G_MIRROR_DEVICE_STATE_STARTING) {
- /* Probable data corruption detected */
- G_MIRROR_DEBUG(0, "Cannot refresh metadata in %s state "
- "(device=%s genid=%u). A stale mirror device was launched.",
- g_mirror_device_state2str(sc->sc_state), sc->sc_name,
- sc->sc_genid);
- return (EINVAL);
- }
-
- /* Update softc */
- g_mirror_reinit_from_metadata(sc, md);
-
- G_MIRROR_DEBUG(1, "Refresh device %s (id=%u, state=%s) from disk %s "
- "(genid=%u syncid=%u md_all=%u).", sc->sc_name, md->md_mid,
- g_mirror_device_state2str(sc->sc_state), pp->name, md->md_genid,
- md->md_syncid, (unsigned)md->md_all);
-
- return (0);
}
DECLARE_GEOM_CLASS(g_mirror_class, g_mirror);
Modified: head/sys/geom/mirror/g_mirror.h
==============================================================================
--- head/sys/geom/mirror/g_mirror.h Fri Dec 7 00:39:34 2018 (r341671)
+++ head/sys/geom/mirror/g_mirror.h Fri Dec 7 00:47:05 2018 (r341672)
@@ -148,10 +148,6 @@ struct g_mirror_disk {
u_int d_genid; /* Disk's generation ID. */
struct g_mirror_disk_sync d_sync;/* Sync information. */
LIST_ENTRY(g_mirror_disk) d_next;
- u_int d_init_ndisks; /* Initial number of mirror components */
- uint32_t d_init_slice; /* Initial slice size */
- uint8_t d_init_balance;/* Initial balance */
- uint64_t d_init_mediasize;/* Initial mediasize */
};
#define d_name d_consumer->provider->name
Modified: head/tests/sys/geom/class/mirror/Makefile
==============================================================================
--- head/tests/sys/geom/class/mirror/Makefile Fri Dec 7 00:39:34 2018 (r341671)
+++ head/tests/sys/geom/class/mirror/Makefile Fri Dec 7 00:47:05 2018 (r341672)
@@ -18,7 +18,6 @@ TAP_TESTS_SH+= 11_test
TAP_TESTS_SH+= 12_test
TAP_TESTS_SH+= 13_test
-ATF_TESTS_SH+= component_selection
ATF_TESTS_SH+= sync_error
${PACKAGE}FILES+= conf.sh
Modified: head/tests/sys/geom/class/mirror/conf.sh
==============================================================================
--- head/tests/sys/geom/class/mirror/conf.sh Fri Dec 7 00:39:34 2018 (r341671)
+++ head/tests/sys/geom/class/mirror/conf.sh Fri Dec 7 00:47:05 2018 (r341672)
@@ -19,35 +19,4 @@ syncwait()
done
}
-consumerrefs()
-{
- gclass=$1
- geom=$2
-
- if [ $# -ne 2 ]; then
- echo "Bad usage consumerrefs" >&2
- exit 1
- fi
-
- geom "${gclass}" list "${geom}" | \
- grep -A5 ^Consumers | \
- grep Mode | \
- cut -d: -f2
-}
-
-disconnectwait()
-{
- gclass=$1
- geom=$2
-
- if [ $# -ne 2 ]; then
- echo "Bad usage disconnectwait" >&2
- exit 1
- fi
-
- while [ $(consumerrefs "$gclass" "$geom") != r0w0e0 ]; do
- sleep 0.05
- done
-}
-
. `dirname $0`/../geom_subr.sh
More information about the svn-src-all
mailing list