Lines Matching +full:acquisition +full:- +full:time +full:- +full:ns
9 * or https://opensource.org/licenses/CDDL-1.0.
29 #include <sys/time.h>
36 * Multi-Modifier Protection (MMP) attempts to prevent a user from importing
37 * or opening a pool on more than one host at a time. In particular, it
38 * prevents "zpool import -f" on a host from succeeding while the pool is
40 * device could be used by two hosts for different purposes at the same time
50 * (N-MMP_BLOCKS_PER_LABEL) slots, the remaining slots are reserved for MMP.
65 * mmp_delay field is a decaying average of the amount of time between
76 * some time, and finds the "best" uberblock again. If any of the mentioned
85 * 1) If uberblock was written by zfs-0.8 or newer and fail_intervals > 0:
91 * time means either the pool is not imported, or it is imported but the pool
100 * 2) If uberblock was written by zfs-0.8 or newer and fail_intervals == 0:
107 * enough time for a write to be attempted to each leaf vdev, and mmp_delay
111 * 3) If uberblock was written by zfs-0.7:
121 * that. We will have waited enough time for zfs_multihost_import_intervals
137 * 4) Otherwise, this uberblock was written by a pre-MMP zfs:
146 * at the same time and automatically attempt to import the pool.
163 * of zfs_multihost_import_intervals will reduce the import time but increase
164 * the risk of failing to detect an active pool. The total activity check time
195 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_init()
197 mutex_init(&mmp->mmp_thread_lock, NULL, MUTEX_DEFAULT, NULL); in mmp_init()
198 cv_init(&mmp->mmp_thread_cv, NULL, CV_DEFAULT, NULL); in mmp_init()
199 mutex_init(&mmp->mmp_io_lock, NULL, MUTEX_DEFAULT, NULL); in mmp_init()
200 mmp->mmp_kstat_id = 1; in mmp_init()
206 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_fini()
208 mutex_destroy(&mmp->mmp_thread_lock); in mmp_fini()
209 cv_destroy(&mmp->mmp_thread_cv); in mmp_fini()
210 mutex_destroy(&mmp->mmp_io_lock); in mmp_fini()
216 CALLB_CPR_INIT(cpr, &mmp->mmp_thread_lock, callb_generic_cpr, FTAG); in mmp_thread_enter()
217 mutex_enter(&mmp->mmp_thread_lock); in mmp_thread_enter()
225 cv_broadcast(&mmp->mmp_thread_cv); in mmp_thread_exit()
226 CALLB_CPR_EXIT(cpr); /* drops &mmp->mmp_thread_lock */ in mmp_thread_exit()
232 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_thread_start()
235 mutex_enter(&mmp->mmp_thread_lock); in mmp_thread_start()
236 if (!mmp->mmp_thread) { in mmp_thread_start()
237 mmp->mmp_thread = thread_create(NULL, 0, mmp_thread, in mmp_thread_start()
242 mutex_exit(&mmp->mmp_thread_lock); in mmp_thread_start()
249 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_thread_stop()
251 mutex_enter(&mmp->mmp_thread_lock); in mmp_thread_stop()
252 mmp->mmp_thread_exiting = 1; in mmp_thread_stop()
253 cv_broadcast(&mmp->mmp_thread_cv); in mmp_thread_stop()
255 while (mmp->mmp_thread) { in mmp_thread_stop()
256 cv_wait(&mmp->mmp_thread_cv, &mmp->mmp_thread_lock); in mmp_thread_stop()
258 mutex_exit(&mmp->mmp_thread_lock); in mmp_thread_stop()
262 ASSERT(mmp->mmp_thread == NULL); in mmp_thread_stop()
263 mmp->mmp_thread_exiting = 0; in mmp_thread_stop()
289 ASSERT(MUTEX_HELD(&spa->spa_mmp.mmp_io_lock)); in mmp_next_leaf()
291 ASSERT(list_link_active(&spa->spa_leaf_list.list_head) == B_TRUE); in mmp_next_leaf()
292 ASSERT(!list_is_empty(&spa->spa_leaf_list)); in mmp_next_leaf()
294 if (spa->spa_mmp.mmp_leaf_last_gen != spa->spa_leaf_list_gen) { in mmp_next_leaf()
295 spa->spa_mmp.mmp_last_leaf = list_head(&spa->spa_leaf_list); in mmp_next_leaf()
296 spa->spa_mmp.mmp_leaf_last_gen = spa->spa_leaf_list_gen; in mmp_next_leaf()
299 leaf = spa->spa_mmp.mmp_last_leaf; in mmp_next_leaf()
301 leaf = list_head(&spa->spa_leaf_list); in mmp_next_leaf()
305 leaf = list_next(&spa->spa_leaf_list, leaf); in mmp_next_leaf()
307 leaf = list_head(&spa->spa_leaf_list); in mmp_next_leaf()
317 if (!vdev_writeable(leaf) || leaf->vdev_offline || in mmp_next_leaf()
318 leaf->vdev_detached) { in mmp_next_leaf()
320 } else if (leaf->vdev_ops == &vdev_draid_spare_ops) { in mmp_next_leaf()
322 } else if (leaf->vdev_mmp_pending != 0) { in mmp_next_leaf()
325 spa->spa_mmp.mmp_last_leaf = leaf; in mmp_next_leaf()
359 mmp_thread_t *mts = &spa->spa_mmp; in mmp_delay_update()
360 hrtime_t delay = gethrtime() - mts->mmp_last_write; in mmp_delay_update()
362 ASSERT(MUTEX_HELD(&mts->mmp_io_lock)); in mmp_delay_update()
365 mts->mmp_delay = 0; in mmp_delay_update()
369 if (delay > mts->mmp_delay) in mmp_delay_update()
370 mts->mmp_delay = delay; in mmp_delay_update()
375 mts->mmp_last_write = gethrtime(); in mmp_delay_update()
380 if (delay < mts->mmp_delay) { in mmp_delay_update()
384 mts->mmp_delay = MAX(((delay + mts->mmp_delay * 127) / 128), in mmp_delay_update()
392 spa_t *spa = zio->io_spa; in mmp_write_done()
393 vdev_t *vd = zio->io_vd; in mmp_write_done()
394 mmp_thread_t *mts = zio->io_private; in mmp_write_done()
396 mutex_enter(&mts->mmp_io_lock); in mmp_write_done()
397 uint64_t mmp_kstat_id = vd->vdev_mmp_kstat_id; in mmp_write_done()
398 hrtime_t mmp_write_duration = gethrtime() - vd->vdev_mmp_pending; in mmp_write_done()
400 mmp_delay_update(spa, (zio->io_error == 0)); in mmp_write_done()
402 vd->vdev_mmp_pending = 0; in mmp_write_done()
403 vd->vdev_mmp_kstat_id = 0; in mmp_write_done()
405 mutex_exit(&mts->mmp_io_lock); in mmp_write_done()
408 spa_mmp_history_set(spa, mmp_kstat_id, zio->io_error, in mmp_write_done()
411 abd_free(zio->io_abd); in mmp_write_done()
415 * When the uberblock on-disk is updated by a spa_sync,
422 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_update_uberblock()
424 mutex_enter(&mmp->mmp_io_lock); in mmp_update_uberblock()
425 mmp->mmp_ub = *ub; in mmp_update_uberblock()
426 mmp->mmp_seq = 1; in mmp_update_uberblock()
427 mmp->mmp_ub.ub_timestamp = gethrestime_sec(); in mmp_update_uberblock()
429 mutex_exit(&mmp->mmp_io_lock); in mmp_update_uberblock()
434 * with a copy of the last-synced uberblock, whose timestamp
441 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_write_uberblock()
449 lock_acquire_time = gethrtime() - lock_acquire_time; in mmp_write_uberblock()
451 zfs_dbgmsg("MMP SCL_STATE acquisition pool '%s' took %llu ns " in mmp_write_uberblock()
455 mutex_enter(&mmp->mmp_io_lock); in mmp_write_uberblock()
461 * Issued MMP write: records time issued, error status, etc. in mmp_write_uberblock()
469 if (mmp->mmp_skip_error == error) { in mmp_write_uberblock()
470 spa_mmp_history_set_skip(spa, mmp->mmp_kstat_id - 1); in mmp_write_uberblock()
472 mmp->mmp_skip_error = error; in mmp_write_uberblock()
473 spa_mmp_history_add(spa, mmp->mmp_ub.ub_txg, in mmp_write_uberblock()
474 gethrestime_sec(), mmp->mmp_delay, NULL, 0, in mmp_write_uberblock()
475 mmp->mmp_kstat_id++, error); in mmp_write_uberblock()
480 mutex_exit(&mmp->mmp_io_lock); in mmp_write_uberblock()
485 vd = spa->spa_mmp.mmp_last_leaf; in mmp_write_uberblock()
486 if (mmp->mmp_skip_error != 0) { in mmp_write_uberblock()
487 mmp->mmp_skip_error = 0; in mmp_write_uberblock()
491 (u_longlong_t)vd->vdev_guid); in mmp_write_uberblock()
494 if (mmp->mmp_zio_root == NULL) in mmp_write_uberblock()
495 mmp->mmp_zio_root = zio_root(spa, NULL, NULL, in mmp_write_uberblock()
498 if (mmp->mmp_ub.ub_timestamp != gethrestime_sec()) { in mmp_write_uberblock()
504 mmp->mmp_ub.ub_timestamp = gethrestime_sec(); in mmp_write_uberblock()
505 mmp->mmp_seq = 1; in mmp_write_uberblock()
508 ub = &mmp->mmp_ub; in mmp_write_uberblock()
509 ub->ub_mmp_magic = MMP_MAGIC; in mmp_write_uberblock()
510 ub->ub_mmp_delay = mmp->mmp_delay; in mmp_write_uberblock()
511 ub->ub_mmp_config = MMP_SEQ_SET(mmp->mmp_seq) | in mmp_write_uberblock()
515 vd->vdev_mmp_pending = gethrtime(); in mmp_write_uberblock()
516 vd->vdev_mmp_kstat_id = mmp->mmp_kstat_id; in mmp_write_uberblock()
518 zio_t *zio = zio_null(mmp->mmp_zio_root, spa, NULL, NULL, NULL, flags); in mmp_write_uberblock()
522 VDEV_UBERBLOCK_SIZE(vd) - sizeof (uberblock_t)); in mmp_write_uberblock()
524 mmp->mmp_seq++; in mmp_write_uberblock()
525 mmp->mmp_kstat_id++; in mmp_write_uberblock()
526 mutex_exit(&mmp->mmp_io_lock); in mmp_write_uberblock()
528 offset = VDEV_UBERBLOCK_OFFSET(vd, VDEV_UBERBLOCK_COUNT(vd) - in mmp_write_uberblock()
536 (void) spa_mmp_history_add(spa, ub->ub_txg, ub->ub_timestamp, in mmp_write_uberblock()
537 ub->ub_mmp_delay, vd, label, vd->vdev_mmp_kstat_id, 0); in mmp_write_uberblock()
546 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_thread()
571 mutex_enter(&mmp->mmp_io_lock); in mmp_thread()
572 mmp->mmp_last_write = gethrtime(); in mmp_thread()
573 mmp->mmp_delay = MSEC2NSEC(MMP_INTERVAL_OK(zfs_multihost_interval)); in mmp_thread()
574 mutex_exit(&mmp->mmp_io_lock); in mmp_thread()
576 while (!mmp->mmp_thread_exiting) { in mmp_thread()
633 * us some time to try. in mmp_thread()
643 mutex_enter(&mmp->mmp_io_lock); in mmp_thread()
644 mmp->mmp_last_write = gethrtime(); in mmp_thread()
645 mmp->mmp_delay = mmp_interval; in mmp_thread()
646 mutex_exit(&mmp->mmp_io_lock); in mmp_thread()
654 mutex_enter(&mmp->mmp_io_lock); in mmp_thread()
655 mmp->mmp_delay = 0; in mmp_thread()
656 mutex_exit(&mmp->mmp_io_lock); in mmp_thread()
664 (gethrtime() - mmp->mmp_last_write) > mmp_fail_ns) { in mmp_thread()
669 (u_longlong_t)mmp->mmp_last_write, in mmp_thread()
673 (u_longlong_t)spa->spa_uberblock.ub_txg); in mmp_thread()
678 NSEC2MSEC(gethrtime() - mmp->mmp_last_write), in mmp_thread()
689 skip_wait--; in mmp_thread()
693 (void) cv_timedwait_idle_hires(&mmp->mmp_thread_cv, in mmp_thread()
694 &mmp->mmp_thread_lock, next_time, USEC2NSEC(100), in mmp_thread()
696 CALLB_CPR_SAFE_END(&cpr, &mmp->mmp_thread_lock); in mmp_thread()
700 zio_wait(mmp->mmp_zio_root); in mmp_thread()
702 mmp->mmp_zio_root = NULL; in mmp_thread()
703 mmp_thread_exit(mmp, &mmp->mmp_thread, &cpr); in mmp_thread()
718 mmp_thread_t *mmp = &spa->spa_mmp; in mmp_signal_thread()
720 mutex_enter(&mmp->mmp_thread_lock); in mmp_signal_thread()
721 if (mmp->mmp_thread) in mmp_signal_thread()
722 cv_broadcast(&mmp->mmp_thread_cv); in mmp_signal_thread()
723 mutex_exit(&mmp->mmp_thread_lock); in mmp_signal_thread()
733 if (spa->spa_state == POOL_STATE_ACTIVE) in mmp_signal_all_threads()