aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/zpool/zpool_main.c3
-rw-r--r--lib/libzfs/libzfs_pool.c51
2 files changed, 50 insertions, 4 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index a13ff5ebd..3ac372866 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -1653,7 +1653,8 @@ zpool_do_create(int argc, char **argv)
if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
(void) nvlist_remove_all(props,
propname);
- } else if (enable_all_pool_feat) {
+ } else if (enable_all_pool_feat &&
+ feat->fi_zfs_mod_supported) {
ret = add_prop_list(propname,
ZFS_FEATURE_ENABLED, &props, B_TRUE);
if (ret != 0)
diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c
index c661ab313..af374fca3 100644
--- a/lib/libzfs/libzfs_pool.c
+++ b/lib/libzfs/libzfs_pool.c
@@ -1189,6 +1189,30 @@ zpool_has_special_vdev(nvlist_t *nvroot)
}
/*
+ * Check if vdev list contains a dRAID vdev
+ */
+static boolean_t
+zpool_has_draid_vdev(nvlist_t *nvroot)
+{
+ nvlist_t **child;
+ uint_t children;
+
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
+ &child, &children) == 0) {
+ for (uint_t c = 0; c < children; c++) {
+ char *type;
+
+ if (nvlist_lookup_string(child[c],
+ ZPOOL_CONFIG_TYPE, &type) == 0 &&
+ strcmp(type, VDEV_TYPE_DRAID) == 0) {
+ return (B_TRUE);
+ }
+ }
+ }
+ return (B_FALSE);
+}
+
+/*
* Output a dRAID top-level vdev name in to the provided buffer.
*/
static char *
@@ -1373,6 +1397,17 @@ zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
"one or more devices is out of space"));
return (zfs_error(hdl, EZFS_BADDEV, msg));
+ case EINVAL:
+ if (zpool_has_draid_vdev(nvroot) &&
+ zfeature_lookup_name("draid", NULL) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dRAID vdevs are unsupported by the "
+ "kernel"));
+ return (zfs_error(hdl, EZFS_BADDEV, msg));
+ } else {
+ return (zpool_standard_error(hdl, errno, msg));
+ }
+
default:
return (zpool_standard_error(hdl, errno, msg));
}
@@ -1528,9 +1563,19 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
break;
case EINVAL:
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid config; a pool with removing/removed "
- "vdevs does not support adding raidz vdevs"));
+
+ if (zpool_has_draid_vdev(nvroot) &&
+ zfeature_lookup_name("draid", NULL) != 0) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "dRAID vdevs are unsupported by the "
+ "kernel"));
+ } else {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "invalid config; a pool with removing/"
+ "removed vdevs does not support adding "
+ "raidz or dRAID vdevs"));
+ }
+
(void) zfs_error(hdl, EZFS_BADDEV, msg);
break;