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
16 changed files with 342 additions and 16 deletions
+22 -3
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
* would be orphaned from our pool. We are also going to issue a
* 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
spa_change_guid(spa_t *spa)
spa_change_guid(spa_t *spa, const uint64_t *guidp)
{
int error;
uint64_t guid;
int error;
mutex_enter(&spa->spa_vdev_top_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,
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);
}
out:
mutex_exit(&spa_namespace_lock);
mutex_exit(&spa->spa_vdev_top_lock);
+29 -1
View File
@@ -1794,17 +1794,45 @@ zfs_ioc_pool_get_history(zfs_cmd_t *zc)
return (error);
}
/*
* inputs:
* zc_nvlist_src nvlist optionally containing ZPOOL_REGUID_GUID
* zc_nvlist_src_size size of the nvlist
*/
static int
zfs_ioc_pool_reguid(zfs_cmd_t *zc)
{
uint64_t *guidp = NULL;
nvlist_t *props = NULL;
spa_t *spa;
uint64_t guid;
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);
if (error == 0) {
error = spa_change_guid(spa);
error = spa_change_guid(spa, guidp);
spa_close(spa, FTAG);
}
out:
if (props != NULL)
nvlist_free(props);
return (error);
}