Skip to content

Commit ea0b253

Browse files
grwilsonbehlendorf
authored andcommitted
Illumos #3349: zpool upgrade -V bumps the on disk version number
3349 zpool upgrade -V bumps the on disk version number, but leaves the in core version Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Christopher Siden <chris.siden@delphix.com> Reviewed by: Matt Ahrens <matthew.ahrens@delphix.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Dan McDonald <danmcd@nexenta.com> References: illumos/illumos-gate@25345e4 https://www.illumos.org/issues/3349 Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>
1 parent 29809a6 commit ea0b253

File tree

2 files changed

+127
-21
lines changed

2 files changed

+127
-21
lines changed

cmd/ztest/ztest.c

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ ztest_func_t ztest_vdev_add_remove;
331331
ztest_func_t ztest_vdev_aux_add_remove;
332332
ztest_func_t ztest_split_pool;
333333
ztest_func_t ztest_reguid;
334+
ztest_func_t ztest_spa_upgrade;
334335

335336
uint64_t zopt_always = 0ULL * NANOSEC; /* all the time */
336337
uint64_t zopt_incessant = 1ULL * NANOSEC / 10; /* every 1/10 second */
@@ -364,6 +365,7 @@ ztest_info_t ztest_info[] = {
364365
{ ztest_reguid, 1, &zopt_sometimes },
365366
{ ztest_spa_rename, 1, &zopt_rarely },
366367
{ ztest_scrub, 1, &zopt_rarely },
368+
{ ztest_spa_upgrade, 1, &zopt_rarely },
367369
{ ztest_dsl_dataset_promote_busy, 1, &zopt_rarely },
368370
{ ztest_vdev_attach_detach, 1, &zopt_rarely },
369371
{ ztest_vdev_LUN_growth, 1, &zopt_rarely },
@@ -818,7 +820,7 @@ ztest_get_ashift(void)
818820
}
819821

820822
static nvlist_t *
821-
make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
823+
make_vdev_file(char *path, char *aux, char *pool, size_t size, uint64_t ashift)
822824
{
823825
char *pathbuf;
824826
uint64_t vdev;
@@ -836,12 +838,13 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
836838
vdev = ztest_shared->zs_vdev_aux;
837839
(void) snprintf(path, MAXPATHLEN,
838840
ztest_aux_template, ztest_opts.zo_dir,
839-
ztest_opts.zo_pool, aux, vdev);
841+
pool == NULL ? ztest_opts.zo_pool : pool,
842+
aux, vdev);
840843
} else {
841844
vdev = ztest_shared->zs_vdev_next_leaf++;
842845
(void) snprintf(path, MAXPATHLEN,
843846
ztest_dev_template, ztest_opts.zo_dir,
844-
ztest_opts.zo_pool, vdev);
847+
pool == NULL ? ztest_opts.zo_pool : pool, vdev);
845848
}
846849
}
847850

@@ -864,17 +867,18 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
864867
}
865868

866869
static nvlist_t *
867-
make_vdev_raidz(char *path, char *aux, size_t size, uint64_t ashift, int r)
870+
make_vdev_raidz(char *path, char *aux, char *pool, size_t size,
871+
uint64_t ashift, int r)
868872
{
869873
nvlist_t *raidz, **child;
870874
int c;
871875

872876
if (r < 2)
873-
return (make_vdev_file(path, aux, size, ashift));
877+
return (make_vdev_file(path, aux, pool, size, ashift));
874878
child = umem_alloc(r * sizeof (nvlist_t *), UMEM_NOFAIL);
875879

876880
for (c = 0; c < r; c++)
877-
child[c] = make_vdev_file(path, aux, size, ashift);
881+
child[c] = make_vdev_file(path, aux, pool, size, ashift);
878882

879883
VERIFY(nvlist_alloc(&raidz, NV_UNIQUE_NAME, 0) == 0);
880884
VERIFY(nvlist_add_string(raidz, ZPOOL_CONFIG_TYPE,
@@ -893,19 +897,19 @@ make_vdev_raidz(char *path, char *aux, size_t size, uint64_t ashift, int r)
893897
}
894898

895899
static nvlist_t *
896-
make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
897-
int r, int m)
900+
make_vdev_mirror(char *path, char *aux, char *pool, size_t size,
901+
uint64_t ashift, int r, int m)
898902
{
899903
nvlist_t *mirror, **child;
900904
int c;
901905

902906
if (m < 1)
903-
return (make_vdev_raidz(path, aux, size, ashift, r));
907+
return (make_vdev_raidz(path, aux, pool, size, ashift, r));
904908

905909
child = umem_alloc(m * sizeof (nvlist_t *), UMEM_NOFAIL);
906910

907911
for (c = 0; c < m; c++)
908-
child[c] = make_vdev_raidz(path, aux, size, ashift, r);
912+
child[c] = make_vdev_raidz(path, aux, pool, size, ashift, r);
909913

910914
VERIFY(nvlist_alloc(&mirror, NV_UNIQUE_NAME, 0) == 0);
911915
VERIFY(nvlist_add_string(mirror, ZPOOL_CONFIG_TYPE,
@@ -922,8 +926,8 @@ make_vdev_mirror(char *path, char *aux, size_t size, uint64_t ashift,
922926
}
923927

924928
static nvlist_t *
925-
make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
926-
int log, int r, int m, int t)
929+
make_vdev_root(char *path, char *aux, char *pool, size_t size, uint64_t ashift,
930+
int log, int r, int m, int t)
927931
{
928932
nvlist_t *root, **child;
929933
int c;
@@ -933,7 +937,8 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
933937
child = umem_alloc(t * sizeof (nvlist_t *), UMEM_NOFAIL);
934938

935939
for (c = 0; c < t; c++) {
936-
child[c] = make_vdev_mirror(path, aux, size, ashift, r, m);
940+
child[c] = make_vdev_mirror(path, aux, pool, size, ashift,
941+
r, m);
937942
VERIFY(nvlist_add_uint64(child[c], ZPOOL_CONFIG_IS_LOG,
938943
log) == 0);
939944
}
@@ -951,6 +956,27 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
951956
return (root);
952957
}
953958

959+
/*
960+
* Find a random spa version. Returns back a random spa version in the
961+
* range [initial_version, SPA_VERSION_FEATURES].
962+
*/
963+
static uint64_t
964+
ztest_random_spa_version(uint64_t initial_version)
965+
{
966+
uint64_t version = initial_version;
967+
968+
if (version <= SPA_VERSION_BEFORE_FEATURES) {
969+
version = version +
970+
ztest_random(SPA_VERSION_BEFORE_FEATURES - version + 1);
971+
}
972+
973+
if (version > SPA_VERSION_BEFORE_FEATURES)
974+
version = SPA_VERSION_FEATURES;
975+
976+
ASSERT(SPA_VERSION_IS_SUPPORTED(version));
977+
return (version);
978+
}
979+
954980
static int
955981
ztest_random_blocksize(void)
956982
{
@@ -2306,15 +2332,15 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
23062332
/*
23072333
* Attempt to create using a bad file.
23082334
*/
2309-
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1);
2335+
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
23102336
VERIFY3U(ENOENT, ==,
23112337
spa_create("ztest_bad_file", nvroot, NULL, NULL, NULL));
23122338
nvlist_free(nvroot);
23132339

23142340
/*
23152341
* Attempt to create using a bad mirror.
23162342
*/
2317-
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 2, 1);
2343+
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 2, 1);
23182344
VERIFY3U(ENOENT, ==,
23192345
spa_create("ztest_bad_mirror", nvroot, NULL, NULL, NULL));
23202346
nvlist_free(nvroot);
@@ -2324,7 +2350,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
23242350
* what's in the nvroot; we should fail with EEXIST.
23252351
*/
23262352
(void) rw_enter(&ztest_name_lock, RW_READER);
2327-
nvroot = make_vdev_root("/dev/bogus", NULL, 0, 0, 0, 0, 0, 1);
2353+
nvroot = make_vdev_root("/dev/bogus", NULL, NULL, 0, 0, 0, 0, 0, 1);
23282354
VERIFY3U(EEXIST, ==, spa_create(zo->zo_pool, nvroot, NULL, NULL, NULL));
23292355
nvlist_free(nvroot);
23302356
VERIFY3U(0, ==, spa_open(zo->zo_pool, &spa, FTAG));
@@ -2334,6 +2360,78 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
23342360
(void) rw_exit(&ztest_name_lock);
23352361
}
23362362

2363+
/* ARGSUSED */
2364+
void
2365+
ztest_spa_upgrade(ztest_ds_t *zd, uint64_t id)
2366+
{
2367+
spa_t *spa;
2368+
uint64_t initial_version = SPA_VERSION_INITIAL;
2369+
uint64_t version, newversion;
2370+
nvlist_t *nvroot, *props;
2371+
char *name;
2372+
2373+
mutex_enter(&ztest_vdev_lock);
2374+
name = kmem_asprintf("%s_upgrade", ztest_opts.zo_pool);
2375+
2376+
/*
2377+
* Clean up from previous runs.
2378+
*/
2379+
(void) spa_destroy(name);
2380+
2381+
nvroot = make_vdev_root(NULL, NULL, name, ztest_opts.zo_vdev_size, 0,
2382+
0, ztest_opts.zo_raidz, ztest_opts.zo_mirrors, 1);
2383+
2384+
/*
2385+
* If we're configuring a RAIDZ device then make sure that the
2386+
* the initial version is capable of supporting that feature.
2387+
*/
2388+
switch (ztest_opts.zo_raidz_parity) {
2389+
case 0:
2390+
case 1:
2391+
initial_version = SPA_VERSION_INITIAL;
2392+
break;
2393+
case 2:
2394+
initial_version = SPA_VERSION_RAIDZ2;
2395+
break;
2396+
case 3:
2397+
initial_version = SPA_VERSION_RAIDZ3;
2398+
break;
2399+
}
2400+
2401+
/*
2402+
* Create a pool with a spa version that can be upgraded. Pick
2403+
* a value between initial_version and SPA_VERSION_BEFORE_FEATURES.
2404+
*/
2405+
do {
2406+
version = ztest_random_spa_version(initial_version);
2407+
} while (version > SPA_VERSION_BEFORE_FEATURES);
2408+
2409+
props = fnvlist_alloc();
2410+
fnvlist_add_uint64(props,
2411+
zpool_prop_to_name(ZPOOL_PROP_VERSION), version);
2412+
VERIFY3S(spa_create(name, nvroot, props, NULL, NULL), ==, 0);
2413+
fnvlist_free(nvroot);
2414+
fnvlist_free(props);
2415+
2416+
VERIFY3S(spa_open(name, &spa, FTAG), ==, 0);
2417+
VERIFY3U(spa_version(spa), ==, version);
2418+
newversion = ztest_random_spa_version(version + 1);
2419+
2420+
if (ztest_opts.zo_verbose >= 4) {
2421+
(void) printf("upgrading spa version from %llu to %llu\n",
2422+
(u_longlong_t)version, (u_longlong_t)newversion);
2423+
}
2424+
2425+
spa_upgrade(spa, newversion);
2426+
VERIFY3U(spa_version(spa), >, version);
2427+
VERIFY3U(spa_version(spa), ==, fnvlist_lookup_uint64(spa->spa_config,
2428+
zpool_prop_to_name(ZPOOL_PROP_VERSION)));
2429+
spa_close(spa, FTAG);
2430+
2431+
strfree(name);
2432+
mutex_exit(&ztest_vdev_lock);
2433+
}
2434+
23372435
static vdev_t *
23382436
vdev_lookup_by_path(vdev_t *vd, const char *path)
23392437
{
@@ -2424,7 +2522,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
24242522
/*
24252523
* Make 1/4 of the devices be log devices.
24262524
*/
2427-
nvroot = make_vdev_root(NULL, NULL,
2525+
nvroot = make_vdev_root(NULL, NULL, NULL,
24282526
ztest_opts.zo_vdev_size, 0,
24292527
ztest_random(4) == 0, ztest_opts.zo_raidz,
24302528
zs->zs_mirrors, 1);
@@ -2503,7 +2601,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
25032601
/*
25042602
* Add a new device.
25052603
*/
2506-
nvlist_t *nvroot = make_vdev_root(NULL, aux,
2604+
nvlist_t *nvroot = make_vdev_root(NULL, aux, NULL,
25072605
(ztest_opts.zo_vdev_size * 5) / 4, 0, 0, 0, 0, 1);
25082606
error = spa_vdev_add(spa, nvroot);
25092607
if (error != 0)
@@ -2776,7 +2874,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
27762874
/*
27772875
* Build the nvlist describing newpath.
27782876
*/
2779-
root = make_vdev_root(newpath, NULL, newvd == NULL ? newsize : 0,
2877+
root = make_vdev_root(newpath, NULL, NULL, newvd == NULL ? newsize : 0,
27802878
ashift, 0, 0, 0, 1);
27812879

27822880
error = spa_vdev_attach(spa, oldguid, root, replacing);
@@ -5055,7 +5153,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id)
50555153
if (error != 0)
50565154
return;
50575155

5058-
if (ztest_opts.zo_verbose >= 3) {
5156+
if (ztest_opts.zo_verbose >= 4) {
50595157
(void) printf("Changed guid old %llu -> %llu\n",
50605158
(u_longlong_t)orig, (u_longlong_t)spa_guid(spa));
50615159
}
@@ -5819,7 +5917,7 @@ ztest_init(ztest_shared_t *zs)
58195917
ztest_shared->zs_vdev_next_leaf = 0;
58205918
zs->zs_splits = 0;
58215919
zs->zs_mirrors = ztest_opts.zo_mirrors;
5822-
nvroot = make_vdev_root(NULL, NULL, ztest_opts.zo_vdev_size, 0,
5920+
nvroot = make_vdev_root(NULL, NULL, NULL, ztest_opts.zo_vdev_size, 0,
58235921
0, ztest_opts.zo_raidz, zs->zs_mirrors, 1);
58245922
props = make_random_props();
58255923
for (i = 0; i < SPA_FEATURES; i++) {

module/zfs/spa.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5742,6 +5742,14 @@ spa_sync_config_object(spa_t *spa, dmu_tx_t *tx)
57425742
config = spa_config_generate(spa, spa->spa_root_vdev,
57435743
dmu_tx_get_txg(tx), B_FALSE);
57445744

5745+
/*
5746+
* If we're upgrading the spa version then make sure that
5747+
* the config object gets updated with the correct version.
5748+
*/
5749+
if (spa->spa_ubsync.ub_version < spa->spa_uberblock.ub_version)
5750+
fnvlist_add_uint64(config, ZPOOL_CONFIG_VERSION,
5751+
spa->spa_uberblock.ub_version);
5752+
57455753
spa_config_exit(spa, SCL_STATE, FTAG);
57465754

57475755
if (spa->spa_config_syncing)

0 commit comments

Comments
 (0)