Skip to content

Commit 0cb40fa

Browse files
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 openzfs#11122 Closes openzfs#11167
1 parent 4b6e2a5 commit 0cb40fa

File tree

10 files changed

+593
-14
lines changed

10 files changed

+593
-14
lines changed

cmd/zpool/zpool_main.c

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,16 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
669669
}
670670

671671
for (c = 0; c < children; c++) {
672-
uint64_t is_log = B_FALSE;
672+
uint64_t is_log = B_FALSE, is_hole = B_FALSE;
673673
char *class = "";
674674

675+
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_HOLE,
676+
&is_hole);
677+
678+
if (is_hole == B_TRUE) {
679+
continue;
680+
}
681+
675682
(void) nvlist_lookup_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
676683
&is_log);
677684
if (is_log)
@@ -692,6 +699,54 @@ print_vdev_tree(zpool_handle_t *zhp, const char *name, nvlist_t *nv, int indent,
692699
}
693700
}
694701

702+
/*
703+
* Print the list of l2cache devices for dry runs.
704+
*/
705+
static void
706+
print_cache_list(nvlist_t *nv, int indent)
707+
{
708+
nvlist_t **child;
709+
uint_t c, children;
710+
711+
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
712+
&child, &children) == 0 && children > 0) {
713+
(void) printf("\t%*s%s\n", indent, "", "cache");
714+
} else {
715+
return;
716+
}
717+
for (c = 0; c < children; c++) {
718+
char *vname;
719+
720+
vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
721+
(void) printf("\t%*s%s\n", indent + 2, "", vname);
722+
free(vname);
723+
}
724+
}
725+
726+
/*
727+
* Print the list of spares for dry runs.
728+
*/
729+
static void
730+
print_spare_list(nvlist_t *nv, int indent)
731+
{
732+
nvlist_t **child;
733+
uint_t c, children;
734+
735+
if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES,
736+
&child, &children) == 0 && children > 0) {
737+
(void) printf("\t%*s%s\n", indent, "", "spares");
738+
} else {
739+
return;
740+
}
741+
for (c = 0; c < children; c++) {
742+
char *vname;
743+
744+
vname = zpool_vdev_name(g_zfs, NULL, child[c], 0);
745+
(void) printf("\t%*s%s\n", indent + 2, "", vname);
746+
free(vname);
747+
}
748+
}
749+
695750
static boolean_t
696751
prop_list_contains_feature(nvlist_t *proplist)
697752
{
@@ -921,16 +976,16 @@ zpool_do_add(int argc, char **argv)
921976

922977
if (dryrun) {
923978
nvlist_t *poolnvroot;
924-
nvlist_t **l2child;
925-
uint_t l2children, c;
979+
nvlist_t **l2child, **sparechild;
980+
uint_t l2children, sparechildren, c;
926981
char *vname;
927-
boolean_t hadcache = B_FALSE;
982+
boolean_t hadcache = B_FALSE, hadspare = B_FALSE;
928983

929984
verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
930985
&poolnvroot) == 0);
931986

932987
(void) printf(gettext("would update '%s' to the following "
933-
"configuration:\n"), zpool_get_name(zhp));
988+
"configuration:\n\n"), zpool_get_name(zhp));
934989

935990
/* print original main pool and new tree */
936991
print_vdev_tree(zhp, poolname, poolnvroot, 0, "",
@@ -991,6 +1046,29 @@ zpool_do_add(int argc, char **argv)
9911046
free(vname);
9921047
}
9931048
}
1049+
/* And finaly the spares */
1050+
if (nvlist_lookup_nvlist_array(poolnvroot, ZPOOL_CONFIG_SPARES,
1051+
&sparechild, &sparechildren) == 0 && sparechildren > 0) {
1052+
hadspare = B_TRUE;
1053+
(void) printf(gettext("\tspares\n"));
1054+
for (c = 0; c < sparechildren; c++) {
1055+
vname = zpool_vdev_name(g_zfs, NULL,
1056+
sparechild[c], name_flags);
1057+
(void) printf("\t %s\n", vname);
1058+
free(vname);
1059+
}
1060+
}
1061+
if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES,
1062+
&sparechild, &sparechildren) == 0 && sparechildren > 0) {
1063+
if (!hadspare)
1064+
(void) printf(gettext("\tspares\n"));
1065+
for (c = 0; c < sparechildren; c++) {
1066+
vname = zpool_vdev_name(g_zfs, NULL,
1067+
sparechild[c], name_flags);
1068+
(void) printf("\t %s\n", vname);
1069+
free(vname);
1070+
}
1071+
}
9941072

9951073
ret = 0;
9961074
} else {
@@ -1548,6 +1626,8 @@ zpool_do_create(int argc, char **argv)
15481626
VDEV_ALLOC_BIAS_SPECIAL, 0);
15491627
print_vdev_tree(NULL, "logs", nvroot, 0,
15501628
VDEV_ALLOC_BIAS_LOG, 0);
1629+
print_cache_list(nvroot, 0);
1630+
print_spare_list(nvroot, 0);
15511631

15521632
ret = 0;
15531633
} else {
@@ -6515,6 +6595,10 @@ zpool_do_split(int argc, char **argv)
65156595
"following layout:\n\n"), newpool);
65166596
print_vdev_tree(NULL, newpool, config, 0, "",
65176597
flags.name_flags);
6598+
print_vdev_tree(NULL, "dedup", config, 0,
6599+
VDEV_ALLOC_BIAS_DEDUP, 0);
6600+
print_vdev_tree(NULL, "special", config, 0,
6601+
VDEV_ALLOC_BIAS_SPECIAL, 0);
65186602
}
65196603
}
65206604

lib/libzfs/libzfs_pool.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3431,7 +3431,7 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
34313431
nvlist_t *props, splitflags_t flags)
34323432
{
34333433
zfs_cmd_t zc = {"\0"};
3434-
char msg[1024];
3434+
char msg[1024], *bias;
34353435
nvlist_t *tree, *config, **child, **newchild, *newconfig = NULL;
34363436
nvlist_t **varray = NULL, *zc_props = NULL;
34373437
uint_t c, children, newchildren, lastlog = 0, vcount, found = 0;
@@ -3489,6 +3489,7 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
34893489

34903490
for (c = 0; c < children; c++) {
34913491
uint64_t is_log = B_FALSE, is_hole = B_FALSE;
3492+
boolean_t is_special = B_FALSE, is_dedup = B_FALSE;
34923493
char *type;
34933494
nvlist_t **mchild, *vdev;
34943495
uint_t mchildren;
@@ -3535,6 +3536,13 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
35353536
goto out;
35363537
}
35373538

3539+
if (nvlist_lookup_string(child[c],
3540+
ZPOOL_CONFIG_ALLOCATION_BIAS, &bias) == 0) {
3541+
if (strcmp(bias, VDEV_ALLOC_BIAS_SPECIAL) == 0)
3542+
is_special = B_TRUE;
3543+
else if (strcmp(bias, VDEV_ALLOC_BIAS_DEDUP) == 0)
3544+
is_dedup = B_TRUE;
3545+
}
35383546
verify(nvlist_lookup_nvlist_array(child[c],
35393547
ZPOOL_CONFIG_CHILDREN, &mchild, &mchildren) == 0);
35403548

@@ -3552,6 +3560,20 @@ zpool_vdev_split(zpool_handle_t *zhp, char *newname, nvlist_t **newroot,
35523560

35533561
if (nvlist_dup(vdev, &varray[vcount++], 0) != 0)
35543562
goto out;
3563+
3564+
if (flags.dryrun != 0) {
3565+
if (is_dedup == B_TRUE) {
3566+
if (nvlist_add_string(varray[vcount - 1],
3567+
ZPOOL_CONFIG_ALLOCATION_BIAS,
3568+
VDEV_ALLOC_BIAS_DEDUP) != 0)
3569+
goto out;
3570+
} else if (is_special == B_TRUE) {
3571+
if (nvlist_add_string(varray[vcount - 1],
3572+
ZPOOL_CONFIG_ALLOCATION_BIAS,
3573+
VDEV_ALLOC_BIAS_SPECIAL) != 0)
3574+
goto out;
3575+
}
3576+
}
35553577
}
35563578

35573579
/* did we find every disk the user specified? */

tests/runfiles/common.run

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ tags = ['functional', 'cli_root', 'zpool']
318318
tests = ['zpool_add_001_pos', 'zpool_add_002_pos', 'zpool_add_003_pos',
319319
'zpool_add_004_pos', 'zpool_add_006_pos', 'zpool_add_007_neg',
320320
'zpool_add_008_neg', 'zpool_add_009_neg', 'zpool_add_010_pos',
321-
'add-o_ashift', 'add_prop_ashift']
321+
'add-o_ashift', 'add_prop_ashift', 'zpool_add_dryrun_output']
322322
tags = ['functional', 'cli_root', 'zpool_add']
323323

324324
[tests/functional/cli_root/zpool_attach]
@@ -345,7 +345,7 @@ tests = ['zpool_create_001_pos', 'zpool_create_002_pos',
345345
'zpool_create_features_001_pos', 'zpool_create_features_002_pos',
346346
'zpool_create_features_003_pos', 'zpool_create_features_004_neg',
347347
'zpool_create_features_005_pos',
348-
'create-o_ashift', 'zpool_create_tempname']
348+
'create-o_ashift', 'zpool_create_tempname', 'zpool_create_dryrun_output']
349349
tags = ['functional', 'cli_root', 'zpool_create']
350350

351351
[tests/functional/cli_root/zpool_destroy]
@@ -462,7 +462,8 @@ tags = ['functional', 'cli_root', 'zpool_set']
462462
[tests/functional/cli_root/zpool_split]
463463
tests = ['zpool_split_cliargs', 'zpool_split_devices',
464464
'zpool_split_encryption', 'zpool_split_props', 'zpool_split_vdevs',
465-
'zpool_split_resilver', 'zpool_split_indirect']
465+
'zpool_split_resilver', 'zpool_split_indirect',
466+
'zpool_split_dryrun_output']
466467
tags = ['functional', 'cli_root', 'zpool_split']
467468

468469
[tests/functional/cli_root/zpool_status]

tests/zfs-tests/tests/functional/cli_root/zpool_add/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ dist_pkgdata_SCRIPTS = \
1414
zpool_add_010_pos.ksh \
1515
add-o_ashift.ksh \
1616
add_prop_ashift.ksh \
17-
add_nested_replacing_spare.ksh
17+
add_nested_replacing_spare.ksh \
18+
zpool_add_dryrun_output.ksh
1819

1920
dist_pkgdata_DATA = \
2021
zpool_add.cfg \

tests/zfs-tests/tests/functional/cli_root/zpool_add/zpool_add_003_pos.ksh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ log_onexit cleanup
6161
typeset TMPFILE_PREFIX="$TEST_BASE_DIR/zpool_add_003"
6262
typeset STR_DRYRUN="would update '$TESTPOOL' to the following configuration:"
6363
typeset VDEV_PREFIX="$TEST_BASE_DIR/filedev"
64-
typeset -a VDEV_TYPES=("" "dedup" "special" "log" "cache")
64+
typeset -a VDEV_TYPES=("" "dedup" "special" "log" "cache" "spare")
6565

6666
vdevs=""
6767
config=""
@@ -91,7 +91,7 @@ log_must zpool add -f $TESTPOOL $config
9191
zpool status $TESTPOOL | awk 'NR == 1, /NAME/ { next } /^$/ {exit}
9292
{print $1}' > "$TMPFILE_PREFIX-vdevtree"
9393
cat "$TMPFILE_PREFIX-dryrun" | awk 'NR == 1, /would/ {next}
94-
{print $1}' > "$TMPFILE_PREFIX-vdevtree-n"
94+
/^$/ {next} {print $1}' > "$TMPFILE_PREFIX-vdevtree-n"
9595
log_must eval "diff $TMPFILE_PREFIX-vdevtree-n $TMPFILE_PREFIX-vdevtree"
9696

9797
log_pass "'zpool add -n <pool> <vdev> ...' executes successfully."

0 commit comments

Comments
 (0)