aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/zdb/zdb.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2018-10-09 15:42:42 -0700
committerBrian Behlendorf <[email protected]>2018-10-12 11:24:04 -0700
commit27f80e85c2649573af3c3d915baf6d4195538583 (patch)
treec95cbc3d0bb78e97ab9071ccb4e7355d81f5315f /cmd/zdb/zdb.c
parentd6c745830f2529643f1967e1f8a5d0abacba4585 (diff)
Improved error handling for extreme rewinds
The vdev_checkpoint_sm_object(), vdev_obsolete_sm_object(), and vdev_obsolete_counts_are_precise() functions assume that the only way a zap_lookup() can fail is if the requested entry is missing. While this is the most common cause, it's not the only cause. Attemping to access a damaged ZAP will result in other errors. The most likely scenario for accessing a damaged ZAP is during an extreme rewind pool import. Under these conditions the pool is expected to contain damaged objects and the import code was updated to handle this gracefully. Getting an ECKSUM error from these ZAPs after the pool in import a far less likely, therefore the behavior for call paths was not modified. Reviewed-by: Tim Chase <[email protected]> Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #7809 Closes #7921
Diffstat (limited to 'cmd/zdb/zdb.c')
-rw-r--r--cmd/zdb/zdb.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c
index 21113da2f..a558f60c0 100644
--- a/cmd/zdb/zdb.c
+++ b/cmd/zdb/zdb.c
@@ -696,19 +696,20 @@ get_metaslab_refcount(vdev_t *vd)
static int
get_obsolete_refcount(vdev_t *vd)
{
+ uint64_t obsolete_sm_object;
int refcount = 0;
- uint64_t obsolete_sm_obj = vdev_obsolete_sm_object(vd);
- if (vd->vdev_top == vd && obsolete_sm_obj != 0) {
+ VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object));
+ if (vd->vdev_top == vd && obsolete_sm_object != 0) {
dmu_object_info_t doi;
VERIFY0(dmu_object_info(vd->vdev_spa->spa_meta_objset,
- obsolete_sm_obj, &doi));
+ obsolete_sm_object, &doi));
if (doi.doi_bonus_size == sizeof (space_map_phys_t)) {
refcount++;
}
} else {
ASSERT3P(vd->vdev_obsolete_sm, ==, NULL);
- ASSERT3U(obsolete_sm_obj, ==, 0);
+ ASSERT3U(obsolete_sm_object, ==, 0);
}
for (unsigned c = 0; c < vd->vdev_children; c++) {
refcount += get_obsolete_refcount(vd->vdev_child[c]);
@@ -1051,7 +1052,8 @@ print_vdev_indirect(vdev_t *vd)
}
(void) printf("\n");
- uint64_t obsolete_sm_object = vdev_obsolete_sm_object(vd);
+ uint64_t obsolete_sm_object;
+ VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object));
if (obsolete_sm_object != 0) {
objset_t *mos = vd->vdev_spa->spa_meta_objset;
(void) printf("obsolete space map object %llu:\n",
@@ -3595,9 +3597,11 @@ zdb_load_obsolete_counts(vdev_t *vd)
spa_t *spa = vd->vdev_spa;
spa_condensing_indirect_phys_t *scip =
&spa->spa_condensing_indirect_phys;
+ uint64_t obsolete_sm_object;
uint32_t *counts;
- EQUIV(vdev_obsolete_sm_object(vd) != 0, vd->vdev_obsolete_sm != NULL);
+ VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object));
+ EQUIV(obsolete_sm_object != 0, vd->vdev_obsolete_sm != NULL);
counts = vdev_indirect_mapping_load_obsolete_counts(vim);
if (vd->vdev_obsolete_sm != NULL) {
vdev_indirect_mapping_load_obsolete_spacemap(vim, counts,
@@ -3972,6 +3976,7 @@ zdb_check_for_obsolete_leaks(vdev_t *vd, zdb_cb_t *zcb)
boolean_t leaks = B_FALSE;
vdev_indirect_mapping_t *vim = vd->vdev_indirect_mapping;
uint64_t total_leaked = 0;
+ boolean_t are_precise = B_FALSE;
ASSERT(vim != NULL);
@@ -3999,9 +4004,9 @@ zdb_check_for_obsolete_leaks(vdev_t *vd, zdb_cb_t *zcb)
zcb->zcb_vd_obsolete_counts[vd->vdev_id][i];
ASSERT3U(DVA_GET_ASIZE(&vimep->vimep_dst), >=,
zcb->zcb_vd_obsolete_counts[vd->vdev_id][i]);
- if (bytes_leaked != 0 &&
- (vdev_obsolete_counts_are_precise(vd) ||
- dump_opt['d'] >= 5)) {
+
+ VERIFY0(vdev_obsolete_counts_are_precise(vd, &are_precise));
+ if (bytes_leaked != 0 && (are_precise || dump_opt['d'] >= 5)) {
(void) printf("obsolete indirect mapping count "
"mismatch on %llu:%llx:%llx : %llx bytes leaked\n",
(u_longlong_t)vd->vdev_id,
@@ -4012,7 +4017,8 @@ zdb_check_for_obsolete_leaks(vdev_t *vd, zdb_cb_t *zcb)
total_leaked += ABS(bytes_leaked);
}
- if (!vdev_obsolete_counts_are_precise(vd) && total_leaked > 0) {
+ VERIFY0(vdev_obsolete_counts_are_precise(vd, &are_precise));
+ if (!are_precise && total_leaked > 0) {
int pct_leaked = total_leaked * 100 /
vdev_indirect_mapping_bytes_mapped(vim);
(void) printf("cannot verify obsolete indirect mapping "
@@ -4576,11 +4582,17 @@ verify_device_removal_feature_counts(spa_t *spa)
obsolete_counts_count++;
}
}
- if (vdev_obsolete_counts_are_precise(vd)) {
+
+ boolean_t are_precise;
+ VERIFY0(vdev_obsolete_counts_are_precise(vd, &are_precise));
+ if (are_precise) {
ASSERT(vic->vic_mapping_object != 0);
precise_vdev_count++;
}
- if (vdev_obsolete_sm_object(vd) != 0) {
+
+ uint64_t obsolete_sm_object;
+ VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object));
+ if (obsolete_sm_object != 0) {
ASSERT(vic->vic_mapping_object != 0);
obsolete_sm_count++;
}