Revert r341665 due to tinderbox breakage
I didn't notice that some format strings were non-portable. Will fix and re-commit later.
This commit is contained in:
parent
a9ebbf33ea
commit
c4e87bdfc1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=341672
@ -59,11 +59,6 @@ static SYSCTL_NODE(_kern_geom, OID_AUTO, mirror, CTLFLAG_RW, 0,
|
||||
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 *disk, u_int state);
|
||||
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_provider *pp,
|
||||
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 force)
|
||||
case G_MIRROR_DEVICE_STATE_STARTING:
|
||||
{
|
||||
struct g_mirror_disk *pdisk, *tdisk;
|
||||
const char *mismatch;
|
||||
uintmax_t found, newest;
|
||||
u_int dirty, ndisks;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
u_int dirty, ndisks, genid, syncid;
|
||||
bool broken;
|
||||
|
||||
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) {
|
||||
/*
|
||||
@ -2487,6 +2419,42 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool force)
|
||||
callout_drain(&sc->sc_callout);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -2500,7 +2468,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool force)
|
||||
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 force)
|
||||
"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 force)
|
||||
* 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 force)
|
||||
|
||||
/* 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, struct g_provider *pp,
|
||||
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_provider *pp,
|
||||
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 @@ g_mirror_access(struct g_provider *pp, int acr, int acw, int ace)
|
||||
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_mirror_metadata *md,
|
||||
|
||||
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;
|
||||
@ -3521,51 +3484,5 @@ g_mirror_fini(struct g_class *mp)
|
||||
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);
|
||||
MODULE_VERSION(geom_mirror, 0);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -1,133 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
atf_test_case run_latest_genid cleanup
|
||||
run_latest_genid_head()
|
||||
{
|
||||
atf_set "descr" \
|
||||
"Ensure that we properly select components (latest genid) during STARTING."
|
||||
atf_set "require.user" "root"
|
||||
}
|
||||
run_latest_genid_body()
|
||||
{
|
||||
. $(atf_get_srcdir)/conf.sh
|
||||
|
||||
f1=$(mktemp ${base}.XXXXXX)
|
||||
f2=$(mktemp ${base}.XXXXXX)
|
||||
f3=$(mktemp ${base}.XXXXXX)
|
||||
rnd1=$(mktemp ${base}.XXXXXX)
|
||||
rnd2=$(mktemp ${base}.XXXXXX)
|
||||
|
||||
atf_check truncate -s 2M $f1
|
||||
atf_check truncate -s 2M $f2
|
||||
atf_check truncate -s 2M $f3
|
||||
dd if=/dev/urandom bs=512 count=1 of="$rnd1"
|
||||
dd if=/dev/urandom bs=512 count=1 of="$rnd2"
|
||||
|
||||
md1=$(attach_md -t vnode -f ${f1})
|
||||
md2=$(attach_md -t vnode -f ${f2})
|
||||
md3=$(attach_md -t vnode -f ${f3})
|
||||
|
||||
# Use a gnop for md1 just for consistency; it's not used for anything.
|
||||
atf_check gnop create $md1
|
||||
atf_check gnop create $md2
|
||||
atf_check gnop create $md3
|
||||
# Hardcode component names so that the non-.nop device isn't tasted
|
||||
# instead.
|
||||
atf_check gmirror label -h $name ${md1}.nop
|
||||
devwait
|
||||
|
||||
atf_check gmirror insert -h $name ${md2}.nop
|
||||
atf_check gmirror insert -h $name ${md3}.nop
|
||||
syncwait
|
||||
|
||||
# Fail mirror 3, writing known contents to mirror 1+2 block 1
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
gnop configure -w 100 ${md3}.nop
|
||||
atf_check -s exit:0 dd if="$rnd1" bs=512 count=1 oseek=1 conv=notrunc \
|
||||
of=/dev/mirror/$name status=none
|
||||
|
||||
disconnectwait nop "${md3}.nop"
|
||||
|
||||
# Should have two mirrors remaining after md3 was evicted
|
||||
atf_check [ $(gmirror status -s $name | wc -l) -eq 2 ]
|
||||
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
|
||||
gmirror status -s $name
|
||||
atf_check -s exit:0 -o match:"DEGRADED ${md2}.nop \(ACTIVE\)" \
|
||||
gmirror status -s $name
|
||||
|
||||
# Repeat:
|
||||
# Fail mirror 2, writing known contents to mirror 1 block 2
|
||||
atf_check -s exit:0 -e empty -o empty \
|
||||
gnop configure -w 100 ${md2}.nop
|
||||
atf_check -s exit:0 dd if="$rnd2" bs=512 count=2 oseek=1 conv=notrunc \
|
||||
of=/dev/mirror/$name status=none
|
||||
|
||||
disconnectwait nop "${md2}.nop"
|
||||
|
||||
# Should have one mirror remaining after md2 was evicted
|
||||
atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
|
||||
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
|
||||
gmirror status -s $name
|
||||
|
||||
# Stop the mirror and remove the pieces so gmirror can't see them.
|
||||
atf_check gmirror stop $name
|
||||
atf_check gnop destroy ${md1}.nop
|
||||
atf_check gnop destroy ${md2}.nop
|
||||
atf_check gnop destroy ${md3}.nop
|
||||
|
||||
# Rebuild; spin up "disk" with lowest genid
|
||||
atf_check gnop create $md3
|
||||
md3gen=$(gmirror dump /dev/${md3}.nop | grep genid | cut -d: -f2)
|
||||
# Assert gmirror is referencing this component for now:
|
||||
atf_check [ $(consumerrefs nop ${md3}.nop) = "r1w1e1" ]
|
||||
|
||||
# Adding newer genid should kick out old component
|
||||
atf_check gnop create $md2
|
||||
md2gen=$(gmirror dump /dev/${md2}.nop | grep genid | cut -d: -f2)
|
||||
atf_check [ $md2gen -gt $md3gen ]
|
||||
|
||||
disconnectwait nop "${md3}.nop"
|
||||
|
||||
# Can't test this because 'status' doesn't exist until RUNNING:
|
||||
#atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
|
||||
# But as a substitute, assert gmirror has dropped reference to staler
|
||||
# component in favor of newer component:
|
||||
atf_check [ $(consumerrefs nop ${md2}.nop) = "r1w1e1" ]
|
||||
|
||||
# ditto
|
||||
atf_check gnop create $md1
|
||||
md1gen=$(gmirror dump /dev/${md1}.nop | grep genid | cut -d: -f2)
|
||||
atf_check [ $md1gen -gt $md2gen ]
|
||||
|
||||
disconnectwait nop "${md2}.nop"
|
||||
|
||||
# Assert gmirror has dropped reference to stale component in favor of
|
||||
# newer component:
|
||||
atf_check [ $(consumerrefs nop ${md1}.nop) = "r1w1e1" ]
|
||||
|
||||
# gmirror won't start the mirror automatically with only one component
|
||||
# ($md0) of configured three, so this waits out the
|
||||
# kern.geom.mirror.timeout:
|
||||
devwait
|
||||
|
||||
atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
|
||||
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
|
||||
gmirror status -s $name
|
||||
}
|
||||
run_latest_genid_cleanup()
|
||||
{
|
||||
. $(atf_get_srcdir)/conf.sh
|
||||
|
||||
if [ -f "$TEST_MDS_FILE" ]; then
|
||||
while read test_md; do
|
||||
echo "# Removing test gnop: ${test_md}.nop"
|
||||
gnop destroy -f "${test_md}.nop" 2>/dev/null || :
|
||||
done < "$TEST_MDS_FILE"
|
||||
fi
|
||||
gmirror_test_cleanup
|
||||
}
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case run_latest_genid
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user