@@ -331,6 +331,7 @@ ztest_func_t ztest_vdev_add_remove;
331
331
ztest_func_t ztest_vdev_aux_add_remove ;
332
332
ztest_func_t ztest_split_pool ;
333
333
ztest_func_t ztest_reguid ;
334
+ ztest_func_t ztest_spa_upgrade ;
334
335
335
336
uint64_t zopt_always = 0ULL * NANOSEC ; /* all the time */
336
337
uint64_t zopt_incessant = 1ULL * NANOSEC / 10 ; /* every 1/10 second */
@@ -364,6 +365,7 @@ ztest_info_t ztest_info[] = {
364
365
{ ztest_reguid , 1 , & zopt_sometimes },
365
366
{ ztest_spa_rename , 1 , & zopt_rarely },
366
367
{ ztest_scrub , 1 , & zopt_rarely },
368
+ { ztest_spa_upgrade , 1 , & zopt_rarely },
367
369
{ ztest_dsl_dataset_promote_busy , 1 , & zopt_rarely },
368
370
{ ztest_vdev_attach_detach , 1 , & zopt_rarely },
369
371
{ ztest_vdev_LUN_growth , 1 , & zopt_rarely },
@@ -818,7 +820,7 @@ ztest_get_ashift(void)
818
820
}
819
821
820
822
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 )
822
824
{
823
825
char * pathbuf ;
824
826
uint64_t vdev ;
@@ -836,12 +838,13 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
836
838
vdev = ztest_shared -> zs_vdev_aux ;
837
839
(void ) snprintf (path , MAXPATHLEN ,
838
840
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 );
840
843
} else {
841
844
vdev = ztest_shared -> zs_vdev_next_leaf ++ ;
842
845
(void ) snprintf (path , MAXPATHLEN ,
843
846
ztest_dev_template , ztest_opts .zo_dir ,
844
- ztest_opts .zo_pool , vdev );
847
+ pool == NULL ? ztest_opts .zo_pool : pool , vdev );
845
848
}
846
849
}
847
850
@@ -864,17 +867,18 @@ make_vdev_file(char *path, char *aux, size_t size, uint64_t ashift)
864
867
}
865
868
866
869
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 )
868
872
{
869
873
nvlist_t * raidz , * * child ;
870
874
int c ;
871
875
872
876
if (r < 2 )
873
- return (make_vdev_file (path , aux , size , ashift ));
877
+ return (make_vdev_file (path , aux , pool , size , ashift ));
874
878
child = umem_alloc (r * sizeof (nvlist_t * ), UMEM_NOFAIL );
875
879
876
880
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 );
878
882
879
883
VERIFY (nvlist_alloc (& raidz , NV_UNIQUE_NAME , 0 ) == 0 );
880
884
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)
893
897
}
894
898
895
899
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 )
898
902
{
899
903
nvlist_t * mirror , * * child ;
900
904
int c ;
901
905
902
906
if (m < 1 )
903
- return (make_vdev_raidz (path , aux , size , ashift , r ));
907
+ return (make_vdev_raidz (path , aux , pool , size , ashift , r ));
904
908
905
909
child = umem_alloc (m * sizeof (nvlist_t * ), UMEM_NOFAIL );
906
910
907
911
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 );
909
913
910
914
VERIFY (nvlist_alloc (& mirror , NV_UNIQUE_NAME , 0 ) == 0 );
911
915
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,
922
926
}
923
927
924
928
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 )
927
931
{
928
932
nvlist_t * root , * * child ;
929
933
int c ;
@@ -933,7 +937,8 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
933
937
child = umem_alloc (t * sizeof (nvlist_t * ), UMEM_NOFAIL );
934
938
935
939
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 );
937
942
VERIFY (nvlist_add_uint64 (child [c ], ZPOOL_CONFIG_IS_LOG ,
938
943
log ) == 0 );
939
944
}
@@ -951,6 +956,27 @@ make_vdev_root(char *path, char *aux, size_t size, uint64_t ashift,
951
956
return (root );
952
957
}
953
958
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
+
954
980
static int
955
981
ztest_random_blocksize (void )
956
982
{
@@ -2306,15 +2332,15 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
2306
2332
/*
2307
2333
* Attempt to create using a bad file.
2308
2334
*/
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 );
2310
2336
VERIFY3U (ENOENT , = = ,
2311
2337
spa_create ("ztest_bad_file" , nvroot , NULL , NULL , NULL ));
2312
2338
nvlist_free (nvroot );
2313
2339
2314
2340
/*
2315
2341
* Attempt to create using a bad mirror.
2316
2342
*/
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 );
2318
2344
VERIFY3U (ENOENT , = = ,
2319
2345
spa_create ("ztest_bad_mirror" , nvroot , NULL , NULL , NULL ));
2320
2346
nvlist_free (nvroot );
@@ -2324,7 +2350,7 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
2324
2350
* what's in the nvroot; we should fail with EEXIST.
2325
2351
*/
2326
2352
(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 );
2328
2354
VERIFY3U (EEXIST , = = , spa_create (zo -> zo_pool , nvroot , NULL , NULL , NULL ));
2329
2355
nvlist_free (nvroot );
2330
2356
VERIFY3U (0 , = = , spa_open (zo -> zo_pool , & spa , FTAG ));
@@ -2334,6 +2360,78 @@ ztest_spa_create_destroy(ztest_ds_t *zd, uint64_t id)
2334
2360
(void ) rw_exit (& ztest_name_lock );
2335
2361
}
2336
2362
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
+
2337
2435
static vdev_t *
2338
2436
vdev_lookup_by_path (vdev_t * vd , const char * path )
2339
2437
{
@@ -2424,7 +2522,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, uint64_t id)
2424
2522
/*
2425
2523
* Make 1/4 of the devices be log devices.
2426
2524
*/
2427
- nvroot = make_vdev_root (NULL , NULL ,
2525
+ nvroot = make_vdev_root (NULL , NULL , NULL ,
2428
2526
ztest_opts .zo_vdev_size , 0 ,
2429
2527
ztest_random (4 ) == 0 , ztest_opts .zo_raidz ,
2430
2528
zs -> zs_mirrors , 1 );
@@ -2503,7 +2601,7 @@ ztest_vdev_aux_add_remove(ztest_ds_t *zd, uint64_t id)
2503
2601
/*
2504
2602
* Add a new device.
2505
2603
*/
2506
- nvlist_t * nvroot = make_vdev_root (NULL , aux ,
2604
+ nvlist_t * nvroot = make_vdev_root (NULL , aux , NULL ,
2507
2605
(ztest_opts .zo_vdev_size * 5 ) / 4 , 0 , 0 , 0 , 0 , 1 );
2508
2606
error = spa_vdev_add (spa , nvroot );
2509
2607
if (error != 0 )
@@ -2776,7 +2874,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id)
2776
2874
/*
2777
2875
* Build the nvlist describing newpath.
2778
2876
*/
2779
- root = make_vdev_root (newpath , NULL , newvd == NULL ? newsize : 0 ,
2877
+ root = make_vdev_root (newpath , NULL , NULL , newvd == NULL ? newsize : 0 ,
2780
2878
ashift , 0 , 0 , 0 , 1 );
2781
2879
2782
2880
error = spa_vdev_attach (spa , oldguid , root , replacing );
@@ -5055,7 +5153,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id)
5055
5153
if (error != 0 )
5056
5154
return ;
5057
5155
5058
- if (ztest_opts .zo_verbose >= 3 ) {
5156
+ if (ztest_opts .zo_verbose >= 4 ) {
5059
5157
(void ) printf ("Changed guid old %llu -> %llu\n" ,
5060
5158
(u_longlong_t )orig , (u_longlong_t )spa_guid (spa ));
5061
5159
}
@@ -5819,7 +5917,7 @@ ztest_init(ztest_shared_t *zs)
5819
5917
ztest_shared -> zs_vdev_next_leaf = 0 ;
5820
5918
zs -> zs_splits = 0 ;
5821
5919
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 ,
5823
5921
0 , ztest_opts .zo_raidz , zs -> zs_mirrors , 1 );
5824
5922
props = make_random_props ();
5825
5923
for (i = 0 ; i < SPA_FEATURES ; i ++ ) {
0 commit comments