device-mapper-multipath/0043-libmpathpersist-limit-changing-prflag-in-update_map_.patch
Benjamin Marzinski 695f9436f4 device-mapper-multipath-0.9.9-13
Add 0035-libmpathpersist-fix-memory-leak-in-mpath_prout_rel.patch
Add 0036-libmpathpersist-retry-commands-on-other-paths-in-mpa.patch
Add 0037-libmpathpersist-check-released-key-against-the-reser.patch
Add 0038-multipathd-remove-thread-from-mpath_pr_event_handle.patch
Add 0039-libmpathpersist-remove-uneeded-wrapper-function.patch
Add 0040-libmpathpersist-reduce-log-level-for-persistent-rese.patch
Add 0041-libmpathpersist-remove-pointless-update_map_pr-ret-v.patch
Add 0042-multipathd-use-update_map_pr-in-mpath_pr_event_handl.patch
Add 0043-libmpathpersist-limit-changing-prflag-in-update_map_.patch
Add 0044-multipathd-Don-t-call-update_map_pr-unnecessarily.patch
Add 0045-libmpathpersist-remove-useless-function-send_prout_a.patch
Add 0046-libmpathpersist-redesign-failed-release-workaround.patch
Add 0047-libmpathpersist-fail-the-release-if-all-threads-fail.patch
Add 0048-libmpathpersist-Handle-changing-key-corner-case.patch
Add 0049-libmpathpersist-Handle-REGISTER-AND-IGNORE-changing-.patch
Add 0050-libmultipath-rename-prflag_value-enums.patch
Add 0051-libmpathpersist-use-a-switch-statement-for-prout-com.patch
Add 0052-libmpathpersist-Add-safety-check-for-preempting-on-k.patch
Add 0053-libmpathpersist-remove-update_map_pr-code-for-NULL-p.patch
Add 0054-libmpathpersist-move-update_map_pr-to-multipathd.patch
Add 0055-multipathd-clean-up-update_map_pr-and-mpath_pr_event.patch
Add 0056-libmpathpersist-clean-up-duplicate-function-declarat.patch
Add 0057-multipathd-wrap-setting-and-unsetting-prflag.patch
Add 0058-multipathd-unregister-PR-key-when-path-is-restored-i.patch
Add 0059-libmpathpersist-Fix-up-reservation_key-checking.patch
Add 0060-libmpathpersist-change-how-reservation-conflicts-are.patch
Add 0061-libmpathpersist-Clear-prkey-in-multipathd-before-unr.patch
Add 0062-libmpathpersist-only-clear-the-key-if-we-are-using-t.patch
Add 0063-libmpathpersist-Restore-old-reservation-key-on-failu.patch
Add 0064-libmpathpersist-update-reservation-key-before-checki.patch
Add 0065-libmpathpersist-retry-on-conflicts-in-mpath_prout_co.patch
Add 0066-libmpathpersist-Don-t-always-fail-registrations-for-.patch
Add 0067-libmpathpersist-Don-t-try-release-workaround-for-inv.patch
Add 0068-libmpathpersist-Don-t-fail-RESERVE-commands-unnecess.patch
Add 0069-libmpathpersist-reregister-keys-when-self-preempting.patch
Add 0070-libmpathpersist-handle-updating-key-race-condition.patch
Add 0071-libmpathpersist-handle-preempting-all-registrants-re.patch
Add 0072-libmpathpersist-Fix-REGISTER-AND-IGNORE-while-holdin.patch
Add 0073-libmpathpersist-Handle-RESERVE-with-reservation-held.patch
Add 0074-libmpathpersist-use-check_holding_reservation-in-mpa.patch
Add 0075-libmpathpersist-Fix-unregistering-while-holding-the-.patch
Add 0076-libmpathpersist-Fix-race-between-restoring-a-path-an.patch
Add 0077-multipathd-Fix-tracking-of-old-PR-key.patch
  * Fixes RHEL-118720 ("There are many bugs in multipath's persistent
    reservation handling [rhel-10]")
Resolves: RHEL-118720
2025-10-01 16:53:32 -04:00

78 lines
3.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 10 Jul 2025 14:10:51 -0400
Subject: [PATCH] libmpathpersist: limit changing prflag in update_map_pr
Do not unset mpp->prflag in update_map_pr() unless the device doesn't
support persistent reservations or it successfully reads the registered
keys and discovers that the device's key is not there. Also, nothing in
the libmpathpersist ever returns MPATH_PR_SENSE_INVALID_OP. It instead
returns MPATH_PR_ILLEGAL_REQ if the device doesn't support persistent
reservations, so check for that instead.
Also, do not even check for the registered keys in update_map_pr() if
mpp->prflag is unset. Otherwise, multipathd will set mpp->prflag if the
key was unregistered (and thus prflag was unset) while a path is down
(and thus could not have its key unregistered) and then that path comes
back up. I should note that the above issue can only occur if multipath
is defining PR keys in /etc/multipath.conf, instead of the prkeys file.
If a device has no registered keys, it must unset prflag, since that
means it's no longer registered. Possibly its registration was removed
by a CLEAR or PREEMPT action. But if a device has a registered key but
it is supposed to be unregistered, it should remain unregistered, since
that key is likely one that libmpathpersist could not unregister at the
time.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Reviewed-by: Martin Wilck <mwilck@suse.com>
---
libmpathpersist/mpath_persist_int.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c
index 8b01492f..c34bc785 100644
--- a/libmpathpersist/mpath_persist_int.c
+++ b/libmpathpersist/mpath_persist_int.c
@@ -73,7 +73,7 @@ static int mpath_prin_activepath (struct multipath *mpp, int rq_servact,
switch(ret)
{
case MPATH_PR_SUCCESS:
- case MPATH_PR_SENSE_INVALID_OP:
+ case MPATH_PR_ILLEGAL_REQ:
return ret;
default:
continue;
@@ -735,6 +735,10 @@ int update_map_pr(struct multipath *mpp, struct path *pp)
int ret = MPATH_PR_OTHER, isFound;
bool was_set = (mpp->prflag == PRFLAG_SET);
+ /* If pr is explicitly unset, it must be manually set */
+ if (mpp->prflag == PRFLAG_UNSET)
+ return MPATH_PR_SKIP;
+
if (!get_be64(mpp->reservation_key))
{
/* Nothing to do. Assuming pr mgmt feature is disabled*/
@@ -755,7 +759,6 @@ int update_map_pr(struct multipath *mpp, struct path *pp)
condlog(2, "%s: No available paths to check pr status", mpp->alias);
goto out;
}
- mpp->prflag = PRFLAG_UNSET;
if (pp)
ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp, noisy);
else
@@ -763,9 +766,12 @@ int update_map_pr(struct multipath *mpp, struct path *pp)
if (ret != MPATH_PR_SUCCESS )
{
+ if (ret == MPATH_PR_ILLEGAL_REQ)
+ mpp->prflag = PRFLAG_UNSET;
condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret);
goto out;
}
+ mpp->prflag = PRFLAG_UNSET;
if (resp->prin_descriptor.prin_readkeys.additional_length == 0 )
{