summaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorPaul Zuchowski <[email protected]>2020-01-16 12:22:49 -0500
committerBrian Behlendorf <[email protected]>2020-01-16 09:22:49 -0800
commitf12e42cccf31d6077f585a562d7e7ed3483291b1 (patch)
treeecee7b446e02d14363f1df499d133651f1b50dbf /cmd
parent1b64627e7335e9f38d66424cdd242b3d0889b060 (diff)
zdb -d should accept the numeric objset id
As an alternative to the dataset name, zdb now allows the decimal or hexadecimal objset ID to be specified. When permanent errors are reported as 2 hexadecimal numbers (objset ID : object ID) in zpool status; you can now use 'zdb <pool>[/objset ID] object' to determine the names of the objset and object which have the error. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Signed-off-by: Paul Zuchowski <[email protected]> Closes #9733
Diffstat (limited to 'cmd')
-rw-r--r--cmd/zdb/zdb.c80
1 files changed, 70 insertions, 10 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index c76076a39..825966555 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -26,7 +26,7 @@
* Copyright 2016 Nexenta Systems, Inc.
* Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC.
* Copyright (c) 2015, 2017, Intel Corporation.
- * Copyright (c) 2019 Datto Inc.
+ * Copyright (c) 2020 Datto Inc.
*/
#include <stdio.h>
@@ -144,9 +144,9 @@ usage(void)
"Usage:\t%s [-AbcdDFGhikLMPsvX] [-e [-V] [-p <path> ...]] "
"[-I <inflight I/Os>]\n"
"\t\t[-o <var>=<value>]... [-t <txg>] [-U <cache>] [-x <dumpdir>]\n"
- "\t\t[<poolname> [<object> ...]]\n"
- "\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>] <dataset>\n"
- "\t\t[<object> ...]\n"
+ "\t\t[<poolname>[/<dataset | objset id>] [<object> ...]]\n"
+ "\t%s [-AdiPv] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
+ "\t\t[<poolname>[/<dataset | objset id>] [<object> ...]\n"
"\t%s [-v] <bookmark>\n"
"\t%s -C [-A] [-U <cache>]\n"
"\t%s -l [-Aqu] <device>\n"
@@ -6335,6 +6335,26 @@ name:
return (NULL);
}
+static int
+name_from_objset_id(spa_t *spa, uint64_t objset_id, char *outstr)
+{
+ dsl_dataset_t *ds;
+
+ dsl_pool_config_enter(spa->spa_dsl_pool, FTAG);
+ int error = dsl_dataset_hold_obj(spa->spa_dsl_pool, objset_id,
+ NULL, &ds);
+ if (error != 0) {
+ (void) fprintf(stderr, "failed to hold objset %llu: %s\n",
+ (u_longlong_t)objset_id, strerror(error));
+ dsl_pool_config_exit(spa->spa_dsl_pool, FTAG);
+ return (error);
+ }
+ dsl_dataset_name(ds, outstr);
+ dsl_dataset_rele(ds, NULL);
+ dsl_pool_config_exit(spa->spa_dsl_pool, FTAG);
+ return (0);
+}
+
static boolean_t
zdb_parse_block_sizes(char *sizes, uint64_t *lsize, uint64_t *psize)
{
@@ -6713,13 +6733,14 @@ main(int argc, char **argv)
int error = 0;
char **searchdirs = NULL;
int nsearch = 0;
- char *target, *target_pool;
+ char *target, *target_pool, dsname[ZFS_MAX_DATASET_NAME_LEN];
nvlist_t *policy = NULL;
uint64_t max_txg = UINT64_MAX;
+ int64_t objset_id = -1;
int flags = ZFS_IMPORT_MISSING_LOG;
int rewind = ZPOOL_NEVER_REWIND;
- char *spa_config_path_env;
- boolean_t target_is_spa = B_TRUE;
+ char *spa_config_path_env, *objset_str;
+ boolean_t target_is_spa = B_TRUE, dataset_lookup = B_FALSE;
nvlist_t *cfg = NULL;
(void) setrlimit(RLIMIT_NOFILE, &rl);
@@ -6846,6 +6867,31 @@ main(int argc, char **argv)
(void) fprintf(stderr, "-p option requires use of -e\n");
usage();
}
+ if (dump_opt['d']) {
+ /* <pool>[/<dataset | objset id> is accepted */
+ if (argv[2] && (objset_str = strchr(argv[2], '/')) != NULL &&
+ objset_str++ != NULL) {
+ char *endptr;
+ errno = 0;
+ objset_id = strtoull(objset_str, &endptr, 0);
+ /* dataset 0 is the same as opening the pool */
+ if (errno == 0 && endptr != objset_str &&
+ objset_id != 0) {
+ target_is_spa = B_FALSE;
+ dataset_lookup = B_TRUE;
+ } else if (objset_id != 0) {
+ printf("failed to open objset %s "
+ "%llu %s", objset_str,
+ (u_longlong_t)objset_id,
+ strerror(errno));
+ exit(1);
+ }
+ /* normal dataset name not an objset ID */
+ if (endptr == objset_str) {
+ objset_id = -1;
+ }
+ }
+ }
#if defined(_LP64)
/*
@@ -6890,7 +6936,6 @@ main(int argc, char **argv)
argc -= optind;
argv += optind;
-
if (argc < 2 && dump_opt['R'])
usage();
@@ -7010,7 +7055,7 @@ main(int argc, char **argv)
checkpoint_pool, error);
}
- } else if (target_is_spa || dump_opt['R']) {
+ } else if (target_is_spa || dump_opt['R'] || objset_id == 0) {
zdb_set_skip_mmp(target);
error = spa_open_rewind(target, &spa, FTAG, policy,
NULL);
@@ -7049,7 +7094,22 @@ main(int argc, char **argv)
return (error);
} else {
zdb_set_skip_mmp(target);
- error = open_objset(target, FTAG, &os);
+ if (dataset_lookup == B_TRUE) {
+ /*
+ * Use the supplied id to get the name
+ * for open_objset.
+ */
+ error = spa_open(target, &spa, FTAG);
+ if (error == 0) {
+ error = name_from_objset_id(spa,
+ objset_id, dsname);
+ spa_close(spa, FTAG);
+ if (error == 0)
+ target = dsname;
+ }
+ }
+ if (error == 0)
+ error = open_objset(target, FTAG, &os);
if (error == 0)
spa = dmu_objset_spa(os);
}