Enhancements to zpool upgrade processing

Introduce a seperate phase to list all unavailable pools when listing
pools to upgrade. This avoids confusing output when displaying older
and disabled feature pools. These existing phases now silently skip
unavailable pools.

Introduce cb_unavail to upgrade_cbdata_t which enables the final
output for zpool list to correctly detail if all pools or only all
available pools where up-to-date on version / features.

Correct the type of upgrade_cbdata_t.cb_first from int -> boolean_t.

Change the pool iteration when upgrading named pools to include
unavailable pools and update upgrade_one so it doesn't try to upgrade
unavailable pools but warns about them. This allows the correct error
to be displayed as well as upgrades with available and unavailable
pools intermixed to partially complete.

Also correct some missing trailing \n's from output in upgrade_one.

MFC after:	1 month
X-MFC-With:	r276194
This commit is contained in:
Steven Hartland 2014-12-26 01:12:02 +00:00
parent e43b65f951
commit ec1b033c60
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=276226

View File

@ -4509,11 +4509,12 @@ zpool_do_status(int argc, char **argv)
} }
typedef struct upgrade_cbdata { typedef struct upgrade_cbdata {
int cb_first; boolean_t cb_first;
char cb_poolname[ZPOOL_MAXNAMELEN]; boolean_t cb_unavail;
int cb_argc; char cb_poolname[ZPOOL_MAXNAMELEN];
uint64_t cb_version; int cb_argc;
char **cb_argv; uint64_t cb_version;
char **cb_argv;
} upgrade_cbdata_t; } upgrade_cbdata_t;
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -4631,7 +4632,8 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is " (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"currently unavailable\n\n"), zpool_get_name(zhp)); "currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
/* Allow iteration to continue. */ /* Allow iteration to continue. */
return (0); return (0);
} }
@ -4696,6 +4698,26 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
return (0); return (0);
} }
static int
upgrade_list_unavail(zpool_handle_t *zhp, void *arg)
{
upgrade_cbdata_t *cbp = arg;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
if (cbp->cb_first) {
(void) fprintf(stderr, gettext("The following pools "
"are unavailable and cannot be upgraded as this "
"time.\n\n"));
(void) fprintf(stderr, gettext("POOL\n"));
(void) fprintf(stderr, gettext("------------\n"));
cbp->cb_first = B_FALSE;
}
(void) printf(gettext("%s\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
}
return (0);
}
static int static int
upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
{ {
@ -4703,6 +4725,15 @@ upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config; nvlist_t *config;
uint64_t version; uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
/*
* This will have been reported by upgrade_list_unavail so
* just allow iteration to continue.
*/
cbp->cb_unavail = B_TRUE;
return (0);
}
config = zpool_get_config(zhp, NULL); config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0); &version) == 0);
@ -4737,10 +4768,11 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
uint64_t version; uint64_t version;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot check supported " /*
"features on '%s': pool is currently unavailable\n\n"), * This will have been reported by upgrade_list_unavail so
zpool_get_name(zhp)); * just allow iteration to continue.
/* Allow iteration to continue. */ */
cbp->cb_unavail = B_TRUE;
return (0); return (0);
} }
@ -4797,10 +4829,17 @@ upgrade_one(zpool_handle_t *zhp, void *data)
uint64_t cur_version; uint64_t cur_version;
int ret; int ret;
if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
(void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
"is currently unavailable.\n\n"), zpool_get_name(zhp));
cbp->cb_unavail = B_TRUE;
return (1);
}
if (strcmp("log", zpool_get_name(zhp)) == 0) { if (strcmp("log", zpool_get_name(zhp)) == 0) {
(void) printf(gettext("'log' is now a reserved word\n" (void) printf(gettext("'log' is now a reserved word\n"
"Pool 'log' must be renamed using export and import" "Pool 'log' must be renamed using export and import"
" to upgrade.\n")); " to upgrade.\n\n"));
return (1); return (1);
} }
@ -4844,7 +4883,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
#endif /* __FreeBSD __*/ #endif /* __FreeBSD __*/
} else if (cur_version == SPA_VERSION) { } else if (cur_version == SPA_VERSION) {
(void) printf(gettext("Pool '%s' already has all " (void) printf(gettext("Pool '%s' already has all "
"supported features enabled.\n"), "supported features enabled.\n\n"),
zpool_get_name(zhp)); zpool_get_name(zhp));
} }
} }
@ -5001,11 +5040,13 @@ zpool_do_upgrade(int argc, char **argv)
ret = zpool_iter(g_zfs, upgrade_cb, &cb); ret = zpool_iter(g_zfs, upgrade_cb, &cb);
if (ret == 0 && cb.cb_first) { if (ret == 0 && cb.cb_first) {
if (cb.cb_version == SPA_VERSION) { if (cb.cb_version == SPA_VERSION) {
(void) printf(gettext("All pools are already " (void) printf(gettext("All %spools are already "
"formatted using feature flags.\n\n")); "formatted using feature flags.\n\n"),
(void) printf(gettext("Every feature flags " cb.cb_unavail ? gettext("available ") : "");
(void) printf(gettext("Every %sfeature flags "
"pool already has all supported features " "pool already has all supported features "
"enabled.\n")); "enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else { } else {
(void) printf(gettext("All pools are already " (void) printf(gettext("All pools are already "
"formatted with version %llu or higher.\n"), "formatted with version %llu or higher.\n"),
@ -5013,13 +5054,22 @@ zpool_do_upgrade(int argc, char **argv)
} }
} }
} else if (argc == 0) { } else if (argc == 0) {
cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb);
assert(ret == 0);
if (!cb.cb_first) {
(void) fprintf(stderr, "\n");
}
cb.cb_first = B_TRUE; cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
assert(ret == 0); assert(ret == 0);
if (cb.cb_first) { if (cb.cb_first) {
(void) printf(gettext("All pools are formatted " (void) printf(gettext("All %spools are formatted using "
"using feature flags.\n\n")); "feature flags.\n\n"), cb.cb_unavail ?
gettext("available ") : "");
} else { } else {
(void) printf(gettext("\nUse 'zpool upgrade -v' " (void) printf(gettext("\nUse 'zpool upgrade -v' "
"for a list of available legacy versions.\n")); "for a list of available legacy versions.\n"));
@ -5030,13 +5080,14 @@ zpool_do_upgrade(int argc, char **argv)
assert(ret == 0); assert(ret == 0);
if (cb.cb_first) { if (cb.cb_first) {
(void) printf(gettext("Every feature flags pool has " (void) printf(gettext("Every %sfeature flags pool has "
"all supported features enabled.\n")); "all supported features enabled.\n"),
cb.cb_unavail ? gettext("available ") : "");
} else { } else {
(void) printf(gettext("\n")); (void) printf(gettext("\n"));
} }
} else { } else {
ret = for_each_pool(argc, argv, B_FALSE, NULL, ret = for_each_pool(argc, argv, B_TRUE, NULL,
upgrade_one, &cb); upgrade_one, &cb);
} }