For multipath devices with path group policies other than group_by_prio, multipathd wasn't updating all the paths' priorities when calling need_switch_pathgroup(), even in cases where it likely was necessary. When a path just becomes usable again, all paths' priorities get updated by update_prio(). But if the priority changes on a path that is already up, the other paths' priorities only get updated if the multipath device uses the group_by_prio path_grouping_policy, otherwise need_switch_pathgroup() is called with refresh set to 0. But if the priority of the checked path has changed, then likely so have the priorities of other paths. Since the pathgroup's priority is the average of its paths' priorities, changing the priority of just one path may not change the average enough to reorder the pathgroups. Instead, set refresh in need_switch_pathgroup() if the priorty has changed to something other than PRIO_UNDEF (which usually means an error has occured) and the priorities of the other paths haven't already been updated by update_prio(). Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> --- multipathd/main.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/multipathd/main.c b/multipathd/main.c index bdeffe76..e7c272ad 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -2575,20 +2575,27 @@ check_path (struct vectors * vecs, struct path * pp, unsigned int ticks) if (marginal_changed) reload_and_sync_map(pp->mpp, vecs, 1); - else if (update_prio(pp, new_path_up) && - (pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio) && - pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) { - condlog(2, "%s: path priorities changed. reloading", - pp->mpp->alias); - reload_and_sync_map(pp->mpp, vecs, !new_path_up); - } else if (need_switch_pathgroup(pp->mpp, 0)) { - if (pp->mpp->pgfailback > 0 && - (new_path_up || pp->mpp->failback_tick <= 0)) - pp->mpp->failback_tick = - pp->mpp->pgfailback + 1; - else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE || - (chkr_new_path_up && followover_should_failback(pp))) - switch_pathgroup(pp->mpp); + else { + int prio_changed = update_prio(pp, new_path_up); + bool need_refresh = (!new_path_up && prio_changed && + pp->priority != PRIO_UNDEF); + + if (prio_changed && + pp->mpp->pgpolicyfn == (pgpolicyfn *)group_by_prio && + pp->mpp->pgfailback == -FAILBACK_IMMEDIATE) { + condlog(2, "%s: path priorities changed. reloading", + pp->mpp->alias); + reload_and_sync_map(pp->mpp, vecs, !new_path_up); + } else if (need_switch_pathgroup(pp->mpp, need_refresh)) { + if (pp->mpp->pgfailback > 0 && + (new_path_up || pp->mpp->failback_tick <= 0)) + pp->mpp->failback_tick = + pp->mpp->pgfailback + 1; + else if (pp->mpp->pgfailback == -FAILBACK_IMMEDIATE || + (chkr_new_path_up && + followover_should_failback(pp))) + switch_pathgroup(pp->mpp); + } } return 1; } -- 2.17.2 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/dm-devel