Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Mar 2021 09:36:37 GMT
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: e1f9a18f917d - stable/13 - zfs: merge OpenZFS master-bf156c966
Message-ID:  <202103100936.12A9ab6e013913@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mm:

URL: https://cgit.FreeBSD.org/src/commit/?id=e1f9a18f917d9d5a3f88419bc72c9ee2fbb1c8df

commit e1f9a18f917d9d5a3f88419bc72c9ee2fbb1c8df
Author:     Martin Matuska <mm@FreeBSD.org>
AuthorDate: 2021-02-18 14:17:31 +0000
Commit:     Martin Matuska <mm@FreeBSD.org>
CommitDate: 2021-03-10 01:25:54 +0000

    zfs: merge OpenZFS master-bf156c966
    
    Notable upstream changes:
        bf156c966 Remove unused abd_alloc_scatter_offset_chunkcnt
        658fb8020 Add "compatibility" property for zpool feature sets
    
    This update introduces a new pool property called "compatibility"
    that can be used to enable a limited set of pool features on pool
    creation and "stick" to it, so the "zpool upgrade" does not
    accidentally enable features that are not desired. The value of
    this property may then be changed later.
    
    See zpool-features(5) for more information about the "compatibility"
    pool property.
    
    Obtained from:  OpenZFS
    
    (cherry picked from commit ee36e25a86cbe2a9474c1d61f2c4b450da8ef952)
---
 sys/contrib/openzfs/cmd/zpool/Makefile.am          |   47 +-
 .../openzfs/cmd/zpool/compatibility.d/compat-2018  |   12 +
 .../openzfs/cmd/zpool/compatibility.d/compat-2019  |   15 +
 .../openzfs/cmd/zpool/compatibility.d/compat-2020  |   15 +
 .../openzfs/cmd/zpool/compatibility.d/compat-2021  |   19 +
 .../openzfs/cmd/zpool/compatibility.d/freebsd-11.0 |   15 +
 .../openzfs/cmd/zpool/compatibility.d/freebsd-11.2 |   18 +
 .../openzfs/cmd/zpool/compatibility.d/freebsd-11.3 |   19 +
 .../cmd/zpool/compatibility.d/freenas-9.10.2       |   13 +
 .../openzfs/cmd/zpool/compatibility.d/grub2        |   12 +
 .../cmd/zpool/compatibility.d/openzfs-2.0-freebsd  |   33 +
 .../cmd/zpool/compatibility.d/openzfs-2.0-linux    |   34 +
 .../cmd/zpool/compatibility.d/openzfsonosx-1.7.0   |   16 +
 .../cmd/zpool/compatibility.d/openzfsonosx-1.8.1   |   21 +
 .../cmd/zpool/compatibility.d/openzfsonosx-1.9.3   |   27 +
 .../openzfs/cmd/zpool/compatibility.d/zol-0.6.5    |   12 +
 .../openzfs/cmd/zpool/compatibility.d/zol-0.7      |   18 +
 .../openzfs/cmd/zpool/compatibility.d/zol-0.8      |   27 +
 sys/contrib/openzfs/cmd/zpool/zpool_main.c         |  165 +-
 sys/contrib/openzfs/cmd/ztest/ztest.c              |    4 +-
 sys/contrib/openzfs/config/Rules.am                |    1 +
 sys/contrib/openzfs/include/libzfs.h               |   16 +
 sys/contrib/openzfs/include/sys/fs/zfs.h           |   19 +-
 sys/contrib/openzfs/include/sys/spa_impl.h         |    2 +
 sys/contrib/openzfs/include/zfeature_common.h      |    2 -
 sys/contrib/openzfs/lib/libzfs/libzfs.abi          | 6933 ++++++++++++--------
 sys/contrib/openzfs/lib/libzfs/libzfs_pool.c       |  228 +
 sys/contrib/openzfs/lib/libzfs/libzfs_status.c     |   29 +-
 sys/contrib/openzfs/lib/libzutil/zutil_import.c    |   10 +
 sys/contrib/openzfs/man/man5/zpool-features.5      |   59 +-
 sys/contrib/openzfs/man/man8/zpool-create.8        |   16 +-
 sys/contrib/openzfs/man/man8/zpool-upgrade.8       |   16 +-
 sys/contrib/openzfs/man/man8/zpoolprops.8          |   19 +
 sys/contrib/openzfs/module/os/freebsd/zfs/abd_os.c |   19 -
 .../openzfs/module/zcommon/zfeature_common.c       |   13 +-
 sys/contrib/openzfs/module/zcommon/zpool_prop.c    |    4 +
 sys/contrib/openzfs/module/zfs/spa.c               |   30 +
 sys/contrib/openzfs/module/zfs/spa_config.c        |    4 +
 sys/contrib/openzfs/rpm/generic/zfs.spec.in        |    6 +-
 sys/contrib/openzfs/scripts/Makefile.am            |    1 +
 sys/contrib/openzfs/tests/runfiles/common.run      |    8 +-
 .../tests/zfs-tests/cmd/xattrtest/xattrtest.c      |    6 +-
 .../openzfs/tests/zfs-tests/include/default.cfg.in |    1 +
 .../functional/cli_root/zpool_create/Makefile.am   |    3 +
 .../cli_root/zpool_create/zpool_create.shlib       |   81 +
 .../zpool_create/zpool_create_features_006_pos.ksh |   58 +
 .../zpool_create/zpool_create_features_007_pos.ksh |   54 +
 .../zpool_create/zpool_create_features_008_pos.ksh |   54 +
 .../functional/cli_root/zpool_get/zpool_get.cfg    |    1 +
 .../functional/cli_root/zpool_status/Makefile.am   |    3 +-
 .../zpool_status/zpool_status_features_001_pos.ksh |   63 +
 .../functional/cli_root/zpool_upgrade/Makefile.am  |    3 +-
 .../zpool_upgrade_features_001_pos.ksh             |   67 +
 53 files changed, 5513 insertions(+), 2858 deletions(-)

diff --git a/sys/contrib/openzfs/cmd/zpool/Makefile.am b/sys/contrib/openzfs/cmd/zpool/Makefile.am
index fb03e99a3054..d47051e4fe50 100644
--- a/sys/contrib/openzfs/cmd/zpool/Makefile.am
+++ b/sys/contrib/openzfs/cmd/zpool/Makefile.am
@@ -39,7 +39,7 @@ include $(top_srcdir)/config/CppCheck.am
 zpoolconfdir = $(sysconfdir)/zfs/zpool.d
 zpoolexecdir = $(zfsexecdir)/zpool.d
 
-EXTRA_DIST = zpool.d/README
+EXTRA_DIST = zpool.d/README compatibility.d
 
 dist_zpoolexec_SCRIPTS = \
 	zpool.d/dm-deps \
@@ -129,6 +129,48 @@ zpoolconfdefaults = \
 	test_progress \
 	test_ended
 
+zpoolcompatdir = $(pkgdatadir)/compatibility.d
+
+dist_zpoolcompat_DATA = \
+	compatibility.d/compat-2018 \
+	compatibility.d/compat-2019 \
+	compatibility.d/compat-2020 \
+	compatibility.d/compat-2021 \
+	compatibility.d/freebsd-11.0 \
+	compatibility.d/freebsd-11.2 \
+	compatibility.d/freebsd-11.3 \
+	compatibility.d/freenas-9.10.2 \
+	compatibility.d/grub2 \
+	compatibility.d/openzfsonosx-1.7.0 \
+	compatibility.d/openzfsonosx-1.8.1 \
+	compatibility.d/openzfsonosx-1.9.3 \
+	compatibility.d/openzfs-2.0-freebsd \
+	compatibility.d/openzfs-2.0-linux \
+	compatibility.d/zol-0.6.5 \
+	compatibility.d/zol-0.7 \
+	compatibility.d/zol-0.8
+
+# canonical <- alias symbolic link pairs
+# eg: "2018" is a link to "compat-2018"
+zpoolcompatlinks = \
+	"compat-2018		2018" \
+	"compat-2019		2019" \
+	"compat-2020		2020" \
+	"compat-2021		2021" \
+	"freebsd-11.0		freebsd-11.1" \
+	"freebsd-11.0		freenas-11.0" \
+	"freebsd-11.2		freenas-11.2" \
+	"freebsd-11.3		freebsd-11.4" \
+	"freebsd-11.3		freebsd-12.0" \
+	"freebsd-11.3		freebsd-12.1" \
+	"freebsd-11.3		freebsd-12.2" \
+	"freebsd-11.3		freenas-11.3" \
+	"freenas-11.0		freenas-11.1" \
+	"openzfsonosx-1.9.3	openzfsonosx-1.9.4" \
+	"openzfs-2.0-freebsd	truenas-12.0" \
+	"zol-0.7		ubuntu-18.04" \
+	"zol-0.8		ubuntu-20.04"
+
 install-data-hook:
 	$(MKDIR_P) "$(DESTDIR)$(zpoolconfdir)"
 	for f in $(zpoolconfdefaults); do \
@@ -136,3 +178,6 @@ install-data-hook:
 	       -L "$(DESTDIR)$(zpoolconfdir)/$${f}" || \
 	    ln -s "$(zpoolexecdir)/$${f}" "$(DESTDIR)$(zpoolconfdir)"; \
 	done
+	for l in $(zpoolcompatlinks); do \
+		(cd "$(DESTDIR)$(zpoolcompatdir)"; ln -s $${l} ); \
+	done
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2018 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2018
new file mode 100644
index 000000000000..7be44e1eee95
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2018
@@ -0,0 +1,12 @@
+# Features supported by all Tier 1 platforms as of 2018
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2019 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2019
new file mode 100644
index 000000000000..c105cc70c290
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2019
@@ -0,0 +1,15 @@
+# Features supported by all Tier 1 platforms as of 2019
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+sha512
+skein
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2020 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2020
new file mode 100644
index 000000000000..8d46a571e6ef
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2020
@@ -0,0 +1,15 @@
+# Features supported by all Tier 1 platforms as of 2020
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+sha512
+skein
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2021 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2021
new file mode 100644
index 000000000000..f45c82d6560f
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/compat-2021
@@ -0,0 +1,19 @@
+# Features supported by all Tier 1 platforms as of 2021
+async_destroy
+bookmarks
+device_removal
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.0 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.0
new file mode 100644
index 000000000000..8718559ffb4c
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.0
@@ -0,0 +1,15 @@
+# Features supported by FreeBSD 11.0
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+sha512
+skein
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.2 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.2
new file mode 100644
index 000000000000..14d2d573b2a0
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.2
@@ -0,0 +1,18 @@
+# Features supported by FreeBSD 11.2
+async_destroy
+bookmarks
+device_removal
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+sha512
+skein
+spacemap_histogram
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.3 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.3
new file mode 100644
index 000000000000..802cc3630de7
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freebsd-11.3
@@ -0,0 +1,19 @@
+# Features supported by FreeBSD 11.3
+async_destroy
+bookmarks
+device_removal
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/freenas-9.10.2 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freenas-9.10.2
new file mode 100644
index 000000000000..10789c96cc8f
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/freenas-9.10.2
@@ -0,0 +1,13 @@
+# Features supported by FreeNAS 9.10.2
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/grub2 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/grub2
new file mode 100644
index 000000000000..4e8f21362554
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/grub2
@@ -0,0 +1,12 @@
+# Features which are supported by GRUB2
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-freebsd b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-freebsd
new file mode 100644
index 000000000000..e7ee2f247670
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-freebsd
@@ -0,0 +1,33 @@
+# Features supported by OpenZFS 2.0 on FreeBSD
+allocation_classes
+async_destroy
+bookmark_v2
+bookmark_written
+bookmarks
+device_rebuild
+device_removal
+embedded_data
+empty_bpobj
+enabled_txg
+encryption
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+large_dnode
+livelist
+log_spacemap
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+project_quota
+redacted_datasets
+redaction_bookmarks
+resilver_defer
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+userobj_accounting
+zpool_checkpoint
+zstd_compress
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-linux b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-linux
new file mode 100644
index 000000000000..ac0f5c863468
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfs-2.0-linux
@@ -0,0 +1,34 @@
+# Features supported by OpenZFS 2.0 on Linux
+allocation_classes
+async_destroy
+bookmark_v2
+bookmark_written
+bookmarks
+device_rebuild
+device_removal
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+encryption
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+large_dnode
+livelist
+log_spacemap
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+project_quota
+redacted_datasets
+redaction_bookmarks
+resilver_defer
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+userobj_accounting
+zpool_checkpoint
+zstd_compress
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.7.0 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.7.0
new file mode 100644
index 000000000000..4ae87c964c5e
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.7.0
@@ -0,0 +1,16 @@
+# Features supported by OpenZFSonOSX 1.7.0
+async_destroy
+bookmarks
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+sha512
+skein
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.8.1 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.8.1
new file mode 100644
index 000000000000..162ff32a7803
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.8.1
@@ -0,0 +1,21 @@
+# Features supported by OpenZFSonOSX 1.8.1
+async_destroy
+bookmarks
+device_removal
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+encryption
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.9.3 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.9.3
new file mode 100644
index 000000000000..b0b28ec04939
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/openzfsonosx-1.9.3
@@ -0,0 +1,27 @@
+# Features supported by OpenZFSonOSX 1.9.3
+allocation_classes
+async_destroy
+bookmark_v2
+bookmarks
+device_removal
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+encryption
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+large_dnode
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+project_quota
+resilver_defer
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+userobj_accounting
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.5 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.5
new file mode 100644
index 000000000000..cb9a94d88951
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.6.5
@@ -0,0 +1,12 @@
+# Features supported by ZFSonLinux v0.6.5
+async_destroy
+bookmarks
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+lz4_compress
+spacemap_histogram
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.7 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.7
new file mode 100644
index 000000000000..22a02936df8c
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.7
@@ -0,0 +1,18 @@
+# Features supported by ZFSonLinux v0.7
+async_destroy
+bookmarks
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+large_dnode
+lz4_compress
+multi_vdev_crash_dump
+sha512
+skein
+spacemap_histogram
+userobj_accounting
diff --git a/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.8 b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.8
new file mode 100644
index 000000000000..762848ef7b4b
--- /dev/null
+++ b/sys/contrib/openzfs/cmd/zpool/compatibility.d/zol-0.8
@@ -0,0 +1,27 @@
+# Features supported by ZFSonLinux v0.8
+allocation_classes
+async_destroy
+bookmark_v2
+bookmarks
+device_removal
+edonr
+embedded_data
+empty_bpobj
+enabled_txg
+encryption
+extensible_dataset
+filesystem_limits
+hole_birth
+large_blocks
+large_dnode
+lz4_compress
+multi_vdev_crash_dump
+obsolete_counts
+project_quota
+resilver_defer
+sha512
+skein
+spacemap_histogram
+spacemap_v2
+userobj_accounting
+zpool_checkpoint
diff --git a/sys/contrib/openzfs/cmd/zpool/zpool_main.c b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
index 50adc0add605..29252e6a24f4 100644
--- a/sys/contrib/openzfs/cmd/zpool/zpool_main.c
+++ b/sys/contrib/openzfs/cmd/zpool/zpool_main.c
@@ -31,6 +31,7 @@
  * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
  * Copyright (c) 2017, Intel Corporation.
  * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
+ * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
  */
 
 #include <assert.h>
@@ -124,6 +125,9 @@ static int zpool_do_version(int, char **);
 
 static int zpool_do_wait(int, char **);
 
+static zpool_compat_status_t zpool_do_load_compat(
+    const char *, boolean_t *);
+
 /*
  * These libumem hooks provide a reasonable set of defaults for the allocator's
  * debugging facilities.
@@ -782,6 +786,8 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props,
 
 	if (poolprop) {
 		const char *vname = zpool_prop_to_name(ZPOOL_PROP_VERSION);
+		const char *fname =
+		    zpool_prop_to_name(ZPOOL_PROP_COMPATIBILITY);
 
 		if ((prop = zpool_name_to_prop(propname)) == ZPOOL_PROP_INVAL &&
 		    !zpool_prop_feature(propname)) {
@@ -804,6 +810,19 @@ add_prop_list(const char *propname, char *propval, nvlist_t **props,
 			return (2);
 		}
 
+		/*
+		 * compatibility property and version should not be specified
+		 * at the same time.
+		 */
+		if ((prop == ZPOOL_PROP_COMPATIBILITY &&
+		    nvlist_exists(proplist, vname)) ||
+		    (prop == ZPOOL_PROP_VERSION &&
+		    nvlist_exists(proplist, fname))) {
+			(void) fprintf(stderr, gettext("'compatibility' and "
+			    "'version' properties cannot be specified "
+			    "together\n"));
+			return (2);
+		}
 
 		if (zpool_prop_feature(propname))
 			normnm = propname;
@@ -1374,13 +1393,15 @@ zpool_do_create(int argc, char **argv)
 {
 	boolean_t force = B_FALSE;
 	boolean_t dryrun = B_FALSE;
-	boolean_t enable_all_pool_feat = B_TRUE;
+	boolean_t enable_pool_features = B_TRUE;
+
 	int c;
 	nvlist_t *nvroot = NULL;
 	char *poolname;
 	char *tname = NULL;
 	int ret = 1;
 	char *altroot = NULL;
+	char *compat = NULL;
 	char *mountpoint = NULL;
 	nvlist_t *fsprops = NULL;
 	nvlist_t *props = NULL;
@@ -1396,7 +1417,7 @@ zpool_do_create(int argc, char **argv)
 			dryrun = B_TRUE;
 			break;
 		case 'd':
-			enable_all_pool_feat = B_FALSE;
+			enable_pool_features = B_FALSE;
 			break;
 		case 'R':
 			altroot = optarg;
@@ -1434,11 +1455,14 @@ zpool_do_create(int argc, char **argv)
 				ver = strtoull(propval, &end, 10);
 				if (*end == '\0' &&
 				    ver < SPA_VERSION_FEATURES) {
-					enable_all_pool_feat = B_FALSE;
+					enable_pool_features = B_FALSE;
 				}
 			}
 			if (zpool_name_to_prop(optarg) == ZPOOL_PROP_ALTROOT)
 				altroot = propval;
+			if (zpool_name_to_prop(optarg) ==
+			    ZPOOL_PROP_COMPATIBILITY)
+				compat = propval;
 			break;
 		case 'O':
 			if ((propval = strchr(optarg, '=')) == NULL) {
@@ -1632,10 +1656,26 @@ zpool_do_create(int argc, char **argv)
 		ret = 0;
 	} else {
 		/*
-		 * Hand off to libzfs.
+		 * Load in feature set.
+		 * Note: if compatibility property not given, we'll have
+		 * NULL, which means 'all features'.
 		 */
-		spa_feature_t i;
-		for (i = 0; i < SPA_FEATURES; i++) {
+		boolean_t requested_features[SPA_FEATURES];
+		if (zpool_do_load_compat(compat, requested_features) !=
+		    ZPOOL_COMPATIBILITY_OK)
+			goto errout;
+
+		/*
+		 * props contains list of features to enable.
+		 * For each feature:
+		 *  - remove it if feature@name=disabled
+		 *  - leave it there if feature@name=enabled
+		 *  - add it if:
+		 *    - enable_pool_features (ie: no '-d' or '-o version')
+		 *    - it's supported by the kernel module
+		 *    - it's in the requested feature set
+		 */
+		for (spa_feature_t i = 0; i < SPA_FEATURES; i++) {
 			char propname[MAXPATHLEN];
 			char *propval;
 			zfeature_info_t *feat = &spa_feature_table[i];
@@ -1643,18 +1683,14 @@ zpool_do_create(int argc, char **argv)
 			(void) snprintf(propname, sizeof (propname),
 			    "feature@%s", feat->fi_uname);
 
-			/*
-			 * Only features contained in props will be enabled:
-			 * remove from the nvlist every ZFS_FEATURE_DISABLED
-			 * value and add every missing ZFS_FEATURE_ENABLED if
-			 * enable_all_pool_feat is set.
-			 */
 			if (!nvlist_lookup_string(props, propname, &propval)) {
 				if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
 					(void) nvlist_remove_all(props,
 					    propname);
-			} else if (enable_all_pool_feat &&
-			    feat->fi_zfs_mod_supported) {
+			} else if (
+			    enable_pool_features &&
+			    feat->fi_zfs_mod_supported &&
+			    requested_features[i]) {
 				ret = add_prop_list(propname,
 				    ZFS_FEATURE_ENABLED, &props, B_TRUE);
 				if (ret != 0)
@@ -2674,8 +2710,15 @@ show_import(nvlist_t *config)
 
 	case ZPOOL_STATUS_FEAT_DISABLED:
 		printf_color(ANSI_BOLD, gettext("status: "));
-		printf_color(ANSI_YELLOW, gettext("Some supported features are "
-		    "not enabled on the pool.\n"));
+		printf_color(ANSI_YELLOW, gettext("Some supported and "
+		    "requested features are not enabled on the pool.\n"));
+		break;
+
+	case ZPOOL_STATUS_COMPATIBILITY_ERR:
+		printf_color(ANSI_BOLD, gettext("status: "));
+		printf_color(ANSI_YELLOW, gettext("Error reading or parsing "
+		    "the file(s) indicated by the 'compatibility'\n"
+		    "property.\n"));
 		break;
 
 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
@@ -2767,6 +2810,12 @@ show_import(nvlist_t *config)
 			    "imported using its name or numeric identifier, "
 			    "though\n\tsome features will not be available "
 			    "without an explicit 'zpool upgrade'.\n"));
+		} else if (reason == ZPOOL_STATUS_COMPATIBILITY_ERR) {
+			(void) printf(gettext(" action: The pool can be "
+			    "imported using its name or numeric\n\tidentifier, "
+			    "though the file(s) indicated by its "
+			    "'compatibility'\n\tproperty cannot be parsed at "
+			    "this time.\n"));
 		} else if (reason == ZPOOL_STATUS_HOSTID_MISMATCH) {
 			(void) printf(gettext(" action: The pool can be "
 			    "imported using its name or numeric "
@@ -7942,7 +7991,8 @@ status_callback(zpool_handle_t *zhp, void *data)
 	if (cbp->cb_explain &&
 	    (reason == ZPOOL_STATUS_OK ||
 	    reason == ZPOOL_STATUS_VERSION_OLDER ||
-	    reason == ZPOOL_STATUS_FEAT_DISABLED)) {
+	    reason == ZPOOL_STATUS_FEAT_DISABLED ||
+	    reason == ZPOOL_STATUS_COMPATIBILITY_ERR)) {
 		if (!cbp->cb_allpools) {
 			(void) printf(gettext("pool '%s' is healthy\n"),
 			    zpool_get_name(zhp));
@@ -8117,9 +8167,10 @@ status_callback(zpool_handle_t *zhp, void *data)
 
 	case ZPOOL_STATUS_FEAT_DISABLED:
 		printf_color(ANSI_BOLD, gettext("status: "));
-		printf_color(ANSI_YELLOW, gettext("Some supported features are "
-		    "not enabled on the pool. The pool can\n\tstill be used, "
-		    "but some features are unavailable.\n"));
+		printf_color(ANSI_YELLOW, gettext("Some supported and "
+		    "requested features are not enabled on the pool.\n\t"
+		    "The pool can still be used, but some features are "
+		    "unavailable.\n"));
 		printf_color(ANSI_BOLD, gettext("action: "));
 		printf_color(ANSI_YELLOW, gettext("Enable all features using "
 		    "'zpool upgrade'. Once this is done,\n\tthe pool may no "
@@ -8127,6 +8178,19 @@ status_callback(zpool_handle_t *zhp, void *data)
 		    "the features. See zpool-features(5) for details.\n"));
 		break;
 
+	case ZPOOL_STATUS_COMPATIBILITY_ERR:
+		printf_color(ANSI_BOLD, gettext("status: "));
+		printf_color(ANSI_YELLOW, gettext("This pool has a "
+		    "compatibility list specified, but it could not be\n\t"
+		    "read/parsed at this time. The pool can still be used, "
+		    "but this\n\tshould be investigated.\n"));
+		printf_color(ANSI_BOLD, gettext("action: "));
+		printf_color(ANSI_YELLOW, gettext("Check the value of the "
+		    "'compatibility' property against the\n\t"
+		    "appropriate file in " ZPOOL_SYSCONF_COMPAT_D " or "
+		    ZPOOL_DATA_COMPAT_D ".\n"));
+		break;
+
 	case ZPOOL_STATUS_UNSUP_FEAT_READ:
 		printf_color(ANSI_BOLD, gettext("status: "));
 		printf_color(ANSI_YELLOW, gettext("The pool cannot be accessed "
@@ -8625,11 +8689,25 @@ upgrade_enable_all(zpool_handle_t *zhp, int *countp)
 	boolean_t firstff = B_TRUE;
 	nvlist_t *enabled = zpool_get_features(zhp);
 
+	char compat[ZFS_MAXPROPLEN];
+	if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compat,
+	    ZFS_MAXPROPLEN, NULL, B_FALSE) != 0)
+		compat[0] = '\0';
+
+	boolean_t requested_features[SPA_FEATURES];
+	if (zpool_do_load_compat(compat, requested_features) !=
+	    ZPOOL_COMPATIBILITY_OK)
+		return (-1);
+
 	count = 0;
 	for (i = 0; i < SPA_FEATURES; i++) {
 		const char *fname = spa_feature_table[i].fi_uname;
 		const char *fguid = spa_feature_table[i].fi_guid;
-		if (!nvlist_exists(enabled, fguid)) {
+
+		if (!spa_feature_table[i].fi_zfs_mod_supported)
+			continue;
+
+		if (!nvlist_exists(enabled, fguid) && requested_features[i]) {
 			char *propname;
 			verify(-1 != asprintf(&propname, "feature@%s", fname));
 			ret = zpool_set_prop(zhp, propname,
@@ -8759,6 +8837,10 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
 		for (i = 0; i < SPA_FEATURES; i++) {
 			const char *fguid = spa_feature_table[i].fi_guid;
 			const char *fname = spa_feature_table[i].fi_uname;
+
+			if (!spa_feature_table[i].fi_zfs_mod_supported)
+				continue;
+
 			if (!nvlist_exists(enabled, fguid)) {
 				if (cbp->cb_first) {
 					(void) printf(gettext("\nSome "
@@ -8847,7 +8929,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
 			printnl = B_TRUE;
 		} else if (cur_version == SPA_VERSION) {
 			(void) printf(gettext("Pool '%s' already has all "
-			    "supported features enabled.\n"),
+			    "supported and requested features enabled.\n"),
 			    zpool_get_name(zhp));
 		}
 	}
@@ -9008,8 +9090,8 @@ zpool_do_upgrade(int argc, char **argv)
 				(void) printf(gettext("All pools are already "
 				    "formatted using feature flags.\n\n"));
 				(void) printf(gettext("Every feature flags "
-				    "pool already has all supported features "
-				    "enabled.\n"));
+				    "pool already has all supported and "
+				    "requested features enabled.\n"));
 			} else {
 				(void) printf(gettext("All pools are already "
 				    "formatted with version %llu or higher.\n"),
@@ -9035,7 +9117,7 @@ zpool_do_upgrade(int argc, char **argv)
 
 		if (cb.cb_first) {
 			(void) printf(gettext("Every feature flags pool has "
-			    "all supported features enabled.\n"));
+			    "all supported and requested features enabled.\n"));
 		} else {
 			(void) printf(gettext("\n"));
 		}
@@ -10339,6 +10421,39 @@ zpool_do_version(int argc, char **argv)
 	return (0);
 }
 
+/*
+ * Do zpool_load_compat() and print error message on failure
+ */
+static zpool_compat_status_t
+zpool_do_load_compat(const char *compat, boolean_t *list)
+{
+	char badword[ZFS_MAXPROPLEN];
+	char badfile[MAXPATHLEN];
+	zpool_compat_status_t ret;
+
+	switch (ret = zpool_load_compat(compat, list, badword, badfile)) {
+	case ZPOOL_COMPATIBILITY_OK:
+		break;
+	case ZPOOL_COMPATIBILITY_READERR:
+		(void) fprintf(stderr, gettext("error reading compatibility "
+		    "file '%s'\n"), badfile);
+		break;
+	case ZPOOL_COMPATIBILITY_BADFILE:
+		(void) fprintf(stderr, gettext("compatibility file '%s' "
+		    "too large or not newline-terminated\n"), badfile);
+		break;
+	case ZPOOL_COMPATIBILITY_BADWORD:
+		(void) fprintf(stderr, gettext("unknown feature '%s' in "
+		    "compatibility file '%s'\n"), badword, badfile);
+		break;
+	case ZPOOL_COMPATIBILITY_NOFILES:
+		(void) fprintf(stderr, gettext("no compatibility files "
+		    "specified\n"));
+		break;
+	}
+	return (ret);
+}
+
 int
 main(int argc, char **argv)
 {
diff --git a/sys/contrib/openzfs/cmd/ztest/ztest.c b/sys/contrib/openzfs/cmd/ztest/ztest.c
index ab20a635d55a..d2bf0101993e 100644
--- a/sys/contrib/openzfs/cmd/ztest/ztest.c
+++ b/sys/contrib/openzfs/cmd/ztest/ztest.c
@@ -133,7 +133,7 @@
 #include <libnvpair.h>
 #include <libzutil.h>
 #include <sys/crypto/icp.h>
-#ifdef __GLIBC__
+#if (__GLIBC__ && !__UCLIBC__)
 #include <execinfo.h> /* for backtrace() */
 #endif
 
@@ -563,7 +563,7 @@ dump_debug_buffer(void)
 static void sig_handler(int signo)
 {
 	struct sigaction action;
-#ifdef __GLIBC__ /* backtrace() is a GNU extension */
+#if (__GLIBC__ && !__UCLIBC__) /* backtrace() is a GNU extension */
 	int nptrs;
 	void *buffer[BACKTRACE_SZ];
 
diff --git a/sys/contrib/openzfs/config/Rules.am b/sys/contrib/openzfs/config/Rules.am
index e9cd134edea8..99587eab2bf8 100644
--- a/sys/contrib/openzfs/config/Rules.am
+++ b/sys/contrib/openzfs/config/Rules.am
@@ -44,6 +44,7 @@ AM_CPPFLAGS += -DLIBEXECDIR=\"$(libexecdir)\"
 AM_CPPFLAGS += -DRUNSTATEDIR=\"$(runstatedir)\"
 AM_CPPFLAGS += -DSBINDIR=\"$(sbindir)\"
 AM_CPPFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\"
+AM_CPPFLAGS += -DPKGDATADIR=\"$(pkgdatadir)\"
 AM_CPPFLAGS += $(DEBUG_CPPFLAGS)
 AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
 if BUILD_LINUX
diff --git a/sys/contrib/openzfs/include/libzfs.h b/sys/contrib/openzfs/include/libzfs.h
index 66cedd0ee0fe..5f0bc03be144 100644
--- a/sys/contrib/openzfs/include/libzfs.h
+++ b/sys/contrib/openzfs/include/libzfs.h
@@ -28,6 +28,7 @@
  * Copyright 2016 Nexenta Systems, Inc.
  * Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
  * Copyright (c) 2019 Datto Inc.
+ * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
  */
 
 #ifndef	_LIBZFS_H
@@ -391,6 +392,7 @@ typedef enum {
 	ZPOOL_STATUS_REBUILDING,	/* device being rebuilt */
 	ZPOOL_STATUS_REBUILD_SCRUB,	/* recommend scrubbing the pool */
 	ZPOOL_STATUS_NON_NATIVE_ASHIFT,	/* (e.g. 512e dev with ashift of 9) */
+	ZPOOL_STATUS_COMPATIBILITY_ERR,	/* bad 'compatibility' property */
 
 	/*
 	 * Finally, the following indicates a healthy pool.
@@ -912,6 +914,20 @@ int zfs_smb_acl_rename(libzfs_handle_t *, char *, char *, char *, char *);
 extern int zpool_enable_datasets(zpool_handle_t *, const char *, int);
 extern int zpool_disable_datasets(zpool_handle_t *, boolean_t);
 
+/*
+ * Parse a features file for -o compatibility
+ */
+typedef enum {
+	ZPOOL_COMPATIBILITY_OK,
+	ZPOOL_COMPATIBILITY_READERR,
+	ZPOOL_COMPATIBILITY_BADFILE,
+	ZPOOL_COMPATIBILITY_BADWORD,
+	ZPOOL_COMPATIBILITY_NOFILES
+} zpool_compat_status_t;
+
+extern zpool_compat_status_t zpool_load_compat(const char *,
+    boolean_t *, char *, char *);
+
 #ifdef __FreeBSD__
 
 /*
diff --git a/sys/contrib/openzfs/include/sys/fs/zfs.h b/sys/contrib/openzfs/include/sys/fs/zfs.h
index 65515e3829f3..71d736d5cc97 100644
--- a/sys/contrib/openzfs/include/sys/fs/zfs.h
*** 9816 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202103100936.12A9ab6e013913>