--- libmultipath/structs_vec.c | 24 +++++++++++++++++------- multipathd/main.c | 2 ++ 2 files changed, 19 insertions(+), 7 deletions(-) Index: multipath-tools-130222/libmultipath/structs_vec.c =================================================================== --- multipath-tools-130222.orig/libmultipath/structs_vec.c +++ multipath-tools-130222/libmultipath/structs_vec.c @@ -312,24 +312,33 @@ update_multipath_strings (struct multipa extern void set_no_path_retry(struct multipath *mpp) { - mpp->retry_tick = 0; + char is_queueing = 0; + mpp->nr_active = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST); - select_no_path_retry(mpp); + if (mpp->features && strstr(mpp->features, "queue_if_no_path")) + is_queueing = 1; switch (mpp->no_path_retry) { case NO_PATH_RETRY_UNDEF: break; case NO_PATH_RETRY_FAIL: - dm_queue_if_no_path(mpp->alias, 0); + if (is_queueing) + dm_queue_if_no_path(mpp->alias, 0); break; case NO_PATH_RETRY_QUEUE: - dm_queue_if_no_path(mpp->alias, 1); + if (!is_queueing) + dm_queue_if_no_path(mpp->alias, 1); break; default: - dm_queue_if_no_path(mpp->alias, 1); - if (mpp->nr_active == 0) { + if (mpp->nr_active > 0) { + mpp->retry_tick = 0; + if (!is_queueing) + dm_queue_if_no_path(mpp->alias, 1); + } else if (is_queueing && mpp->retry_tick == 0) { /* Enter retry mode */ - mpp->retry_tick = mpp->no_path_retry * conf->checkint; + mpp->stat_queueing_timeouts++; + mpp->retry_tick = mpp->no_path_retry * + conf->checkint + 1; condlog(1, "%s: Entering recovery mode: max_retries=%d", mpp->alias, mpp->no_path_retry); } @@ -360,6 +369,7 @@ __setup_multipath (struct vectors * vecs if (reset) { select_rr_weight(mpp); select_pgfailback(mpp); + select_no_path_retry(mpp); set_no_path_retry(mpp); select_pg_timeout(mpp); select_flush_on_last_del(mpp); Index: multipath-tools-130222/multipathd/main.c =================================================================== --- multipath-tools-130222.orig/multipathd/main.c +++ multipath-tools-130222/multipathd/main.c @@ -1464,6 +1464,8 @@ check_path (struct vectors * vecs, struc if (!pp->mpp) return 0; + set_no_path_retry(pp->mpp); + if ((newstate == PATH_UP || newstate == PATH_GHOST) && pp->io_err_disable_reinstate && need_io_err_check(pp)) { pp->state = PATH_SHAKY;