From beaf9c99679d31c6cf423974ff39a7f3eb7a19ba Mon Sep 17 00:00:00 2001 From: Benjamin Marzinski Date: Tue, 21 Apr 2026 19:36:13 -0400 Subject: [PATCH] device-mapper-multipath-0.8.7-47 Add 0212-libmultipath-return-pending-state-when-port-is-in-tr.patch * Fixes RHEL-165540 ("multipath's tur checker should mark transitioning paths as PATH_PENDING") Resolves: RHEL-165540 --- ...urn-pending-state-when-port-is-in-tr.patch | 100 ++++++++++++++++++ device-mapper-multipath.spec | 9 +- 2 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 0212-libmultipath-return-pending-state-when-port-is-in-tr.patch diff --git a/0212-libmultipath-return-pending-state-when-port-is-in-tr.patch b/0212-libmultipath-return-pending-state-when-port-is-in-tr.patch new file mode 100644 index 0000000..7c25d52 --- /dev/null +++ b/0212-libmultipath-return-pending-state-when-port-is-in-tr.patch @@ -0,0 +1,100 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Tue, 7 Mar 2023 16:49:32 -0600 +Subject: [PATCH] libmultipath: return 'pending' state when port is in + transition + +The tur checker should not return that a path is down when it is in the +transitioning state. Instead, it should return PATH_PENDING, so that +the path retains its current state, and multipathd can react quickly +when it moves out of the transitioning state. + +The code needs to be careful to differentiate between when the checker +thread has finished and returned PATH_PENDING, and when it is still +running. + +Reported-by: Brian Bunker +Signed-off-by: Benjamin Marzinski +Reviewed-by: Martin Wilck +Tested-by: Brian Bunker +--- + libmultipath/checkers/tur.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c +index 370a02a6..ef88472e 100644 +--- a/libmultipath/checkers/tur.c ++++ b/libmultipath/checkers/tur.c +@@ -33,6 +33,7 @@ enum { + MSG_TUR_RUNNING = CHECKER_FIRST_MSGID, + MSG_TUR_TIMEOUT, + MSG_TUR_FAILED, ++ MSG_TUR_TRANSITIONING, + }; + + #define _IDX(x) (MSG_ ## x - CHECKER_FIRST_MSGID) +@@ -40,6 +41,7 @@ const char *libcheck_msgtable[] = { + [_IDX(TUR_RUNNING)] = " still running", + [_IDX(TUR_TIMEOUT)] = " timed out", + [_IDX(TUR_FAILED)] = " failed to initialize", ++ [_IDX(TUR_TRANSITIONING)] = " reports path is transitioning", + NULL, + }; + +@@ -180,13 +182,20 @@ retry: + else if (key == 0x2) { + /* Not Ready */ + /* Note: Other ALUA states are either UP or DOWN */ +- if( asc == 0x04 && ascq == 0x0b){ ++ if (asc == 0x04 && ascq == 0x0b) { + /* + * LOGICAL UNIT NOT ACCESSIBLE, + * TARGET PORT IN STANDBY STATE + */ + *msgid = CHECKER_MSGID_GHOST; + return PATH_GHOST; ++ } else if (asc == 0x04 && ascq == 0x0a) { ++ /* ++ * LOGICAL UNIT NOT ACCESSIBLE, ++ * ASYMMETRIC ACCESS STATE TRANSITION ++ */ ++ *msgid = MSG_TUR_TRANSITIONING; ++ return PATH_PENDING; + } + } else if (key == 0x5) { + /* Illegal request */ +@@ -361,6 +370,7 @@ int libcheck_check(struct checker * c) + condlog(3, "%d:%d : tur checker not finished", + major(ct->devt), minor(ct->devt)); + tur_status = PATH_PENDING; ++ c->msgid = MSG_TUR_RUNNING; + } else { + /* TUR checker done */ + ct->thread = 0; +@@ -415,7 +425,7 @@ int libcheck_check(struct checker * c) + /* Start new TUR checker */ + pthread_mutex_lock(&ct->lock); + tur_status = ct->state = PATH_PENDING; +- ct->msgid = CHECKER_MSGID_NONE; ++ c->msgid = ct->msgid = MSG_TUR_RUNNING; + pthread_mutex_unlock(&ct->lock); + ct->fd = c->fd; + ct->timeout = c->timeout; +@@ -435,7 +445,7 @@ int libcheck_check(struct checker * c) + } + tur_timeout(&tsp); + pthread_mutex_lock(&ct->lock); +- if (ct->state == PATH_PENDING) ++ if (ct->state == PATH_PENDING && ct->msgid == MSG_TUR_RUNNING) + r = pthread_cond_timedwait(&ct->active, &ct->lock, + &tsp); + if (!r) { +@@ -443,7 +453,7 @@ int libcheck_check(struct checker * c) + c->msgid = ct->msgid; + } + pthread_mutex_unlock(&ct->lock); +- if (tur_status == PATH_PENDING) { ++ if (tur_status == PATH_PENDING && c->msgid == MSG_TUR_RUNNING) { + condlog(4, "%d:%d : tur checker still running", + major(ct->devt), minor(ct->devt)); + } else { diff --git a/device-mapper-multipath.spec b/device-mapper-multipath.spec index b8abae7..dd1688e 100644 --- a/device-mapper-multipath.spec +++ b/device-mapper-multipath.spec @@ -1,6 +1,6 @@ Name: device-mapper-multipath Version: 0.8.7 -Release: 46%{?dist} +Release: 47%{?dist} Summary: Tools to manage multipath devices using device-mapper License: GPLv2 URL: http://christophe.varoqui.free.fr/ @@ -221,6 +221,7 @@ Patch0208: 0208-libmpathpersist-fix-register-retry-status-checking.patch Patch0209: 0209-multipathd-remember-number-of-registered-keys-when-i.patch Patch0210: 0210-libmpathpersist-fix-code-for-skipping-multipathd-pat.patch Patch0211: 0211-libmultipath-set-offline-whenever-path-is-not-online.patch +Patch0212: 0212-libmultipath-return-pending-state-when-port-is-in-tr.patch # runtime Requires: %{name}-libs = %{version}-%{release} @@ -423,6 +424,12 @@ fi %{_pkgconfdir}/libdmmp.pc %changelog +* Tue Apr 21 2026 Benjamin Marzinski - 0.8.7-47 +- Add 0212-libmultipath-return-pending-state-when-port-is-in-tr.patch + * Fixes RHEL-165540 ("multipath's tur checker should mark + transitioning paths as PATH_PENDING") +- Resolves: RHEL-165540 + * Fri Mar 6 2026 Benjamin Marzinski - 0.8.7-46 - Add 0211-libmultipath-set-offline-whenever-path-is-not-online.patch * Fixes RHEL-151448 ("multipathd doesn't print checker messages for