summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlaf Faaland <[email protected]>2018-08-20 10:05:23 -0700
committerBrian Behlendorf <[email protected]>2018-08-20 10:05:23 -0700
commit34fe773e303e499e6a6e5fcd2ceeee4531579dab (patch)
tree2871fe497c6ce4ee775411d13f8b5d011564e8bf
parentedc05fdb34792e65508ac2ff91c58828b44f19b1 (diff)
Skip import activity test in more zdb code paths
Since zdb opens the pools read-only, it cannot damage the pool in the event the pool is already imported either on the same host or on another one. If the pool vdev structure is changing while zdb is importing the pool, it may cause zdb to crash. However this is unlikely, and in any case it's a user space process and can simply be run again. For this reason, zdb should disable the multihost activity test on import that is normally run. This commit fixes a few zdb code paths where that had been overlooked. It also adds tests to ensure that several common use cases handle this properly in the future. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Gu Zheng <[email protected]> Signed-off-by: Olaf Faaland <[email protected]> Closes #7797 Closes #7801
-rw-r--r--cmd/zdb/zdb.c42
-rw-r--r--tests/runfiles/linux.run3
-rw-r--r--tests/zfs-tests/tests/functional/mmp/Makefile.am1
-rwxr-xr-xtests/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh81
4 files changed, 110 insertions, 17 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 142968d07..38ffbbece 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -24,7 +24,7 @@
* Copyright (c) 2011, 2017 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2016 Nexenta Systems, Inc.
- * Copyright (c) 2017 Lawrence Livermore National Security, LLC.
+ * Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC.
* Copyright (c) 2015, 2017, Intel Corporation.
*/
@@ -4558,6 +4558,22 @@ verify_device_removal_feature_counts(spa_t *spa)
return (ret);
}
+static void
+zdb_set_skip_mmp(char *target)
+{
+ spa_t *spa;
+
+ /*
+ * Disable the activity check to allow examination of
+ * active pools.
+ */
+ mutex_enter(&spa_namespace_lock);
+ if ((spa = spa_lookup(target)) != NULL) {
+ spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
+ }
+ mutex_exit(&spa_namespace_lock);
+}
+
#define BOGUS_SUFFIX "_CHECKPOINTED_UNIVERSE"
/*
* Import the checkpointed state of the pool specified by the target
@@ -4592,6 +4608,7 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
}
if (cfg == NULL) {
+ zdb_set_skip_mmp(poolname);
error = spa_get_stats(poolname, &cfg, NULL, 0);
if (error != 0) {
fatal("Tried to read config of pool \"%s\" but "
@@ -4605,7 +4622,8 @@ import_checkpointed_state(char *target, nvlist_t *cfg, char **new_path)
fnvlist_add_string(cfg, ZPOOL_CONFIG_POOL_NAME, bogus_name);
error = spa_import(bogus_name, cfg, NULL,
- ZFS_IMPORT_MISSING_LOG | ZFS_IMPORT_CHECKPOINT);
+ ZFS_IMPORT_MISSING_LOG | ZFS_IMPORT_CHECKPOINT |
+ ZFS_IMPORT_SKIP_MMP);
if (error != 0) {
fatal("Tried to import pool \"%s\" but spa_import() failed "
"with error %d\n", bogus_name, error);
@@ -5739,15 +5757,15 @@ main(int argc, char **argv)
target, strerror(ENOMEM));
}
- /*
- * Disable the activity check to allow examination of
- * active pools.
- */
if (dump_opt['C'] > 1) {
(void) printf("\nConfiguration for import:\n");
dump_nvlist(cfg, 8);
}
+ /*
+ * Disable the activity check to allow examination of
+ * active pools.
+ */
error = spa_import(target_pool, cfg, NULL,
flags | ZFS_IMPORT_SKIP_MMP);
}
@@ -5769,16 +5787,7 @@ main(int argc, char **argv)
}
} else if (target_is_spa || dump_opt['R']) {
- /*
- * Disable the activity check to allow examination of
- * active pools.
- */
- mutex_enter(&spa_namespace_lock);
- if ((spa = spa_lookup(target)) != NULL) {
- spa->spa_import_flags |= ZFS_IMPORT_SKIP_MMP;
- }
- mutex_exit(&spa_namespace_lock);
-
+ zdb_set_skip_mmp(target);
error = spa_open_rewind(target, &spa, FTAG, policy,
NULL);
if (error) {
@@ -5801,6 +5810,7 @@ main(int argc, char **argv)
}
}
} else {
+ zdb_set_skip_mmp(target);
error = open_objset(target, DMU_OST_ANY, FTAG, &os);
if (error == 0)
spa = dmu_objset_spa(os);
diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run
index 10c1200a4..445463cf8 100644
--- a/tests/runfiles/linux.run
+++ b/tests/runfiles/linux.run
@@ -597,7 +597,8 @@ tags = ['functional', 'mmap']
[tests/functional/mmp]
tests = ['mmp_on_thread', 'mmp_on_uberblocks', 'mmp_on_off', 'mmp_interval',
'mmp_active_import', 'mmp_inactive_import', 'mmp_exported_import',
- 'mmp_write_uberblocks', 'mmp_reset_interval', 'multihost_history']
+ 'mmp_write_uberblocks', 'mmp_reset_interval', 'multihost_history',
+ 'mmp_on_zdb']
tags = ['functional', 'mmp']
[tests/functional/mount]
diff --git a/tests/zfs-tests/tests/functional/mmp/Makefile.am b/tests/zfs-tests/tests/functional/mmp/Makefile.am
index ecf16f806..f2d0ad0ea 100644
--- a/tests/zfs-tests/tests/functional/mmp/Makefile.am
+++ b/tests/zfs-tests/tests/functional/mmp/Makefile.am
@@ -10,6 +10,7 @@ dist_pkgdata_SCRIPTS = \
mmp_exported_import.ksh \
mmp_write_uberblocks.ksh \
mmp_reset_interval.ksh \
+ mmp_on_zdb.ksh \
setup.ksh \
cleanup.ksh
diff --git a/tests/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh b/tests/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh
new file mode 100755
index 000000000..131fd21e8
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/mmp/mmp_on_zdb.ksh
@@ -0,0 +1,81 @@
+#!/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2018 Lawrence Livermore National Security, LLC.
+# Copyright (c) 2018 by Nutanix. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/mmp/mmp.cfg
+. $STF_SUITE/tests/functional/mmp/mmp.kshlib
+
+#
+# Description:
+# zdb will work while multihost is enabled.
+#
+# Strategy:
+# 1. Create a pool
+# 2. Enable multihost
+# 3. Run zdb -d with pool and dataset arguments.
+# 4. Create a checkpoint
+# 5. Run zdb -kd with pool and dataset arguments.
+# 6. Discard the checkpoint
+# 7. Export the pool
+# 8. Run zdb -ed with pool and dataset arguments.
+#
+
+function cleanup
+{
+ datasetexists $TESTPOOL && destroy_pool $TESTPOOL
+ for DISK in $DISKS; do
+ zpool labelclear -f $DEV_RDSKDIR/$DISK
+ done
+ log_must mmp_clear_hostid
+}
+
+log_assert "Verify zdb -d works while multihost is enabled"
+log_onexit cleanup
+
+verify_runnable "global"
+verify_disk_count "$DISKS" 2
+
+default_mirror_setup_noexit $DISKS
+log_must mmp_set_hostid $HOSTID1
+log_must zpool set multihost=on $TESTPOOL
+log_must zfs snap $TESTPOOL/$TESTFS@snap
+
+log_must zdb -d $TESTPOOL
+log_must zdb -d $TESTPOOL/
+log_must zdb -d $TESTPOOL/$TESTFS
+log_must zdb -d $TESTPOOL/$TESTFS@snap
+
+log_must zpool checkpoint $TESTPOOL
+log_must zdb -kd $TESTPOOL
+log_must zdb -kd $TESTPOOL/
+log_must zdb -kd $TESTPOOL/$TESTFS
+log_must zdb -kd $TESTPOOL/$TESTFS@snap
+log_must zpool checkpoint -d $TESTPOOL
+
+log_must zpool export $TESTPOOL
+
+log_must zdb -ed $TESTPOOL
+log_must zdb -ed $TESTPOOL/
+log_must zdb -ed $TESTPOOL/$TESTFS
+log_must zdb -ed $TESTPOOL/$TESTFS@snap
+
+log_must zpool import $TESTPOOL
+
+cleanup
+
+log_pass "zdb -d works while multihost is enabled"