zpool: Provide GUID to zpool-reguid(8) with -g (#16239)

This commit extends the zpool-reguid(8) command with a -g flag, which
allows the user to specify the GUID to set.

This change also adds some general tests for zpool-reguid(8).

Sponsored-by: Wasabi Technology, Inc.
Sponsored-by: Klara, Inc.

Signed-off-by: Mateusz Piotrowski <0mp@FreeBSD.org>
Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
This commit is contained in:
Mateusz Piotrowski 2024-08-26 18:27:24 +02:00 committed by GitHub
parent 2420ee6e12
commit 6be8bf5552
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 342 additions and 16 deletions

View File

@ -537,7 +537,7 @@ get_usage(zpool_help_t idx)
"\t [-o property=value] <pool> <newpool> " "\t [-o property=value] <pool> <newpool> "
"[<device> ...]\n")); "[<device> ...]\n"));
case HELP_REGUID: case HELP_REGUID:
return (gettext("\treguid <pool>\n")); return (gettext("\treguid [-g guid] <pool>\n"));
case HELP_SYNC: case HELP_SYNC:
return (gettext("\tsync [pool] ...\n")); return (gettext("\tsync [pool] ...\n"));
case HELP_VERSION: case HELP_VERSION:
@ -2025,7 +2025,7 @@ zpool_do_create(int argc, char **argv)
char *end; char *end;
u_longlong_t ver; u_longlong_t ver;
ver = strtoull(propval, &end, 10); ver = strtoull(propval, &end, 0);
if (*end == '\0' && if (*end == '\0' &&
ver < SPA_VERSION_FEATURES) { ver < SPA_VERSION_FEATURES) {
enable_pool_features = B_FALSE; enable_pool_features = B_FALSE;
@ -8232,19 +8232,32 @@ zpool_do_clear(int argc, char **argv)
} }
/* /*
* zpool reguid <pool> * zpool reguid [-g <guid>] <pool>
*/ */
int int
zpool_do_reguid(int argc, char **argv) zpool_do_reguid(int argc, char **argv)
{ {
uint64_t guid;
uint64_t *guidp = NULL;
int c; int c;
char *endptr;
char *poolname; char *poolname;
zpool_handle_t *zhp; zpool_handle_t *zhp;
int ret = 0; int ret = 0;
/* check options */ /* check options */
while ((c = getopt(argc, argv, "")) != -1) { while ((c = getopt(argc, argv, "g:")) != -1) {
switch (c) { switch (c) {
case 'g':
errno = 0;
guid = strtoull(optarg, &endptr, 10);
if (errno != 0 || *endptr != '\0') {
(void) fprintf(stderr,
gettext("invalid GUID: %s\n"), optarg);
usage(B_FALSE);
}
guidp = &guid;
break;
case '?': case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"), (void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt); optopt);
@ -8270,7 +8283,7 @@ zpool_do_reguid(int argc, char **argv)
if ((zhp = zpool_open(g_zfs, poolname)) == NULL) if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
return (1); return (1);
ret = zpool_reguid(zhp); ret = zpool_set_guid(zhp, guidp);
zpool_close(zhp); zpool_close(zhp);
return (ret); return (ret);

View File

@ -6746,7 +6746,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id)
load = spa_load_guid(spa); load = spa_load_guid(spa);
(void) pthread_rwlock_wrlock(&ztest_name_lock); (void) pthread_rwlock_wrlock(&ztest_name_lock);
error = spa_change_guid(spa); error = spa_change_guid(spa, NULL);
zs->zs_guid = spa_guid(spa); zs->zs_guid = spa_guid(spa);
(void) pthread_rwlock_unlock(&ztest_name_lock); (void) pthread_rwlock_unlock(&ztest_name_lock);

View File

@ -300,6 +300,7 @@ _LIBZFS_H int zpool_trim(zpool_handle_t *, pool_trim_func_t, nvlist_t *,
_LIBZFS_H int zpool_clear(zpool_handle_t *, const char *, nvlist_t *); _LIBZFS_H int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
_LIBZFS_H int zpool_reguid(zpool_handle_t *); _LIBZFS_H int zpool_reguid(zpool_handle_t *);
_LIBZFS_H int zpool_set_guid(zpool_handle_t *, const uint64_t *);
_LIBZFS_H int zpool_reopen_one(zpool_handle_t *, void *); _LIBZFS_H int zpool_reopen_one(zpool_handle_t *, void *);
_LIBZFS_H int zpool_sync_one(zpool_handle_t *, void *); _LIBZFS_H int zpool_sync_one(zpool_handle_t *, void *);

View File

@ -1710,6 +1710,11 @@ typedef enum {
#define ZPOOL_INITIALIZE_COMMAND "initialize_command" #define ZPOOL_INITIALIZE_COMMAND "initialize_command"
#define ZPOOL_INITIALIZE_VDEVS "initialize_vdevs" #define ZPOOL_INITIALIZE_VDEVS "initialize_vdevs"
/*
* The following are names used when invoking ZFS_IOC_POOL_REGUID.
*/
#define ZPOOL_REGUID_GUID "guid"
/* /*
* The following are names used when invoking ZFS_IOC_POOL_TRIM. * The following are names used when invoking ZFS_IOC_POOL_TRIM.
*/ */

View File

@ -1092,7 +1092,7 @@ extern void spa_strfree(char *);
extern uint64_t spa_generate_guid(spa_t *spa); extern uint64_t spa_generate_guid(spa_t *spa);
extern void snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp); extern void snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp);
extern void spa_freeze(spa_t *spa); extern void spa_freeze(spa_t *spa);
extern int spa_change_guid(spa_t *spa); extern int spa_change_guid(spa_t *spa, const uint64_t *guidp);
extern void spa_upgrade(spa_t *spa, uint64_t version); extern void spa_upgrade(spa_t *spa, uint64_t version);
extern void spa_evict_all(void); extern void spa_evict_all(void);
extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid, extern vdev_t *spa_lookup_by_guid(spa_t *spa, uint64_t guid,

View File

@ -556,6 +556,7 @@
<elf-symbol name='zpool_scan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_scan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_search_import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_search_import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_set_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_set_bootenv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_set_guid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_set_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_set_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_set_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_set_vdev_prop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
<elf-symbol name='zpool_skip_pool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> <elf-symbol name='zpool_skip_pool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
@ -6639,6 +6640,11 @@
<parameter type-id='9c313c2d' name='guid'/> <parameter type-id='9c313c2d' name='guid'/>
<return type-id='95e97e5e'/> <return type-id='95e97e5e'/>
</function-decl> </function-decl>
<function-decl name='zpool_set_guid' mangled-name='zpool_set_guid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_set_guid'>
<parameter type-id='4c81de99' name='zhp'/>
<parameter type-id='713a56f5' name='guid'/>
<return type-id='95e97e5e'/>
</function-decl>
<function-decl name='zpool_reguid' mangled-name='zpool_reguid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_reguid'> <function-decl name='zpool_reguid' mangled-name='zpool_reguid' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='zpool_reguid'>
<parameter type-id='4c81de99' name='zhp'/> <parameter type-id='4c81de99' name='zhp'/>
<return type-id='95e97e5e'/> <return type-id='95e97e5e'/>

View File

@ -4310,22 +4310,55 @@ zpool_vdev_clear(zpool_handle_t *zhp, uint64_t guid)
/* /*
* Change the GUID for a pool. * Change the GUID for a pool.
*
* Similar to zpool_reguid(), but may take a GUID.
*
* If the guid argument is NULL, then no GUID is passed in the nvlist to the
* ioctl().
*/ */
int int
zpool_reguid(zpool_handle_t *zhp) zpool_set_guid(zpool_handle_t *zhp, const uint64_t *guid)
{ {
char errbuf[ERRBUFLEN]; char errbuf[ERRBUFLEN];
libzfs_handle_t *hdl = zhp->zpool_hdl; libzfs_handle_t *hdl = zhp->zpool_hdl;
nvlist_t *nvl = NULL;
zfs_cmd_t zc = {"\0"}; zfs_cmd_t zc = {"\0"};
int error = -1;
if (guid != NULL) {
if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
return (no_memory(hdl));
if (nvlist_add_uint64(nvl, ZPOOL_REGUID_GUID, *guid) != 0) {
nvlist_free(nvl);
return (no_memory(hdl));
}
zcmd_write_src_nvlist(hdl, &zc, nvl);
}
(void) snprintf(errbuf, sizeof (errbuf), (void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name); dgettext(TEXT_DOMAIN, "cannot reguid '%s'"), zhp->zpool_name);
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name)); (void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
if (zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc) == 0) error = zfs_ioctl(hdl, ZFS_IOC_POOL_REGUID, &zc);
return (0); if (error) {
return (zpool_standard_error(hdl, errno, errbuf));
}
if (guid != NULL) {
zcmd_free_nvlists(&zc);
nvlist_free(nvl);
}
return (0);
}
return (zpool_standard_error(hdl, errno, errbuf)); /*
* Change the GUID for a pool.
*/
int
zpool_reguid(zpool_handle_t *zhp)
{
return (zpool_set_guid(zhp, NULL));
} }
/* /*

View File

@ -25,8 +25,10 @@
.\" Copyright (c) 2018 George Melikov. All Rights Reserved. .\" Copyright (c) 2018 George Melikov. All Rights Reserved.
.\" Copyright 2017 Nexenta Systems, Inc. .\" Copyright 2017 Nexenta Systems, Inc.
.\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved. .\" Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
.\" Copyright (c) 2024, Klara Inc.
.\" Copyright (c) 2024, Mateusz Piotrowski
.\" .\"
.Dd May 31, 2021 .Dd June 21, 2023
.Dt ZPOOL-REGUID 8 .Dt ZPOOL-REGUID 8
.Os .Os
. .
@ -36,6 +38,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm zpool .Nm zpool
.Cm reguid .Cm reguid
.Op Fl g Ar guid
.Ar pool .Ar pool
. .
.Sh DESCRIPTION .Sh DESCRIPTION
@ -43,6 +46,15 @@ Generates a new unique identifier for the pool.
You must ensure that all devices in this pool are online and healthy before You must ensure that all devices in this pool are online and healthy before
performing this action. performing this action.
. .
.Bl -tag -width Ds
.It Fl g Ar guid
Set the pool GUID to the provided value.
The GUID can be any 64-bit value accepted by
.Xr strtoull 3
in base 10.
.Nm
will return an error if the provided GUID is already in use.
.El
.Sh SEE ALSO .Sh SEE ALSO
.Xr zpool-export 8 , .Xr zpool-export 8 ,
.Xr zpool-import 8 .Xr zpool-import 8

View File

@ -1040,16 +1040,34 @@ spa_change_guid_sync(void *arg, dmu_tx_t *tx)
* online when we do this, or else any vdevs that weren't present * online when we do this, or else any vdevs that weren't present
* would be orphaned from our pool. We are also going to issue a * would be orphaned from our pool. We are also going to issue a
* sysevent to update any watchers. * sysevent to update any watchers.
*
* The GUID of the pool will be changed to the value pointed to by guidp.
* The GUID may not be set to the reserverd value of 0.
* The new GUID will be generated if guidp is NULL.
*/ */
int int
spa_change_guid(spa_t *spa) spa_change_guid(spa_t *spa, const uint64_t *guidp)
{ {
int error;
uint64_t guid; uint64_t guid;
int error;
mutex_enter(&spa->spa_vdev_top_lock); mutex_enter(&spa->spa_vdev_top_lock);
mutex_enter(&spa_namespace_lock); mutex_enter(&spa_namespace_lock);
guid = spa_generate_guid(NULL);
if (guidp != NULL) {
guid = *guidp;
if (guid == 0) {
error = SET_ERROR(EINVAL);
goto out;
}
if (spa_guid_exists(guid, 0)) {
error = SET_ERROR(EEXIST);
goto out;
}
} else {
guid = spa_generate_guid(NULL);
}
error = dsl_sync_task(spa->spa_name, spa_change_guid_check, error = dsl_sync_task(spa->spa_name, spa_change_guid_check,
spa_change_guid_sync, &guid, 5, ZFS_SPACE_CHECK_RESERVED); spa_change_guid_sync, &guid, 5, ZFS_SPACE_CHECK_RESERVED);
@ -1068,6 +1086,7 @@ spa_change_guid(spa_t *spa)
spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_REGUID); spa_event_notify(spa, NULL, NULL, ESC_ZFS_POOL_REGUID);
} }
out:
mutex_exit(&spa_namespace_lock); mutex_exit(&spa_namespace_lock);
mutex_exit(&spa->spa_vdev_top_lock); mutex_exit(&spa->spa_vdev_top_lock);

View File

@ -1794,17 +1794,45 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
return (error); return (error);
} }
/*
* inputs:
* zc_nvlist_src nvlist optionally containing ZPOOL_REGUID_GUID
* zc_nvlist_src_size size of the nvlist
*/
static int static int
zfs_ioc_pool_reguid(zfs_cmd_t *zc) zfs_ioc_pool_reguid(zfs_cmd_t *zc)
{ {
uint64_t *guidp = NULL;
nvlist_t *props = NULL;
spa_t *spa; spa_t *spa;
uint64_t guid;
int error; int error;
if (zc->zc_nvlist_src_size != 0) {
error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
zc->zc_iflags, &props);
if (error != 0)
return (error);
error = nvlist_lookup_uint64(props, ZPOOL_REGUID_GUID, &guid);
if (error == 0)
guidp = &guid;
else if (error == ENOENT)
guidp = NULL;
else
goto out;
}
error = spa_open(zc->zc_name, &spa, FTAG); error = spa_open(zc->zc_name, &spa, FTAG);
if (error == 0) { if (error == 0) {
error = spa_change_guid(spa); error = spa_change_guid(spa, guidp);
spa_close(spa, FTAG); spa_close(spa, FTAG);
} }
out:
if (props != NULL)
nvlist_free(props);
return (error); return (error);
} }

View File

@ -514,6 +514,10 @@ tags = ['functional', 'cli_root', 'zpool_offline']
tests = ['zpool_online_001_pos', 'zpool_online_002_neg'] tests = ['zpool_online_001_pos', 'zpool_online_002_neg']
tags = ['functional', 'cli_root', 'zpool_online'] tags = ['functional', 'cli_root', 'zpool_online']
[tests/functional/cli_root/zpool_reguid]
tests = ['zpool_reguid_001_pos', 'zpool_reguid_002_neg']
tags = ['functional', 'cli_root', 'zpool_reguid']
[tests/functional/cli_root/zpool_remove] [tests/functional/cli_root/zpool_remove]
tests = ['zpool_remove_001_neg', 'zpool_remove_002_pos', tests = ['zpool_remove_001_neg', 'zpool_remove_002_pos',
'zpool_remove_003_pos'] 'zpool_remove_003_pos']

View File

@ -0,0 +1,6 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/cli_root/zpool_reguid
dist_pkgdata_SCRIPTS = \
setup.ksh \
cleanup.ksh \
zpool_reguid_001_pos.ksh \
zpool_reguid_002_neg.ksh

View File

@ -0,0 +1,32 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
verify_runnable "global"
default_cleanup

View File

@ -0,0 +1,34 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or https://opensource.org/licenses/CDDL-1.0.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
. $STF_SUITE/include/libtest.shlib
verify_runnable "global"
DISK=${DISKS%% *}
default_setup $DISK

View File

@ -0,0 +1,73 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
# Copyright 2023 Mateusz Piotrowski
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
# Verify 'zpool reguid' can change pool's GUID.
#
# STRATEGY:
# 1. Use zpool get to obtain the initial GUID of a pool.
# 2. Change pool's GUID with zpool reguid.
# 3. Verify the GUID has changed to a random GUID.
#
# 4. Change pool's GUID with zpool reguid -g.
# 5. Verify the GUID has changed to the specified GUID.
#
# set_guid guid [expected_guid]
set_guid() {
gflag_guid="$1"
expected_guid="${2:-"$gflag_guid"}"
initial_guid="$(zpool get -H -o value guid "$TESTPOOL")"
log_assert "Verify 'zpool reguid -g \"$gflag_guid\"' sets GUID as expected."
log_must zpool reguid -g "$gflag_guid" "$TESTPOOL"
retrieved_guid="$(zpool get -H -o value guid "$TESTPOOL")"
if [[ "$retrieved_guid" == "" ]]; then
log_fail "Unable to obtain the new GUID of pool $TESTPOOL"
fi
if [[ "$expected_guid" != "$retrieved_guid" ]]; then
log_fail "GUID set to '$retrieved_guid' instead of '$expected_guid'"
fi
}
log_assert "Verify 'zpool reguid' picks a new random GUID for the pool."
initial_guid="$(zpool get -H -o value guid "$TESTPOOL")"
if [[ $initial_guid == "" ]]; then
log_fail "Unable to obtain the initial GUID of pool $TESTPOOL"
fi
log_must zpool reguid "$TESTPOOL"
new_guid="$(zpool get -H -o value guid "$TESTPOOL")"
if [[ "$new_guid" == "" ]]; then
log_fail "Unable to obtain the new GUID of pool $TESTPOOL"
fi
if [[ "$initial_guid" == "$new_guid" ]]; then
log_fail "GUID change failed; GUID has not changed: $initial_guid"
fi
for g in "$(bc -e '2^64 - 1')" 0; do
set_guid "$g"
done
# zpool-reguid(8) will strip the leading 0.
set_guid 0123 "123"
# GUID "-1" is effectively 2^64 - 1 in value.
set_guid -1 "$(bc -e '2^64 - 1')"
log_pass "'zpool reguid' changes GUID as expected."

View File

@ -0,0 +1,60 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#
# CDDL HEADER END
#
# Copyright 2023 Mateusz Piotrowski
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
# Verify 'zpool reguid' does not accept invalid GUIDs.
#
# STRATEGY:
# 1. Call zpool reguid with an invalid GUID.
# 2. Verify that the call fails.
# 3. Verify that the pool GUID did not change.
#
# 4. Call zpool reguid with a GUID that is already in use.
# 5. Verify that the call fails.
#
check_guid() {
invalid_guid="$1"
initial_guid="$(zpool get -H -o value guid "$TESTPOOL")"
log_assert "'zpool reguid' will not accept invalid GUID '$invalid_guid'"
if zpool reguid -g "$invalid_guid" "$TESTPOOL"; then
log_fail "'zpool reguid' accepted invalid GUID: $invalid_guid"
fi
final_guid="$(zpool get -H -o value guid "$TESTPOOL")"
if [[ "$initial_guid" != "$final_guid" ]]; then
log_fail "Invalid GUID change from '$initial_guid' to '$final_guid'"
fi
}
log_assert "Verify 'zpool reguid' does not accept invalid GUIDs"
for ig in "$(bc -e '2^64')" 0xA 0xa; do
check_guid "$ig"
done
guid="42"
log_assert "Verify 'zpool reguid -g' does not accept GUID which are already in use"
log_must zpool reguid -g "$guid" "$TESTPOOL"
if zpool reguid -g "$guid" "$TESTPOOL"; then
log_fail "'zpool reguid' accepted GUID that was already in use: $invalid_guid"
fi
log_pass "'zpool reguid' does not accept invalid GUIDs."