mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-11-04 03:24:44 +00:00 
			
		
		
		
	zdb: show BRT statistics and dump its contents
Same idea as the dedup stats, but for block cloning. Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Kay Pedersen <mail@mkwg.de> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <robn@despairlabs.com> Closes #15541
This commit is contained in:
		
							parent
							
								
									803a9c12c9
								
							
						
					
					
						commit
						213d682967
					
				@ -34,6 +34,7 @@
 | 
			
		||||
 * Copyright (c) 2021 Allan Jude
 | 
			
		||||
 * Copyright (c) 2021 Toomas Soome <tsoome@me.com>
 | 
			
		||||
 * Copyright (c) 2023, Klara Inc.
 | 
			
		||||
 * Copyright (c) 2023, Rob Norris <robn@despairlabs.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
 | 
			
		||||
@ -2081,6 +2094,76 @@ dump_all_ddts(spa_t *spa)
 | 
			
		||||
	dump_dedup_ratio(&dds_total);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
@ -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':
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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."
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user