Browse files

Add `zdb -Y` for split block reconstruction

The new -Y flag allows `zdb` to try all possible combinations
when performing split block reconstruction.

Depending on the extent of the damage this may not be able to
complete in a reasonable amount of time.  However, it is primarily
intended to be used by ztest(8) which by design should never be
able to damage a pool beyond repair.  The worst case observed
has been blocks with 18 splits which can be recovered in a few

Signed-off-by: Brian Behlendorf <>
  • Loading branch information...
behlendorf committed Nov 8, 2018
1 parent c8332cd commit a25ecd31d1c8e5280b8183de7c09f2f3e40acdee
Showing with 15 additions and 5 deletions.
  1. +8 −1 cmd/zdb/zdb.c
  2. +1 −2 cmd/ztest/ztest.c
  3. +6 −2 man/man8/zdb.8
@@ -100,6 +100,7 @@ extern int zfs_recover;
extern uint64_t zfs_arc_max, zfs_arc_meta_limit;
extern int zfs_vdev_async_read_max_active;
extern boolean_t spa_load_verify_dryrun;
extern int zfs_reconstruct_indirect_combinations_max;
static const char cmdname[] = "zdb";
uint8_t dump_opt[256];
@@ -215,6 +216,8 @@ usage(void)
"dump all read blocks into specified directory\n");
(void) fprintf(stderr, " -X attempt extreme rewind (does not "
"work with dataset)\n");
(void) fprintf(stderr, " -Y attempt all reconstruction "
"combinations for split blocks\n");
(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
"to make only that option verbose\n");
(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
@@ -5871,7 +5874,7 @@ main(int argc, char **argv)
spa_config_path = spa_config_path_env;
while ((c = getopt(argc, argv,
"AbcCdDeEFGhiI:klLmMo:Op:PqRsSt:uU:vVx:X")) != -1) {
"AbcCdDeEFGhiI:klLmMo:Op:PqRsSt:uU:vVx:XY")) != -1) {
switch (c) {
case 'b':
case 'c':
@@ -5903,6 +5906,10 @@ main(int argc, char **argv)
case 'X':
case 'Y':
zfs_reconstruct_indirect_combinations_max = INT_MAX;
zfs_deadman_enabled = 0;
/* NB: Sort single match options below. */
case 'I':
max_inflight = strtoull(optarg, NULL, 0);
@@ -6351,8 +6351,7 @@ ztest_run_zdb(char *pool)
ztest_get_zdb_bin(bin, len);
(void) sprintf(zdb,
"%s -bcc%s%s -G -d -U %s "
"-o zfs_reconstruct_indirect_combinations_max=65536 %s",
"%s -bcc%s%s -G -d -Y -U %s %s",
ztest_opts.zo_verbose >= 3 ? "s" : "",
ztest_opts.zo_verbose >= 4 ? "v" : "",
@@ -23,7 +23,7 @@
.Nd display zpool debugging and consistency information
.Op Fl AbcdDFGhikLMPsvX
.Op Fl AbcdDFGhikLMPsvXY
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl I Ar inflight I/Os
.Oo Fl o Ar var Ns = Ns Ar value Oc Ns ...
@@ -50,7 +50,7 @@
.Ar device
.Fl m
.Op Fl e Oo Fl V Oc Op Fl p Ar path ...
.Op Fl t Ar txg
.Op Fl U Ar cache
@@ -349,6 +349,10 @@ Attempt
transaction rewind, that is attempt the same recovery as
.Fl F
but read transactions otherwise deemed too old.
.It Fl Y
Attempt all possible combinations when reconstructing indirect split blocks.
This flag disables the individual I/O deadman timer in order to allow as
much time as required for the attempted reconstruction.
Specifying a display option more than once enables verbosity for only that

0 comments on commit a25ecd3

Please sign in to comment.