Skip to content

Commit b1a4bcf

Browse files
committed
Improved zpool status output, list all affected datasets
Currently, determining which datasets are affected by corruption is a manual process. The primary difficulty in reporting the list of affected snapshots is that since the error was initially found, the snapshot where the error originally occurred in, may have been deleted. To solve this issue, we add the ID of the head dataset of the original snapshot which the error was detected in, to the stored error report. Then any time a filesystem is deleted, the errors associated with it are deleted as well. Any time a clone promote occurs, we modify reports associated with the original head to refer to the new head. The stored error reports are identified by this head ID, the birth time of the block which the error occurred in, as well as some information about the error itself are also stored. Once this information is stored, we can find the set of datasets affected by an error by walking back the list of snapshots in the given head until we find one with the appropriate birth txg, and then traverse through the snapshots of the clone family, terminating a branch if the block was replaced in a given snapshot. Then we report this information back to libzfs, and to the zpool status command, where it is displayed as follows: pool: test state: ONLINE status: One or more devices has experienced an error resulting in data corruption. Applications may be affected. action: Restore the file in question if possible. Otherwise restore the entire pool from backup. see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-8A scan: scrub repaired 0B in 00:00:00 with 800 errors on Fri Dec 3 08:27:57 2021 config: NAME STATE READ WRITE CKSUM test ONLINE 0 0 0 sdb ONLINE 0 0 1.58K errors: Permanent errors have been detected in the following files: test@1:/test.0.0 /test/test.0.0 /test/1clone/test.0.0 A new feature flag is introduced to mark the presence of this change, as well as promotion and backwards compatibility logic. This is an updated version of #9175. Rebase required fixing the tests, updating the ABI of libzfs, and updating the man pages. Signed-off-by: TulsiJain <[email protected]> Signed-off-by: George Amanakis <[email protected]>
1 parent ddc026f commit b1a4bcf

File tree

15 files changed

+896
-68
lines changed

15 files changed

+896
-68
lines changed

include/sys/spa.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1144,11 +1144,14 @@ extern void zfs_post_remove(spa_t *spa, vdev_t *vd);
11441144
extern void zfs_post_state_change(spa_t *spa, vdev_t *vd, uint64_t laststate);
11451145
extern void zfs_post_autoreplace(spa_t *spa, vdev_t *vd);
11461146
extern uint64_t spa_get_errlog_size(spa_t *spa);
1147-
extern int spa_get_errlog(spa_t *spa, void *uaddr, size_t *count);
1147+
extern int spa_get_errlog(spa_t *spa, void *uaddr, uint64_t *count);
11481148
extern void spa_errlog_rotate(spa_t *spa);
11491149
extern void spa_errlog_drain(spa_t *spa);
11501150
extern void spa_errlog_sync(spa_t *spa, uint64_t txg);
11511151
extern void spa_get_errlists(spa_t *spa, avl_tree_t *last, avl_tree_t *scrub);
1152+
extern void spa_delete_dataset_errlog(spa_t *spa, uint64_t ds, dmu_tx_t *tx);
1153+
extern void spa_swap_errlog(spa_t *spa, uint64_t new_head_ds,
1154+
uint64_t old_head_ds, dmu_tx_t *tx);
11521155

11531156
/* vdev cache */
11541157
extern void vdev_cache_stat_init(void);

include/sys/zio.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,13 @@ struct zbookmark_phys {
291291
uint64_t zb_blkid;
292292
};
293293

294+
typedef struct zbookmark_err_phys {
295+
uint64_t zb_object;
296+
int64_t zb_level;
297+
uint64_t zb_blkid;
298+
uint64_t zb_birth;
299+
} zbookmark_err_phys_t;
300+
294301
#define SET_BOOKMARK(zb, objset, object, level, blkid) \
295302
{ \
296303
(zb)->zb_objset = objset; \

include/zfeature_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ typedef enum spa_feature {
7575
SPA_FEATURE_DEVICE_REBUILD,
7676
SPA_FEATURE_ZSTD_COMPRESS,
7777
SPA_FEATURE_DRAID,
78+
SPA_FEATURE_HEAD_ERRLOG,
7879
SPA_FEATURES
7980
} spa_feature_t;
8081

lib/libzfs/libzfs.abi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@
596596
<elf-symbol name='fletcher_4_superscalar_ops' size='64' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
597597
<elf-symbol name='libspl_assert_ok' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
598598
<elf-symbol name='libzfs_config_ops' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
599-
<elf-symbol name='spa_feature_table' size='1904' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
599+
<elf-symbol name='spa_feature_table' size='1960' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
600600
<elf-symbol name='zfeature_checks_disable' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
601601
<elf-symbol name='zfs_deleg_perm_tab' size='512' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
602602
<elf-symbol name='zfs_history_event_names' size='328' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@@ -1856,8 +1856,8 @@
18561856
</function-decl>
18571857
</abi-instr>
18581858
<abi-instr address-size='64' path='../../module/zcommon/zfeature_common.c' language='LANG_C99'>
1859-
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='15232' id='d96379d0'>
1860-
<subrange length='34' type-id='7359adad' id='6a6a7e00'/>
1859+
<array-type-def dimensions='1' type-id='83f29ca2' size-in-bits='15680' id='9d60dcc5'>
1860+
<subrange length='35' type-id='7359adad' id='6e6845b5'/>
18611861
</array-type-def>
18621862
<enum-decl name='spa_feature' id='33ecb627'>
18631863
<underlying-type type-id='9cac1fee'/>
@@ -1896,7 +1896,8 @@
18961896
<enumerator name='SPA_FEATURE_DEVICE_REBUILD' value='31'/>
18971897
<enumerator name='SPA_FEATURE_ZSTD_COMPRESS' value='32'/>
18981898
<enumerator name='SPA_FEATURE_DRAID' value='33'/>
1899-
<enumerator name='SPA_FEATURES' value='34'/>
1899+
<enumerator name='SPA_FEATURE_HEAD_ERRLOG' value='34'/>
1900+
<enumerator name='SPA_FEATURES' value='35'/>
19001901
</enum-decl>
19011902
<typedef-decl name='spa_feature_t' type-id='33ecb627' id='d6618c78'/>
19021903
<enum-decl name='zfeature_flags' id='6db816a4'>
@@ -1944,7 +1945,7 @@
19441945
<qualified-type-def type-id='d6618c78' const='yes' id='81a65028'/>
19451946
<pointer-type-def type-id='81a65028' size-in-bits='64' id='1acff326'/>
19461947
<pointer-type-def type-id='d6618c78' size-in-bits='64' id='a8425263'/>
1947-
<var-decl name='spa_feature_table' type-id='d96379d0' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
1948+
<var-decl name='spa_feature_table' type-id='9d60dcc5' mangled-name='spa_feature_table' visibility='default' elf-symbol-id='spa_feature_table'/>
19481949
<var-decl name='zfeature_checks_disable' type-id='c19b74c3' mangled-name='zfeature_checks_disable' visibility='default' elf-symbol-id='zfeature_checks_disable'/>
19491950
<function-decl name='zfeature_is_valid_guid' mangled-name='zfeature_is_valid_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zfeature_is_valid_guid'>
19501951
<parameter type-id='80f4b756' name='name'/>

man/man7/zpool-features.7

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,15 @@ once all filesystems that have ever had their
832832
property set to
833833
.Sy zstd
834834
are destroyed.
835+
.feature com.delphix head_errlog no
836+
This feature enables the upgraded version of errlog.
837+
This required an on-disk error format change.
838+
Now the errorlog of each head dataset is stored separately
839+
in the zap object and keyed by the head id.
840+
With this feature enabled, every dataset affected by an error block is listed
841+
in the output of
842+
.Nm zpool Cm status .
843+
This feature can only be enabled at pool creation time.
835844
.El
836-
.
837845
.Sh SEE ALSO
838846
.Xr zpool 8

module/zcommon/zfeature_common.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ zpool_feature_init(void)
594594
zfeature_register(SPA_FEATURE_DRAID,
595595
"org.openzfs:draid", "draid", "Support for distributed spare RAID",
596596
ZFEATURE_FLAG_MOS, ZFEATURE_TYPE_BOOLEAN, NULL);
597+
598+
zfeature_register(SPA_FEATURE_HEAD_ERRLOG,
599+
"com.delphix:head_errlog", "head_errlog",
600+
"Introduce an on-disk block error log.",
601+
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, ZFEATURE_TYPE_BOOLEAN, NULL);
597602
}
598603

599604
#if defined(_KERNEL)

module/zfs/dsl_dataset.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3741,6 +3741,15 @@ dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx)
37413741

37423742
dsl_dir_rele(odd, FTAG);
37433743
promote_rele(ddpa, FTAG);
3744+
3745+
/*
3746+
* Transfer common error blocks from old head to new head.
3747+
*/
3748+
if (spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_HEAD_ERRLOG)) {
3749+
uint64_t old_head = origin_head->ds_object;
3750+
uint64_t new_head = hds->ds_object;
3751+
spa_swap_errlog(dp->dp_spa, new_head, old_head, tx);
3752+
}
37443753
}
37453754

37463755
/*

module/zfs/dsl_destroy.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,9 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx)
11531153
dsl_destroy_snapshot_sync_impl(prev, B_FALSE, tx);
11541154
dsl_dataset_rele(prev, FTAG);
11551155
}
1156+
/* Delete errlog. */
1157+
if (spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_HEAD_ERRLOG))
1158+
spa_delete_dataset_errlog(dp->dp_spa, ds->ds_object, tx);
11561159
}
11571160

11581161
void

0 commit comments

Comments
 (0)