aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zdb/zdb.c90
-rw-r--r--man/man8/zdb.811
-rwxr-xr-xtests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh2
3 files changed, 99 insertions, 4 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 18221c4b9..e8726915c 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -34,6 +34,7 @@
* Copyright (c) 2021 Allan Jude
* Copyright (c) 2021 Toomas Soome <[email protected]>
* Copyright (c) 2023, Klara Inc.
+ * Copyright (c) 2023, Rob Norris <[email protected]>
*/
#include <stdio.h>
@@ -80,6 +81,7 @@
#include <sys/dsl_scan.h>
#include <sys/btree.h>
#include <sys/brt.h>
+#include <sys/brt_impl.h>
#include <zfs_comutil.h>
#include <sys/zstd/zstd.h>
@@ -899,6 +901,8 @@ usage(void)
"don't print label contents\n");
(void) fprintf(stderr, " -t --txg=INTEGER "
"highest txg to use when searching for uberblocks\n");
+ (void) fprintf(stderr, " -T --brt-stats "
+ "BRT statistics\n");
(void) fprintf(stderr, " -u --uberblock "
"uberblock\n");
(void) fprintf(stderr, " -U --cachefile=PATH "
@@ -999,6 +1003,15 @@ zdb_nicenum(uint64_t num, char *buf, size_t buflen)
nicenum(num, buf, buflen);
}
+static void
+zdb_nicebytes(uint64_t bytes, char *buf, size_t buflen)
+{
+ if (dump_opt['P'])
+ (void) snprintf(buf, buflen, "%llu", (longlong_t)bytes);
+ else
+ zfs_nicebytes(bytes, buf, buflen);
+}
+
static const char histo_stars[] = "****************************************";
static const uint64_t histo_width = sizeof (histo_stars) - 1;
@@ -2082,6 +2095,76 @@ dump_all_ddts(spa_t *spa)
}
static void
+dump_brt(spa_t *spa)
+{
+ if (!spa_feature_is_enabled(spa, SPA_FEATURE_BLOCK_CLONING)) {
+ printf("BRT: unsupported on this pool\n");
+ return;
+ }
+
+ if (!spa_feature_is_active(spa, SPA_FEATURE_BLOCK_CLONING)) {
+ printf("BRT: empty\n");
+ return;
+ }
+
+ brt_t *brt = spa->spa_brt;
+ VERIFY(brt);
+
+ char count[32], used[32], saved[32];
+ zdb_nicebytes(brt_get_used(spa), used, sizeof (used));
+ zdb_nicebytes(brt_get_saved(spa), saved, sizeof (saved));
+ uint64_t ratio = brt_get_ratio(spa);
+ printf("BRT: used %s; saved %s; ratio %llu.%02llux\n", used, saved,
+ (u_longlong_t)(ratio / 100), (u_longlong_t)(ratio % 100));
+
+ if (dump_opt['T'] < 2)
+ return;
+
+ for (uint64_t vdevid = 0; vdevid < brt->brt_nvdevs; vdevid++) {
+ brt_vdev_t *brtvd = &brt->brt_vdevs[vdevid];
+ if (brtvd == NULL)
+ continue;
+
+ if (!brtvd->bv_initiated) {
+ printf("BRT: vdev %lu: empty\n", vdevid);
+ continue;
+ }
+
+ zdb_nicenum(brtvd->bv_totalcount, count, sizeof (count));
+ zdb_nicebytes(brtvd->bv_usedspace, used, sizeof (used));
+ zdb_nicebytes(brtvd->bv_savedspace, saved, sizeof (saved));
+ printf("BRT: vdev %lu: refcnt %s; used %s; saved %s\n",
+ vdevid, count, used, saved);
+ }
+
+ if (dump_opt['T'] < 3)
+ return;
+
+ char dva[64];
+ printf("\n%-16s %-10s\n", "DVA", "REFCNT");
+
+ for (uint64_t vdevid = 0; vdevid < brt->brt_nvdevs; vdevid++) {
+ brt_vdev_t *brtvd = &brt->brt_vdevs[vdevid];
+ if (brtvd == NULL || !brtvd->bv_initiated)
+ continue;
+
+ zap_cursor_t zc;
+ zap_attribute_t za;
+ for (zap_cursor_init(&zc, brt->brt_mos, brtvd->bv_mos_entries);
+ zap_cursor_retrieve(&zc, &za) == 0;
+ zap_cursor_advance(&zc)) {
+ uint64_t offset = *(uint64_t *)za.za_name;
+ uint64_t refcnt = za.za_first_integer;
+
+ snprintf(dva, sizeof (dva), "%lu:%llx", vdevid,
+ (u_longlong_t)offset);
+ printf("%-16s %-10llu\n", dva, (u_longlong_t)refcnt);
+ }
+ zap_cursor_fini(&zc);
+ }
+}
+
+static void
dump_dtl_seg(void *arg, uint64_t start, uint64_t size)
{
char *prefix = arg;
@@ -8108,6 +8191,9 @@ dump_zpool(spa_t *spa)
if (dump_opt['D'])
dump_all_ddts(spa);
+ if (dump_opt['T'])
+ dump_brt(spa);
+
if (dump_opt['d'] > 2 || dump_opt['m'])
dump_metaslabs(spa);
if (dump_opt['M'])
@@ -8894,6 +8980,7 @@ main(int argc, char **argv)
{"io-stats", no_argument, NULL, 's'},
{"simulate-dedup", no_argument, NULL, 'S'},
{"txg", required_argument, NULL, 't'},
+ {"brt-stats", no_argument, NULL, 'T'},
{"uberblock", no_argument, NULL, 'u'},
{"cachefile", required_argument, NULL, 'U'},
{"verbose", no_argument, NULL, 'v'},
@@ -8907,7 +8994,7 @@ main(int argc, char **argv)
};
while ((c = getopt_long(argc, argv,
- "AbBcCdDeEFGhiI:kK:lLmMNo:Op:PqrRsSt:uU:vVx:XYyZ",
+ "AbBcCdDeEFGhiI:kK:lLmMNo:Op:PqrRsSt:TuU:vVx:XYyZ",
long_options, NULL)) != -1) {
switch (c) {
case 'b':
@@ -8929,6 +9016,7 @@ main(int argc, char **argv)
case 'R':
case 's':
case 'S':
+ case 'T':
case 'u':
case 'y':
case 'Z':
diff --git a/man/man8/zdb.8 b/man/man8/zdb.8
index 52c8e452f..d7f66d917 100644
--- a/man/man8/zdb.8
+++ b/man/man8/zdb.8
@@ -14,7 +14,7 @@
.\" Copyright (c) 2017 Lawrence Livermore National Security, LLC.
.\" Copyright (c) 2017 Intel Corporation.
.\"
-.Dd June 27, 2023
+.Dd November 18, 2023
.Dt ZDB 8
.Os
.
@@ -23,7 +23,7 @@
.Nd display ZFS storage pool debugging and consistency information
.Sh SYNOPSIS
.Nm
-.Op Fl AbcdDFGhikLMNPsvXYy
+.Op Fl AbcdDFGhikLMNPsTvXYy
.Op Fl e Oo Fl V Oc Oo Fl p Ar path Oc Ns …
.Op Fl I Ar inflight-I/O-ops
.Oo Fl o Ar var Ns = Ns Ar value Oc Ns …
@@ -403,6 +403,13 @@ Display operation counts, bandwidth, and error counts of I/O to the pool from
Simulate the effects of deduplication, constructing a DDT and then display
that DDT as with
.Fl DD .
+.It Fl T , -brt-stats
+Display block reference table (BRT) statistics, including the size of uniques
+blocks cloned, the space saving as a result of cloning, and the saving ratio.
+.It Fl TT
+Display the per-vdev BRT statistics, including total references.
+.It Fl TTT
+Dump the contents of the block reference tables.
.It Fl u , -uberblock
Display the current uberblock.
.El
diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh
index 168e7c18c..688d488ce 100755
--- a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh
+++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_args_neg.ksh
@@ -58,7 +58,7 @@ set -A args "create" "add" "destroy" "import fakepool" \
"setvprop" "blah blah" "-%" "--?" "-*" "-=" \
"-a" "-f" "-g" "-j" "-n" "-o" "-p" "-p /tmp" \
"-t" "-w" "-z" "-E" "-H" "-I" "-J" \
- "-Q" "-R" "-T" "-W"
+ "-Q" "-R" "-W"
log_assert "Execute zdb using invalid parameters."