diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index a13ff5ebdf..3ac3728667 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 c661ab3131..af374fca36 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -1188,6 +1188,30 @@ zpool_has_special_vdev(nvlist_t *nvroot) return (B_FALSE); } +/* + * 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. */ @@ -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;