Only add supported features during pool creation

When creating a pool only features supported by both user and
kernel space should be enabled.  Furthermore, improve the error
messages when attempting to create, or add, a dRAID vdev when
the dRAID feature is not supported by the kernel modules.

Reviewed-by: Mark Maybee <mark.maybee@delphix.com>
Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #11492
This commit is contained in:
Brian Behlendorf 2021-01-22 09:47:06 -08:00 committed by GitHub
parent aa755b3549
commit 76e1f78d4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 4 deletions

View File

@ -1653,7 +1653,8 @@ zpool_do_create(int argc, char **argv)
if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0) if (strcmp(propval, ZFS_FEATURE_DISABLED) == 0)
(void) nvlist_remove_all(props, (void) nvlist_remove_all(props,
propname); propname);
} else if (enable_all_pool_feat) { } else if (enable_all_pool_feat &&
feat->fi_zfs_mod_supported) {
ret = add_prop_list(propname, ret = add_prop_list(propname,
ZFS_FEATURE_ENABLED, &props, B_TRUE); ZFS_FEATURE_ENABLED, &props, B_TRUE);
if (ret != 0) if (ret != 0)

View File

@ -1188,6 +1188,30 @@ zpool_has_special_vdev(nvlist_t *nvroot)
return (B_FALSE); 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. * 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")); "one or more devices is out of space"));
return (zfs_error(hdl, EZFS_BADDEV, msg)); 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: default:
return (zpool_standard_error(hdl, errno, msg)); return (zpool_standard_error(hdl, errno, msg));
} }
@ -1528,9 +1563,19 @@ zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
break; break;
case EINVAL: case EINVAL:
if (zpool_has_draid_vdev(nvroot) &&
zfeature_lookup_name("draid", NULL) != 0) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid config; a pool with removing/removed " "dRAID vdevs are unsupported by the "
"vdevs does not support adding raidz vdevs")); "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); (void) zfs_error(hdl, EZFS_BADDEV, msg);
break; break;