aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/zpool/zpool_main.c
diff options
context:
space:
mode:
authorAttila Fülöp <[email protected]>2020-12-04 23:04:39 +0100
committerBrian Behlendorf <[email protected]>2021-01-08 15:37:56 -0800
commit6539bf71fe0efb610bd7957e7e9c5ea153397739 (patch)
treeb9c31ecf10cd9320b503a11ad020416fb23518ff /cmd/zpool/zpool_main.c
parent32a78e579dd3395e122a451848cf88089f6b18ae (diff)
zpool: Dryrun fails to list some devices
`zpool create -n` fails to list cache and spare vdevs. `zpool add -n` fails to list spare devices. `zpool split -n` fails to list `special` and `dedup` labels. `zpool add -n` and `zpool split -n` shouldn't list hole devices. Reviewed-by: Ryan Moeller <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Attila Fülöp <[email protected]> Closes #11122 Closes #11167
Diffstat (limited to 'cmd/zpool/zpool_main.c')
-rw-r--r--cmd/zpool/zpool_main.c94
1 files changed, 89 insertions, 5 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c
index 2ddb0f66b..fbea83c38 100644
--- a/cmd/zpool/zpool_main.c
+++ b/cmd/zpool/zpool_main.c
@@ -669,9 +669,16 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
}
for (c = 0; c < children; c++) {
- uint64_t is_log = B_FALSE;
+ uint64_t is_log = B_FALSE, is_hole = B_FALSE;
char *class = "";
+ (void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
+ &is_hole);
+
+ if (is_hole == B_TRUE) {
+ continue;
+ }
+
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
&is_log);
if (is_log)
@@ -692,6 +699,54 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
}
}
+/*
+ * Print the list of l2cache devices for dry runs.
+ */
+static void
+print_cache_list(nvlist_t *nv, int indent)
+{
+ nvlist_t **child;
+ uint_t c, children;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+ &child, &children) == 0 && children > 0) {
+ (void) printf("\t%*s%s\n", indent, "", "cache");
+ } else {
+ return;
+ }
+ for (c = 0; c < children; c++) {
+ char *vname;
+
+ vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
+ (void) printf("\t%*s%s\n", indent + 2, "", vname);
+ free(vname);
+ }
+}
+
+/*
+ * Print the list of spares for dry runs.
+ */
+static void
+print_spare_list(nvlist_t *nv, int indent)
+{
+ nvlist_t **child;
+ uint_t c, children;
+
+ if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
+ &child, &children) == 0 && children > 0) {
+ (void) printf("\t%*s%s\n", indent, "", "spares");
+ } else {
+ return;
+ }
+ for (c = 0; c < children; c++) {
+ char *vname;
+
+ vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
+ (void) printf("\t%*s%s\n", indent + 2, "", vname);
+ free(vname);
+ }
+}
+
static boolean_t
prop_list_contains_feature(nvlist_t *proplist)
{
@@ -921,16 +976,16 @@ zpool_do_add(int argc, char **argv)
if (dryrun) {
nvlist_t *poolnvroot;
- nvlist_t **l2child;
- uint_t l2children, c;
+ nvlist_t **l2child, **sparechild;
+ uint_t l2children, sparechildren, c;
char *vname;
- boolean_t hadcache = B_FALSE;
+ boolean_t hadcache = B_FALSE, hadspare = B_FALSE;
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
&poolnvroot) == 0);
(void) printf(gettext("would update '%s' to the following "
- "configuration:\n"), zpool_get_name(zhp));
+ "configuration:\n\n"), zpool_get_name(zhp));
/* print original main pool and new tree */
print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
@@ -991,6 +1046,29 @@ zpool_do_add(int argc, char **argv)
free(vname);
}
}
+ /* And finaly the spares */
+ if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_SPARES,
+ &sparechild, &sparechildren) == 0 && sparechildren > 0) {
+ hadspare = B_TRUE;
+ (void) printf(gettext("\tspares\n"));
+ for (c = 0; c < sparechildren; c++) {
+ vname = zpool_vdev_name(g_zfs, NULL,
+ sparechild[c], name_flags);
+ (void) printf("\t %s\n", vname);
+ free(vname);
+ }
+ }
+ if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
+ &sparechild, &sparechildren) == 0 && sparechildren > 0) {
+ if (!hadspare)
+ (void) printf(gettext("\tspares\n"));
+ for (c = 0; c < sparechildren; c++) {
+ vname = zpool_vdev_name(g_zfs, NULL,
+ sparechild[c], name_flags);
+ (void) printf("\t %s\n", vname);
+ free(vname);
+ }
+ }
ret = 0;
} else {
@@ -1548,6 +1626,8 @@ zpool_do_create(int argc, char **argv)
VDEV_ALLOC_BIAS_SPECIAL, 0);
print_vdev_tree(NULL, "logs", nvroot, 0,
VDEV_ALLOC_BIAS_LOG, 0);
+ print_cache_list(nvroot, 0);
+ print_spare_list(nvroot, 0);
ret = 0;
} else {
@@ -6515,6 +6595,10 @@ zpool_do_split(int argc, char **argv)
"following layout:\n\n"), newpool);
print_vdev_tree(NULL, newpool, config, 0, "",
flags.name_flags);
+ print_vdev_tree(NULL, "dedup", config, 0,
+ VDEV_ALLOC_BIAS_DEDUP, 0);
+ print_vdev_tree(NULL, "special", config, 0,
+ VDEV_ALLOC_BIAS_SPECIAL, 0);
}
}