zdb: add --class=(normal|special|...) to filter blocks by alloc class

When counting blocks to generate block size histograms (`-bb`), accept a
`--class=` argument (as a comma-separated list of either "normal",
"special", "dedup" or "other") to only consider blocks that belong to
these metaslab classes.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
This commit is contained in:
Ivan Shapovalov 2024-12-10 17:12:53 +04:00 committed by Tony Hutter
parent 627b530059
commit 968cfc3df2
2 changed files with 104 additions and 0 deletions

View File

@ -109,6 +109,7 @@ extern uint_t zfs_btree_verify_intensity;
enum {
ARG_ALLOCATED = 256,
ARG_BLOCK_BIN_MODE,
ARG_BLOCK_CLASSES,
};
static const char cmdname[] = "zdb";
@ -141,6 +142,13 @@ static enum {
BIN_ASIZE,
} block_bin_mode = BIN_AUTO;
static enum {
CLASS_NORMAL = 1 << 1,
CLASS_SPECIAL = 1 << 2,
CLASS_DEDUP = 1 << 3,
CLASS_OTHER = 1 << 4,
} block_classes = 0;
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
static void mos_obj_refd(uint64_t);
@ -761,6 +769,10 @@ usage(void)
"block statistics\n");
(void) fprintf(stderr, " --bin=(lsize|psize|asize) "
"bin blocks based on this size in all three columns\n");
(void) fprintf(stderr,
" --class=(normal|special|dedup|other)[,...]\n"
" only consider blocks from "
"these allocation classes\n");
(void) fprintf(stderr, " -B --backup "
"backup stream\n");
(void) fprintf(stderr, " -c --checksum "
@ -5840,6 +5852,20 @@ dump_size_histograms(zdb_cb_t *zcb)
printf("(note: all categories are binned separately)\n");
break;
}
if (block_classes != 0) {
char buf[256] = "";
if (block_classes & CLASS_NORMAL)
strlcat(buf, "\"normal\", ", sizeof (buf));
if (block_classes & CLASS_SPECIAL)
strlcat(buf, "\"special\", ", sizeof (buf));
if (block_classes & CLASS_DEDUP)
strlcat(buf, "\"dedup\", ", sizeof (buf));
if (block_classes & CLASS_OTHER)
strlcat(buf, "\"other\", ", sizeof (buf));
buf[strlen(buf)-2] = '\0';
printf("(note: only blocks in these classes are counted: %s)\n",
buf);
}
/*
* Print the first line titles
*/
@ -6189,6 +6215,38 @@ skipped:
return;
}
if (block_classes != 0) {
spa_config_enter(zcb->zcb_spa, SCL_CONFIG, FTAG, RW_READER);
uint64_t vdev = DVA_GET_VDEV(&bp->blk_dva[0]);
uint64_t offset = DVA_GET_OFFSET(&bp->blk_dva[0]);
vdev_t *vd = vdev_lookup_top(zcb->zcb_spa, vdev);
ASSERT(vd != NULL);
metaslab_t *ms = vd->vdev_ms[offset >> vd->vdev_ms_shift];
ASSERT(ms != NULL);
metaslab_group_t *mg = ms->ms_group;
ASSERT(mg != NULL);
metaslab_class_t *mc = mg->mg_class;
ASSERT(mc != NULL);
spa_config_exit(zcb->zcb_spa, SCL_CONFIG, FTAG);
int class;
if (mc == spa_normal_class(zcb->zcb_spa)) {
class = CLASS_NORMAL;
} else if (mc == spa_special_class(zcb->zcb_spa)) {
class = CLASS_SPECIAL;
} else if (mc == spa_dedup_class(zcb->zcb_spa)) {
class = CLASS_DEDUP;
} else {
class = CLASS_OTHER;
}
if (!(block_classes & class)) {
goto hist_skipped;
}
}
/*
* The binning histogram bins by powers of two up to
* SPA_MAXBLOCKSIZE rather than creating bins for
@ -6225,6 +6283,7 @@ skipped:
zcb->zcb_asize_len[bin] += BP_GET_ASIZE(bp);
zcb->zcb_asize_total += BP_GET_ASIZE(bp);
hist_skipped:
if (!do_claim)
return;
@ -9469,6 +9528,8 @@ main(int argc, char **argv)
ARG_ALLOCATED},
{"bin", required_argument, NULL,
ARG_BLOCK_BIN_MODE},
{"class", required_argument, NULL,
ARG_BLOCK_CLASSES},
{0, 0, 0, 0}
};
@ -9596,6 +9657,45 @@ main(int argc, char **argv)
usage();
}
break;
case ARG_BLOCK_CLASSES: {
char *buf = strdup(optarg), *tok = buf, *next,
*save = NULL;
while ((next = strtok_r(tok, ",", &save)) != NULL) {
tok = NULL;
if (strcmp(next, "normal") == 0) {
block_classes |= CLASS_NORMAL;
} else if (strcmp(next, "special") == 0) {
block_classes |= CLASS_SPECIAL;
} else if (strcmp(next, "dedup") == 0) {
block_classes |= CLASS_DEDUP;
} else if (strcmp(next, "other") == 0) {
block_classes |= CLASS_OTHER;
} else {
(void) fprintf(stderr,
"--class=\"%s\" must be a "
"comma-separated list of either "
"\"normal\", \"special\", "
"\"asize\" or \"other\"; "
"got \"%s\"\n",
optarg, next);
usage();
}
}
if (block_classes == 0) {
(void) fprintf(stderr,
"--class= must be a comma-separated "
"list of either \"normal\", \"special\", "
"\"asize\" or \"other\"; got empty\n");
usage();
}
free(buf);
break;
}
default:
usage();
break;

View File

@ -154,6 +154,10 @@ For instance, with
.Fl -bin Ns = Ns Li lsize ,
a block with lsize of 16K and psize of 4K will be added to the 16K bin
in all three columns.
.It Fl -class Ns = Ns ( Li normal Ns | Ns Li special Ns | Ns Li dedup Ns | Ns Li other ) Ns Op , Ns
When used with
.Fl bb ,
only consider blocks from these allocation classes.
.It Fl B , -backup
Generate a backup stream, similar to
.Nm zfs Cm send ,