Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import: add newname property to rename pool on next import #16874

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion cmd/zpool/zpool_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3888,7 +3888,29 @@ do_import(nvlist_t *config, const char *newname, const char *mntopts,
if (zpool_import_props(g_zfs, config, newname, props, flags) != 0)
return (1);

if (newname != NULL)
/*
* Figure out the imported name, so we can use it to open the pool
* and mount the filesystems.
*
* XXX ideally, zpool_import_props() would return the name it used,
* or there would be some other mechanism to get it. Alas, there
* is not. Choices seem to be to break a public function, or to
* smuggle it through one of the nvlists. Not keen on either
* until we get there -- robn, 2024-12-16
*/
if (newname == NULL) {
int error = nvlist_lookup_string(config, ZPOOL_CONFIG_NEWNAME,
&newname);
if (error == 0) {
fprintf(stderr, gettext("Pool '%s' has newname "
"property set and was renamed to '%s'\n"), name,
newname);
name = newname;
}
else
VERIFY3U(error, ==, ENOENT);
}
else
name = newname;

if ((zhp = zpool_open_canfail(g_zfs, name)) == NULL)
Expand Down
2 changes: 2 additions & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ typedef enum {
ZPOOL_PROP_DEDUP_TABLE_QUOTA,
ZPOOL_PROP_DEDUPCACHED,
ZPOOL_PROP_LAST_SCRUBBED_TXG,
ZPOOL_PROP_NEWNAME,
ZPOOL_NUM_PROPS
} zpool_prop_t;

Expand Down Expand Up @@ -865,6 +866,7 @@ typedef struct zpool_load_policy {
#define ZPOOL_CONFIG_EXPANSION_TIME "expansion_time" /* not stored */
#define ZPOOL_CONFIG_REBUILD_STATS "org.openzfs:rebuild_stats"
#define ZPOOL_CONFIG_COMPATIBILITY "compatibility"
#define ZPOOL_CONFIG_NEWNAME "org.openzfs:newname"

/*
* The persistent vdev state is stored as separate values rather than a single
Expand Down
2 changes: 2 additions & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ struct spa {
boolean_t spa_waiters_cancel; /* waiters should return */

char *spa_compatibility; /* compatibility file(s) */
char *spa_newname; /* pool name on next import */

uint64_t spa_dedup_table_quota; /* property DDT maximum size */
uint64_t spa_dedup_dsize; /* cached on-disk size of DDT */
uint64_t spa_dedup_class_full_txg; /* txg dedup class was full */
Expand Down
17 changes: 17 additions & 0 deletions lib/libzfs/libzfs_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
case ZPOOL_PROP_CACHEFILE:
case ZPOOL_PROP_COMMENT:
case ZPOOL_PROP_COMPATIBILITY:
case ZPOOL_PROP_NEWNAME:
if (zhp->zpool_props != NULL ||
zpool_get_all_props(zhp) == 0) {
(void) strlcpy(buf,
Expand Down Expand Up @@ -876,6 +877,13 @@ zpool_valid_proplist(libzfs_handle_t *hdl, const char *poolname,
"any effect\n", propname);
break;

case ZPOOL_PROP_NEWNAME:
if (zpool_name_valid(hdl, B_FALSE, strval))
break;
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"invalid pool name '%s'"), strval);
(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
goto error;
default:
break;
}
Expand Down Expand Up @@ -2193,6 +2201,15 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot import pool '%s'"), origname);

if (newname == NULL) {
error = nvlist_lookup_string(config, ZPOOL_CONFIG_NEWNAME,
&newname);
if (error != 0 && error != ENOENT)
return (zpool_standard_error(hdl, error,
dgettext(TEXT_DOMAIN, "error looking up newname")));
error = 0;
}

if (newname != NULL) {
if (!zpool_name_valid(hdl, B_FALSE, newname))
return (zfs_error_fmt(hdl, EZFS_INVALIDNAME,
Expand Down
7 changes: 7 additions & 0 deletions lib/libzutil/zutil_import.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,10 +589,12 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok,
* pool state
* hostid (if available)
* hostname (if available)
* new name (if available)
*/
uint64_t state, version;
const char *comment = NULL;
const char *compatibility = NULL;
const char *newname = NULL;

version = fnvlist_lookup_uint64(tmp,
ZPOOL_CONFIG_VERSION);
Expand Down Expand Up @@ -635,6 +637,11 @@ get_configs(libpc_handle_t *hdl, pool_list_t *pl, boolean_t active_ok,
ZPOOL_CONFIG_HOSTNAME, hostname);
}

if (nvlist_lookup_string(tmp,
ZPOOL_CONFIG_NEWNAME, &newname) == 0)
fnvlist_add_string(config,
ZPOOL_CONFIG_NEWNAME, newname);

config_seen = B_TRUE;
}

Expand Down
2 changes: 2 additions & 0 deletions module/zcommon/zpool_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ zpool_prop_init(void)
zprop_register_string(ZPOOL_PROP_COMPATIBILITY, "compatibility",
"off", PROP_DEFAULT, ZFS_TYPE_POOL,
"<file[,file...]> | off | legacy", "COMPATIBILITY", sfeatures);
zprop_register_string(ZPOOL_PROP_NEWNAME, "newname", NULL,
PROP_DEFAULT, ZFS_TYPE_POOL, "<name>", "NEWNAME", sfeatures);

/* readonly number properties */
zprop_register_number(ZPOOL_PROP_SIZE, "size", 0, PROP_READONLY,
Expand Down
32 changes: 32 additions & 0 deletions module/zfs/spa.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,11 @@ spa_prop_get_config(spa_t *spa, nvlist_t *nv)
spa->spa_compatibility, 0, ZPROP_SRC_LOCAL);
}

if (spa->spa_newname != NULL) {
spa_prop_add_list(nv, ZPOOL_PROP_NEWNAME,
spa->spa_newname, 0, ZPROP_SRC_LOCAL);
}

if (spa->spa_root != NULL)
spa_prop_add_list(nv, ZPOOL_PROP_ALTROOT, spa->spa_root,
0, ZPROP_SRC_LOCAL);
Expand Down Expand Up @@ -3900,6 +3905,7 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type)
uint64_t pool_guid;
const char *comment;
const char *compatibility;
const char *newname;

/*
* Versioning wasn't explicitly added to the label until later, so if
Expand Down Expand Up @@ -3953,6 +3959,10 @@ spa_ld_parse_config(spa_t *spa, spa_import_type_t type)
&compatibility) == 0)
spa->spa_compatibility = spa_strdup(compatibility);

ASSERT(spa->spa_newname == NULL);
if (nvlist_lookup_string(config, ZPOOL_CONFIG_NEWNAME, &newname) == 0)
spa->spa_newname = spa_strdup(newname);

(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
&spa->spa_config_txg);

Expand Down Expand Up @@ -6861,6 +6871,12 @@ spa_import(char *pool, nvlist_t *config, nvlist_t *props, uint64_t flags)
spa_aux_check_removed(&spa->spa_l2cache);
}

/* Clear newname after each successful import */
if (spa->spa_newname != NULL) {
spa_strfree(spa->spa_newname);
spa->spa_newname = NULL;
}

if (spa_writeable(spa)) {
/*
* Update the config cache to include the newly-imported pool.
Expand Down Expand Up @@ -9642,6 +9658,22 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
}

spa_history_log_internal(spa, "set", tx,
"%s=%s", nvpair_name(elem), strval);
break;
case ZPOOL_PROP_NEWNAME:
strval = fnvpair_value_string(elem);
if (spa->spa_newname != NULL)
spa_strfree(spa->spa_newname);
spa->spa_newname = spa_strdup(strval);
/*
* Dirty the configuration on vdevs as above.
*/
if (tx->tx_txg != TXG_INITIAL) {
vdev_config_dirty(spa->spa_root_vdev);
spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
}

spa_history_log_internal(spa, "set", tx,
"%s=%s", nvpair_name(elem), strval);
break;
Expand Down
3 changes: 3 additions & 0 deletions module/zfs/spa_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,9 @@ spa_config_generate(spa_t *spa, vdev_t *vd, uint64_t txg, int getstats)
if (spa->spa_compatibility != NULL)
fnvlist_add_string(config, ZPOOL_CONFIG_COMPATIBILITY,
spa->spa_compatibility);
if (spa->spa_newname != NULL)
fnvlist_add_string(config, ZPOOL_CONFIG_NEWNAME,
spa->spa_newname);

hostid = spa_get_hostid(spa);
if (hostid != 0)
Expand Down
Loading