aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libzfs/libzfs_status.c
diff options
context:
space:
mode:
authorColm <[email protected]>2021-04-12 17:08:56 +0100
committerGitHub <[email protected]>2021-04-12 09:08:56 -0700
commite086db16568e2cb8f484325481430aafd414d913 (patch)
treedc8a69c68b630af46dab51bb518096c3407602d0 /lib/libzfs/libzfs_status.c
parent888700bc6b4e673af3b90e7529a313573c4cc5b1 (diff)
Improvements to the 'compatibility' property
Several improvements to the operation of the 'compatibility' property: 1) Improved handling of unrecognized features: Change the way unrecognized features in compatibility files are handled. * invalid features in files under /usr/share/zfs/compatibility.d only get a warning (as these may refer to future features not yet in the library), * invalid features in files under /etc/zfs/compatibility.d get an error (as these are presumed to refer to the current system). 2) Improved error reporting from zpool_load_compat. Note: slight ABI change to zpool_load_compat for better error reporting. 3) compatibility=legacy inhibits all 'zpool upgrade' operations. 4) Detect when features are enabled outside current compatibility set * zpool set compatibility=foo <-- print a warning * zpool set feature@xxx=enabled <-- error * zpool status <-- indicate this state Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Colm Buckley <[email protected]> Closes #11861
Diffstat (limited to 'lib/libzfs/libzfs_status.c')
-rw-r--r--lib/libzfs/libzfs_status.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/libzfs/libzfs_status.c b/lib/libzfs/libzfs_status.c
index 5e5cb5f5d..33d6e1bfd 100644
--- a/lib/libzfs/libzfs_status.c
+++ b/lib/libzfs/libzfs_status.c
@@ -89,6 +89,7 @@ static char *zfs_msgid_table[] = {
* ZPOOL_STATUS_REBUILDING
* ZPOOL_STATUS_REBUILD_SCRUB
* ZPOOL_STATUS_COMPATIBILITY_ERR
+ * ZPOOL_STATUS_INCOMPATIBLE_FEAT
* ZPOOL_STATUS_OK
*/
};
@@ -453,11 +454,17 @@ check_status(nvlist_t *config, boolean_t isimport,
/*
* Outdated, but usable, version
*/
- if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION)
- return (ZPOOL_STATUS_VERSION_OLDER);
+ if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION) {
+ /* "legacy" compatibility disables old version reporting */
+ if (compat != NULL && strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0)
+ return (ZPOOL_STATUS_OK);
+ else
+ return (ZPOOL_STATUS_VERSION_OLDER);
+ }
/*
- * Usable pool with disabled features
+ * Usable pool with disabled or superfluous features
+ * (superfluous = beyond what's requested by 'compatibility')
*/
if (version >= SPA_VERSION_FEATURES) {
int i;
@@ -475,18 +482,23 @@ check_status(nvlist_t *config, boolean_t isimport,
}
/* check against all features, or limited set? */
- boolean_t pool_features[SPA_FEATURES];
+ boolean_t c_features[SPA_FEATURES];
- if (zpool_load_compat(compat, pool_features, NULL, NULL) !=
- ZPOOL_COMPATIBILITY_OK)
+ switch (zpool_load_compat(compat, c_features, NULL, 0)) {
+ case ZPOOL_COMPATIBILITY_OK:
+ case ZPOOL_COMPATIBILITY_WARNTOKEN:
+ break;
+ default:
return (ZPOOL_STATUS_COMPATIBILITY_ERR);
+ }
for (i = 0; i < SPA_FEATURES; i++) {
zfeature_info_t *fi = &spa_feature_table[i];
if (!fi->fi_zfs_mod_supported)
continue;
- if (pool_features[i] &&
- !nvlist_exists(feat, fi->fi_guid))
+ if (c_features[i] && !nvlist_exists(feat, fi->fi_guid))
return (ZPOOL_STATUS_FEAT_DISABLED);
+ if (!c_features[i] && nvlist_exists(feat, fi->fi_guid))
+ return (ZPOOL_STATUS_INCOMPATIBLE_FEAT);
}
}