From 658fb8020f0501435516baeea7004575d640649b Mon Sep 17 00:00:00 2001 From: Colm Date: Thu, 18 Feb 2021 05:30:45 +0000 Subject: Add "compatibility" property for zpool feature sets Property to allow sets of features to be specified; for compatibility with specific versions / releases / external systems. Influences the behavior of 'zpool upgrade' and 'zpool create'. Initial man page changes and test cases included. Brief synopsis: zpool create -o compatibility=off|legacy|file[,file...] pool vdev... compatibility = off : disable compatibility mode (enable all features) compatibility = legacy : request that no features be enabled compatibility = file[,file...] : read features from specified files. Only features present in *all* files will be enabled on the resulting pool. Filenames may be absolute, or relative to /etc/zfs/compatibility.d or /usr/share/zfs/compatibility.d (/etc checked first). Only affects zpool create, zpool upgrade and zpool status. ABI changes in libzfs: * New function "zpool_load_compat" to load and parse compat sets. * Add "zpool_compat_status_t" typedef for compatibility parse status. * Add ZPOOL_PROP_COMPATIBILITY to the pool properties enum * Add ZPOOL_STATUS_COMPATIBILITY_ERR to the pool status enum An initial set of base compatibility sets are included in cmd/zpool/compatibility.d, and the Makefile for cmd/zpool is modified to install these in $pkgdatadir/compatibility.d and to create symbolic links to a reasonable set of aliases. Reviewed-by: ericloewe Reviewed-by: Matthew Ahrens Reviewed-by: Richard Laager Reviewed-by: Brian Behlendorf Signed-off-by: Colm Buckley Closes #11468 --- module/zcommon/zpool_prop.c | 4 ++++ module/zfs/spa.c | 30 ++++++++++++++++++++++++++++++ module/zfs/spa_config.c | 4 ++++ 3 files changed, 38 insertions(+) (limited to 'module') diff --git a/module/zcommon/zpool_prop.c b/module/zcommon/zpool_prop.c index 815fad6df..6299d371f 100644 --- a/module/zcommon/zpool_prop.c +++ b/module/zcommon/zpool_prop.c @@ -22,6 +22,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012, 2018 by Delphix. All rights reserved. + * Copyright (c) 2021, Colm Buckley */ #include @@ -71,6 +72,9 @@ zpool_prop_init(void) PROP_DEFAULT, ZFS_TYPE_POOL, " | none", "CACHEFILE"); zprop_register_string(ZPOOL_PROP_COMMENT, "comment", NULL, PROP_DEFAULT, ZFS_TYPE_POOL, "", "COMMENT"); + zprop_register_string(ZPOOL_PROP_COMPATIBILITY, "compatibility", + "off", PROP_DEFAULT, ZFS_TYPE_POOL, + " | off | legacy", "COMPATIBILITY"); /* readonly number properties */ zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY, diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 56354a107..5170c9ca2 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -32,6 +32,7 @@ * Copyright (c) 2017, 2019, Datto Inc. All rights reserved. * Copyright 2017 Joyent, Inc. * Copyright (c) 2017, Intel Corporation. + * Copyright (c) 2021, Colm Buckley */ /* @@ -377,6 +378,11 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) 0, ZPROP_SRC_LOCAL); } + if (spa->spa_compatibility != NULL) { + spa_prop_add_list(*nvp, ZPOOL_PROP_COMPATIBILITY, + spa->spa_compatibility, 0, ZPROP_SRC_LOCAL); + } + if (spa->spa_root != NULL) spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root, 0, ZPROP_SRC_LOCAL); @@ -1669,6 +1675,10 @@ spa_unload(spa_t *spa) spa_strfree(spa->spa_comment); spa->spa_comment = NULL; } + if (spa->spa_compatibility != NULL) { + spa_strfree(spa->spa_compatibility); + spa->spa_compatibility = NULL; + } spa_config_exit(spa, SCL_ALL, spa); } @@ -3249,6 +3259,7 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type) vdev_t *rvd; uint64_t pool_guid; char *comment; + char *compatibility; /* * Versioning wasn't explicitly added to the label until later, so if @@ -3297,6 +3308,11 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type) if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMMENT, &comment) == 0) spa->spa_comment = spa_strdup(comment); + ASSERT(spa->spa_compatibility == NULL); + if (nvlist_lookup_string(config, ZPOOL_CONFIG_COMPATIBILITY, + &compatibility) == 0) + spa->spa_compatibility = spa_strdup(compatibility); + (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &spa->spa_config_txg); @@ -8668,6 +8684,20 @@ spa_sync_props(void *arg, dmu_tx_t *tx) spa_history_log_internal(spa, "set", tx, "%s=%s", nvpair_name(elem), strval); break; + case ZPOOL_PROP_COMPATIBILITY: + strval = fnvpair_value_string(elem); + if (spa->spa_compatibility != NULL) + spa_strfree(spa->spa_compatibility); + spa->spa_compatibility = spa_strdup(strval); + /* + * Dirty the configuration on vdevs as above. + */ + if (tx->tx_txg != TXG_INITIAL) + vdev_config_dirty(spa->spa_root_vdev); + spa_history_log_internal(spa, "set", tx, + "%s=%s", nvpair_name(elem), strval); + break; + default: /* * Set pool property values in the poolprops mos object. diff --git a/module/zfs/spa_config.c b/module/zfs/spa_config.c index dacba127d..4a3144313 100644 --- a/module/zfs/spa_config.c +++ b/module/zfs/spa_config.c @@ -24,6 +24,7 @@ * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2011, 2020 by Delphix. All rights reserved. * Copyright 2017 Joyent, Inc. + * Copyright (c) 2021, Colm Buckley */ #include @@ -446,6 +447,9 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats) if (spa->spa_comment != NULL) fnvlist_add_string(config, ZPOOL_CONFIG_COMMENT, spa->spa_comment); + if (spa->spa_compatibility != NULL) + fnvlist_add_string(config, ZPOOL_CONFIG_COMPATIBILITY, + spa->spa_compatibility); hostid = spa_get_hostid(spa); if (hostid != 0) -- cgit v1.2.3