From 09e4e01e93c53127705d3d8fa4d4f8ac17ce5156 Mon Sep 17 00:00:00 2001 From: shuppy Date: Thu, 15 Jan 2026 06:51:51 +0800 Subject: [PATCH] Fix history logging for `zpool create -t` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `zpool create` is supposed to log the command to the new pool’s history, as a special record that never gets evicted from the ring buffer. but when you create a pool with `zpool create -t`, no such record is ever logged (#18102). that bug may be the cause of issues like #16408. `zpool create -t` (83e9986f6eefdf0afc387f06407087bba3ead4e9) and `zpool import -t` (26b42f3f9d03f85cc7966dc2fe4dfe9216601b0e) are both designed to override the on-disk zpool property `name` with an in-core “temporary” name, but they work somewhat differently under the hood. importing with a temporary name sets `spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME` in ZFS_IOC_POOL_IMPORT, which tells spa_write_cachefile() and spa_config_generate() to use the ZPOOL_CONFIG_POOL_NAME in `spa->spa_config` instead of `spa->spa_name`. creating with a temporary name permanently(!) sets the internal zpool property `tname` (ZPOOL_PROP_TNAME) in the `zc->zc_nvlist_src` of ZFS_IOC_POOL_CREATE, which tells zfs_ioc_pool_create() (4ceb8dd6fdfdde3b6ac55cf52132858973fce9d0) and spa_create() to use that name instead of `zc->zc_name`, then sets `spa->spa_import_flags |= ZFS_IMPORT_TEMP_NAME` like an import. but zfsdev_ioctl_common() fails to check for `tname` when saving the pool name to `zfs_allow_log_key`, so when we call ZFS_IOC_LOG_HISTORY, we call spa_open() on the wrong pool name and get ENOENT, so the logging silently fails. this patch fixes #18102 by checking for `tname` in zfsdev_ioctl_common() like we do in zfs_ioc_pool_create(). Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: delan azabani Closes #18118 Closes #18102 --- module/zfs/zfs_ioctl.c | 10 ++++++++-- .../cli_root/zpool_create/zpool_create_tempname.ksh | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 1b2392aea..c6f7dd596 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -8151,10 +8151,16 @@ zfsdev_ioctl_common(uint_t vecnum, zfs_cmd_t *zc, int flag) * Can't use kmem_strdup() as we might truncate the string and * kmem_strfree() would then free with incorrect size. */ - saved_poolname_len = strlen(zc->zc_name) + 1; + const char *spa_name = zc->zc_name; + const char *tname; + if (nvlist_lookup_string(innvl, + zpool_prop_to_name(ZPOOL_PROP_TNAME), &tname) == 0) { + spa_name = tname; + } + saved_poolname_len = strlen(spa_name) + 1; saved_poolname = kmem_alloc(saved_poolname_len, KM_SLEEP); - strlcpy(saved_poolname, zc->zc_name, saved_poolname_len); + strlcpy(saved_poolname, spa_name, saved_poolname_len); saved_poolname[strcspn(saved_poolname, "/@#")] = '\0'; if (vec->zvec_func != NULL) { diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh index fa0e913f8..234b0c36f 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_tempname.ksh @@ -60,6 +60,8 @@ for poolprop in "${poolprops[@]}"; do log_must test "$(get_prop $propname $TEMPPOOL)" == "$propval" IFS='=' read -r propname propval <<<"$poolprop" log_must test "$(get_pool_prop $propname $TEMPPOOL)" == "$propval" + # 3. Verify the `zpool create` command is logged to the pool history + log_must eval "zpool history $TEMPPOOL | grep -q 'zpool create -t'" # Cleanup destroy_pool $TEMPPOOL done