ztest.c (88ecc943b4eb72f7c4fbbd8435997b85ef171fc3) | ztest.c (d20e665c84abf083a9e8b62cca93383ecb55afdf) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 154 unchanged lines hidden (view full) --- 163 164/* 165 * Note: these aren't static because we want dladdr() to work. 166 */ 167ztest_func_t ztest_dmu_read_write; 168ztest_func_t ztest_dmu_read_write_zcopy; 169ztest_func_t ztest_dmu_write_parallel; 170ztest_func_t ztest_dmu_object_alloc_free; | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 154 unchanged lines hidden (view full) --- 163 164/* 165 * Note: these aren't static because we want dladdr() to work. 166 */ 167ztest_func_t ztest_dmu_read_write; 168ztest_func_t ztest_dmu_read_write_zcopy; 169ztest_func_t ztest_dmu_write_parallel; 170ztest_func_t ztest_dmu_object_alloc_free; |
171ztest_func_t ztest_dmu_commit_callbacks; |
|
171ztest_func_t ztest_zap; 172ztest_func_t ztest_fzap; 173ztest_func_t ztest_zap_parallel; 174ztest_func_t ztest_traverse; 175ztest_func_t ztest_dsl_prop_get_set; 176ztest_func_t ztest_dmu_objset_create_destroy; 177ztest_func_t ztest_dmu_snapshot_create_destroy; 178ztest_func_t ztest_dsl_dataset_promote_busy; --- 21 unchanged lines hidden (view full) --- 200uint64_t zopt_sometimes = 10; /* every 10 seconds */ 201uint64_t zopt_rarely = 60; /* every 60 seconds */ 202 203ztest_info_t ztest_info[] = { 204 { ztest_dmu_read_write, 1, &zopt_always }, 205 { ztest_dmu_read_write_zcopy, 1, &zopt_always }, 206 { ztest_dmu_write_parallel, 30, &zopt_always }, 207 { ztest_dmu_object_alloc_free, 1, &zopt_always }, | 172ztest_func_t ztest_zap; 173ztest_func_t ztest_fzap; 174ztest_func_t ztest_zap_parallel; 175ztest_func_t ztest_traverse; 176ztest_func_t ztest_dsl_prop_get_set; 177ztest_func_t ztest_dmu_objset_create_destroy; 178ztest_func_t ztest_dmu_snapshot_create_destroy; 179ztest_func_t ztest_dsl_dataset_promote_busy; --- 21 unchanged lines hidden (view full) --- 201uint64_t zopt_sometimes = 10; /* every 10 seconds */ 202uint64_t zopt_rarely = 60; /* every 60 seconds */ 203 204ztest_info_t ztest_info[] = { 205 { ztest_dmu_read_write, 1, &zopt_always }, 206 { ztest_dmu_read_write_zcopy, 1, &zopt_always }, 207 { ztest_dmu_write_parallel, 30, &zopt_always }, 208 { ztest_dmu_object_alloc_free, 1, &zopt_always }, |
209 { ztest_dmu_commit_callbacks, 10, &zopt_always }, |
|
208 { ztest_zap, 30, &zopt_always }, 209 { ztest_fzap, 30, &zopt_always }, 210 { ztest_zap_parallel, 100, &zopt_always }, 211 { ztest_dsl_prop_get_set, 1, &zopt_sometimes }, 212 { ztest_dmu_objset_create_destroy, 1, &zopt_sometimes }, 213 { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes }, 214 { ztest_spa_create_destroy, 1, &zopt_sometimes }, 215 { ztest_fault_inject, 1, &zopt_sometimes }, --- 6 unchanged lines hidden (view full) --- 222 { ztest_scrub, 1, &zopt_vdevtime }, 223}; 224 225#define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t)) 226 227#define ZTEST_SYNC_LOCKS 16 228 229/* | 210 { ztest_zap, 30, &zopt_always }, 211 { ztest_fzap, 30, &zopt_always }, 212 { ztest_zap_parallel, 100, &zopt_always }, 213 { ztest_dsl_prop_get_set, 1, &zopt_sometimes }, 214 { ztest_dmu_objset_create_destroy, 1, &zopt_sometimes }, 215 { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes }, 216 { ztest_spa_create_destroy, 1, &zopt_sometimes }, 217 { ztest_fault_inject, 1, &zopt_sometimes }, --- 6 unchanged lines hidden (view full) --- 224 { ztest_scrub, 1, &zopt_vdevtime }, 225}; 226 227#define ZTEST_FUNCS (sizeof (ztest_info) / sizeof (ztest_info_t)) 228 229#define ZTEST_SYNC_LOCKS 16 230 231/* |
232 * The following struct is used to hold a list of uncalled commit callbacks. 233 * 234 * The callbacks are ordered by txg number. 235 */ 236typedef struct ztest_cb_list { 237 mutex_t zcl_callbacks_lock; 238 list_t zcl_callbacks; 239} ztest_cb_list_t; 240 241/* |
|
230 * Stuff we need to share writably between parent and child. 231 */ 232typedef struct ztest_shared { 233 mutex_t zs_vdev_lock; 234 rwlock_t zs_name_lock; 235 uint64_t zs_vdev_next_leaf; 236 uint64_t zs_vdev_aux; 237 uint64_t zs_enospc_count; --- 11 unchanged lines hidden (view full) --- 249static ztest_shared_t *ztest_shared; 250 251static int ztest_random_fd; 252static int ztest_dump_core = 1; 253 254static uint64_t metaslab_sz; 255static boolean_t ztest_exiting; 256 | 242 * Stuff we need to share writably between parent and child. 243 */ 244typedef struct ztest_shared { 245 mutex_t zs_vdev_lock; 246 rwlock_t zs_name_lock; 247 uint64_t zs_vdev_next_leaf; 248 uint64_t zs_vdev_aux; 249 uint64_t zs_enospc_count; --- 11 unchanged lines hidden (view full) --- 261static ztest_shared_t *ztest_shared; 262 263static int ztest_random_fd; 264static int ztest_dump_core = 1; 265 266static uint64_t metaslab_sz; 267static boolean_t ztest_exiting; 268 |
269/* Global commit callback list */ 270static ztest_cb_list_t zcl; 271 |
|
257extern uint64_t metaslab_gang_bang; 258extern uint64_t metaslab_df_alloc_threshold; 259 260#define ZTEST_DIROBJ 1 261#define ZTEST_MICROZAP_OBJ 2 262#define ZTEST_FATZAP_OBJ 3 263 264#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10) --- 2928 unchanged lines hidden (view full) --- 3193 ASSERT(error == 0 || error == ENOENT); 3194 break; 3195 } 3196 3197 if (tx != NULL) 3198 dmu_tx_commit(tx); 3199} 3200 | 272extern uint64_t metaslab_gang_bang; 273extern uint64_t metaslab_df_alloc_threshold; 274 275#define ZTEST_DIROBJ 1 276#define ZTEST_MICROZAP_OBJ 2 277#define ZTEST_FATZAP_OBJ 3 278 279#define ZTEST_DIROBJ_BLOCKSIZE (1 << 10) --- 2928 unchanged lines hidden (view full) --- 3208 ASSERT(error == 0 || error == ENOENT); 3209 break; 3210 } 3211 3212 if (tx != NULL) 3213 dmu_tx_commit(tx); 3214} 3215 |
3216/* 3217 * Commit callback data. 3218 */ 3219typedef struct ztest_cb_data { 3220 list_node_t zcd_node; 3221 uint64_t zcd_txg; 3222 int zcd_expected_err; 3223 boolean_t zcd_added; 3224 boolean_t zcd_called; 3225 spa_t *zcd_spa; 3226} ztest_cb_data_t; 3227 3228/* This is the actual commit callback function */ 3229static void 3230ztest_commit_callback(void *arg, int error) 3231{ 3232 ztest_cb_data_t *data = arg; 3233 uint64_t synced_txg; 3234 3235 VERIFY(data != NULL); 3236 VERIFY3S(data->zcd_expected_err, ==, error); 3237 VERIFY(!data->zcd_called); 3238 3239 synced_txg = spa_last_synced_txg(data->zcd_spa); 3240 if (data->zcd_txg > synced_txg) 3241 fatal(0, "commit callback of txg %" PRIu64 " called prematurely" 3242 ", last synced txg = %" PRIu64 "\n", data->zcd_txg, 3243 synced_txg); 3244 3245 data->zcd_called = B_TRUE; 3246 3247 if (error == ECANCELED) { 3248 ASSERT3U(data->zcd_txg, ==, 0); 3249 ASSERT(!data->zcd_added); 3250 3251 /* 3252 * The private callback data should be destroyed here, but 3253 * since we are going to check the zcd_called field after 3254 * dmu_tx_abort(), we will destroy it there. 3255 */ 3256 return; 3257 } 3258 3259 /* Was this callback added to the global callback list? */ 3260 if (!data->zcd_added) 3261 goto out; 3262 3263 ASSERT3U(data->zcd_txg, !=, 0); 3264 3265 /* Remove our callback from the list */ 3266 (void) mutex_lock(&zcl.zcl_callbacks_lock); 3267 list_remove(&zcl.zcl_callbacks, data); 3268 (void) mutex_unlock(&zcl.zcl_callbacks_lock); 3269 3270out: 3271 umem_free(data, sizeof (ztest_cb_data_t)); 3272} 3273 3274/* Allocate and initialize callback data structure */ 3275static ztest_cb_data_t * 3276ztest_create_cb_data(objset_t *os, uint64_t txg) 3277{ 3278 ztest_cb_data_t *cb_data; 3279 3280 cb_data = umem_zalloc(sizeof (ztest_cb_data_t), UMEM_NOFAIL); 3281 3282 cb_data->zcd_txg = txg; 3283 cb_data->zcd_spa = dmu_objset_spa(os); 3284 3285 return (cb_data); 3286} 3287 3288/* 3289 * If a number of txgs equal to this threshold have been created after a commit 3290 * callback has been registered but not called, then we assume there is an 3291 * implementation bug. 3292 */ 3293#define ZTEST_COMMIT_CALLBACK_THRESH (TXG_CONCURRENT_STATES + 2) 3294 3295/* 3296 * Commit callback test. 3297 */ |
|
3201void | 3298void |
3299ztest_dmu_commit_callbacks(ztest_args_t *za) 3300{ 3301 objset_t *os = za->za_os; 3302 dmu_tx_t *tx; 3303 ztest_cb_data_t *cb_data[3], *tmp_cb; 3304 uint64_t old_txg, txg; 3305 int i, error; 3306 3307 tx = dmu_tx_create(os); 3308 3309 cb_data[0] = ztest_create_cb_data(os, 0); 3310 dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[0]); 3311 3312 dmu_tx_hold_write(tx, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t)); 3313 3314 /* Every once in a while, abort the transaction on purpose */ 3315 if (ztest_random(100) == 0) 3316 error = -1; 3317 3318 if (!error) 3319 error = dmu_tx_assign(tx, TXG_NOWAIT); 3320 3321 txg = error ? 0 : dmu_tx_get_txg(tx); 3322 3323 cb_data[0]->zcd_txg = txg; 3324 cb_data[1] = ztest_create_cb_data(os, txg); 3325 dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[1]); 3326 3327 if (error) { 3328 /* 3329 * It's not a strict requirement to call the registered 3330 * callbacks from inside dmu_tx_abort(), but that's what 3331 * it's supposed to happen in the current implementation 3332 * so we will check for that. 3333 */ 3334 for (i = 0; i < 2; i++) { 3335 cb_data[i]->zcd_expected_err = ECANCELED; 3336 VERIFY(!cb_data[i]->zcd_called); 3337 } 3338 3339 dmu_tx_abort(tx); 3340 3341 for (i = 0; i < 2; i++) { 3342 VERIFY(cb_data[i]->zcd_called); 3343 umem_free(cb_data[i], sizeof (ztest_cb_data_t)); 3344 } 3345 3346 return; 3347 } 3348 3349 cb_data[2] = ztest_create_cb_data(os, txg); 3350 dmu_tx_callback_register(tx, ztest_commit_callback, cb_data[2]); 3351 3352 /* 3353 * Read existing data to make sure there isn't a future leak. 3354 */ 3355 VERIFY(0 == dmu_read(os, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t), 3356 &old_txg, DMU_READ_PREFETCH)); 3357 3358 if (old_txg > txg) 3359 fatal(0, "future leak: got %" PRIu64 ", open txg is %" PRIu64, 3360 old_txg, txg); 3361 3362 dmu_write(os, ZTEST_DIROBJ, za->za_diroff, sizeof (uint64_t), &txg, tx); 3363 3364 (void) mutex_lock(&zcl.zcl_callbacks_lock); 3365 3366 /* 3367 * Since commit callbacks don't have any ordering requirement and since 3368 * it is theoretically possible for a commit callback to be called 3369 * after an arbitrary amount of time has elapsed since its txg has been 3370 * synced, it is difficult to reliably determine whether a commit 3371 * callback hasn't been called due to high load or due to a flawed 3372 * implementation. 3373 * 3374 * In practice, we will assume that if after a certain number of txgs a 3375 * commit callback hasn't been called, then most likely there's an 3376 * implementation bug.. 3377 */ 3378 tmp_cb = list_head(&zcl.zcl_callbacks); 3379 if (tmp_cb != NULL && 3380 tmp_cb->zcd_txg > txg - ZTEST_COMMIT_CALLBACK_THRESH) { 3381 fatal(0, "Commit callback threshold exceeded, oldest txg: %" 3382 PRIu64 ", open txg: %" PRIu64 "\n", tmp_cb->zcd_txg, txg); 3383 } 3384 3385 /* 3386 * Let's find the place to insert our callbacks. 3387 * 3388 * Even though the list is ordered by txg, it is possible for the 3389 * insertion point to not be the end because our txg may already be 3390 * quiescing at this point and other callbacks in the open txg 3391 * (from other objsets) may have sneaked in. 3392 */ 3393 tmp_cb = list_tail(&zcl.zcl_callbacks); 3394 while (tmp_cb != NULL && tmp_cb->zcd_txg > txg) 3395 tmp_cb = list_prev(&zcl.zcl_callbacks, tmp_cb); 3396 3397 /* Add the 3 callbacks to the list */ 3398 for (i = 0; i < 3; i++) { 3399 if (tmp_cb == NULL) 3400 list_insert_head(&zcl.zcl_callbacks, cb_data[i]); 3401 else 3402 list_insert_after(&zcl.zcl_callbacks, tmp_cb, 3403 cb_data[i]); 3404 3405 cb_data[i]->zcd_added = B_TRUE; 3406 VERIFY(!cb_data[i]->zcd_called); 3407 3408 tmp_cb = cb_data[i]; 3409 } 3410 3411 (void) mutex_unlock(&zcl.zcl_callbacks_lock); 3412 3413 dmu_tx_commit(tx); 3414} 3415 3416void |
|
3202ztest_dsl_prop_get_set(ztest_args_t *za) 3203{ 3204 objset_t *os = za->za_os; 3205 int i, inherit; 3206 uint64_t value; 3207 const char *prop, *valname; 3208 char setpoint[MAXPATHLEN]; 3209 char osname[MAXNAMELEN]; --- 592 unchanged lines hidden (view full) --- 3802 char name[100]; 3803 thread_t resume_tid; 3804 3805 ztest_exiting = B_FALSE; 3806 3807 (void) _mutex_init(&zs->zs_vdev_lock, USYNC_THREAD, NULL); 3808 (void) rwlock_init(&zs->zs_name_lock, USYNC_THREAD, NULL); 3809 | 3417ztest_dsl_prop_get_set(ztest_args_t *za) 3418{ 3419 objset_t *os = za->za_os; 3420 int i, inherit; 3421 uint64_t value; 3422 const char *prop, *valname; 3423 char setpoint[MAXPATHLEN]; 3424 char osname[MAXNAMELEN]; --- 592 unchanged lines hidden (view full) --- 4017 char name[100]; 4018 thread_t resume_tid; 4019 4020 ztest_exiting = B_FALSE; 4021 4022 (void) _mutex_init(&zs->zs_vdev_lock, USYNC_THREAD, NULL); 4023 (void) rwlock_init(&zs->zs_name_lock, USYNC_THREAD, NULL); 4024 |
4025 (void) _mutex_init(&zcl.zcl_callbacks_lock, USYNC_THREAD, 4026 NULL); 4027 4028 list_create(&zcl.zcl_callbacks, sizeof (ztest_cb_data_t), 4029 offsetof(ztest_cb_data_t, zcd_node)); 4030 |
|
3810 for (t = 0; t < ZTEST_SYNC_LOCKS; t++) 3811 (void) _mutex_init(&zs->zs_sync_lock[t], USYNC_THREAD, NULL); 3812 3813 /* 3814 * Destroy one disk before we even start. 3815 * It's mirrored, so everything should work just fine. 3816 * This makes us exercise fault handling very early in spa_load(). 3817 */ --- 185 unchanged lines hidden (view full) --- 4003 * spa_close() should wait for it to complete. 4004 */ 4005 for (t = 1; t < 50; t++) 4006 dmu_prefetch(spa->spa_meta_objset, t, 0, 1 << 15); 4007 4008 spa_close(spa, FTAG); 4009 4010 kernel_fini(); | 4031 for (t = 0; t < ZTEST_SYNC_LOCKS; t++) 4032 (void) _mutex_init(&zs->zs_sync_lock[t], USYNC_THREAD, NULL); 4033 4034 /* 4035 * Destroy one disk before we even start. 4036 * It's mirrored, so everything should work just fine. 4037 * This makes us exercise fault handling very early in spa_load(). 4038 */ --- 185 unchanged lines hidden (view full) --- 4224 * spa_close() should wait for it to complete. 4225 */ 4226 for (t = 1; t < 50; t++) 4227 dmu_prefetch(spa->spa_meta_objset, t, 0, 1 << 15); 4228 4229 spa_close(spa, FTAG); 4230 4231 kernel_fini(); |
4232 4233 list_destroy(&zcl.zcl_callbacks); 4234 4235 (void) _mutex_destroy(&zcl.zcl_callbacks_lock); 4236 4237 (void) rwlock_destroy(&zs->zs_name_lock); 4238 (void) _mutex_destroy(&zs->zs_vdev_lock); |
|
4011} 4012 4013void 4014print_time(hrtime_t t, char *timebuf) 4015{ 4016 hrtime_t s = t / NANOSEC; 4017 hrtime_t m = s / 60; 4018 hrtime_t h = m / 60; --- 243 unchanged lines hidden --- | 4239} 4240 4241void 4242print_time(hrtime_t t, char *timebuf) 4243{ 4244 hrtime_t s = t / NANOSEC; 4245 hrtime_t m = s / 60; 4246 hrtime_t h = m / 60; --- 243 unchanged lines hidden --- |