device-mapper-multipath/0074-libmpathpersist-use-check_holding_reservation-in-mpa.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

150 lines
5.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Benjamin Marzinski <bmarzins@redhat.com>
Date: Thu, 25 Sep 2025 16:48:49 -0400
Subject: [PATCH] libmpathpersist: use check_holding_reservation in
mpath_prout_rel
Instead of open-coding mostly the same work, just make mpath_prout_rel()
call check_holding_reservation().
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
---
libmpathpersist/mpath_persist_int.c | 86 ++++++++++++-----------------
1 file changed, 35 insertions(+), 51 deletions(-)
diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c
index 0cb08f88..0eb7041e 100644
--- a/libmpathpersist/mpath_persist_int.c
+++ b/libmpathpersist/mpath_persist_int.c
@@ -649,12 +649,42 @@ static int preempt_all(struct multipath *mpp, int rq_servact, int rq_scope,
noisy, false);
}
+static int reservation_key_matches(struct multipath *mpp, uint8_t *key,
+ unsigned int *type)
+{
+ struct prin_resp resp = {{{.prgeneration = 0}}};
+ int status;
+
+ status = mpath_prin_activepath(mpp, MPATH_PRIN_RRES_SA, &resp, 0);
+ if (status != MPATH_PR_SUCCESS) {
+ condlog(0, "%s: pr in read reservation command failed.", mpp->wwid);
+ return YNU_UNDEF;
+ }
+ if (!resp.prin_descriptor.prin_readresv.additional_length)
+ return YNU_NO;
+ if (memcmp(key, resp.prin_descriptor.prin_readresv.key, 8) == 0) {
+ if (type)
+ *type = resp.prin_descriptor.prin_readresv.scope_type &
+ MPATH_PR_TYPE_MASK;
+ return YNU_YES;
+ }
+ return YNU_NO;
+}
+
+static bool check_holding_reservation(struct multipath *mpp, unsigned int *type)
+{
+ if (get_be64(mpp->reservation_key) &&
+ get_prhold(mpp->alias) == PR_SET &&
+ reservation_key_matches(mpp, (uint8_t *)&mpp->reservation_key, type) == YNU_YES)
+ return true;
+ return false;
+}
+
static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
unsigned int rq_type,
struct prout_param_descriptor * paramp, int noisy)
{
int i, j;
- int num = 0;
struct pathgroup *pgp = NULL;
struct path *pp = NULL;
int active_pathcount = 0;
@@ -662,9 +692,8 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
int rc;
int count = 0;
int status = MPATH_PR_SUCCESS;
- struct prin_resp resp = {{{.prgeneration = 0}}};
bool all_threads_failed;
- unsigned int scope_type;
+ unsigned int res_type;
if (!mpp)
return MPATH_PR_DMMP_ERROR;
@@ -743,27 +772,13 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
return status;
}
- status = mpath_prin_activepath (mpp, MPATH_PRIN_RRES_SA, &resp, noisy);
- if (status != MPATH_PR_SUCCESS){
- condlog (0, "%s: pr in read reservation command failed.", mpp->wwid);
- return MPATH_PR_OTHER;
- }
-
- num = resp.prin_descriptor.prin_readresv.additional_length / 8;
- if (num == 0){
- condlog (2, "%s: Path holding reservation is released.", mpp->wwid);
- return MPATH_PR_SUCCESS;
- }
- if (!get_be64(mpp->reservation_key) ||
- memcmp(&mpp->reservation_key, resp.prin_descriptor.prin_readresv.key, 8)) {
+ if (!check_holding_reservation(mpp, &res_type)) {
condlog(2, "%s: Releasing key not holding reservation.", mpp->wwid);
return MPATH_PR_SUCCESS;
}
-
- scope_type = resp.prin_descriptor.prin_readresv.scope_type;
- if ((scope_type & MPATH_PR_TYPE_MASK) != rq_type) {
+ if (res_type != rq_type) {
condlog(2, "%s: --prout_type %u doesn't match reservation %u",
- mpp->wwid, rq_type, scope_type & MPATH_PR_TYPE_MASK);
+ mpp->wwid, rq_type, res_type);
return MPATH_PR_RESERV_CONFLICT;
}
@@ -783,28 +798,6 @@ static int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
return preempt_self(mpp, MPATH_PROUT_PREE_SA, rq_scope, rq_type, noisy, true);
}
-static int reservation_key_matches(struct multipath *mpp, uint8_t *key,
- unsigned int *type)
-{
- struct prin_resp resp = {{{.prgeneration = 0}}};
- int status;
-
- status = mpath_prin_activepath(mpp, MPATH_PRIN_RRES_SA, &resp, 0);
- if (status != MPATH_PR_SUCCESS) {
- condlog(0, "%s: pr in read reservation command failed.", mpp->wwid);
- return YNU_UNDEF;
- }
- if (!resp.prin_descriptor.prin_readresv.additional_length)
- return YNU_NO;
- if (memcmp(key, resp.prin_descriptor.prin_readresv.key, 8) == 0) {
- if (type)
- *type = resp.prin_descriptor.prin_readresv.scope_type &
- MPATH_PR_TYPE_MASK;
- return YNU_YES;
- }
- return YNU_NO;
-}
-
/*
* for MPATH_PROUT_REG_IGN_SA, we use the ignored paramp->key to store the
* currently registered key for use in preempt_missing_path(), but only if
@@ -823,15 +816,6 @@ static void set_ignored_key(struct multipath *mpp, uint8_t *curr_key,
memcpy(key, curr_key, 8);
}
-static bool check_holding_reservation(struct multipath *mpp, unsigned int *type)
-{
- if (get_be64(mpp->reservation_key) &&
- get_prhold(mpp->alias) == PR_SET &&
- reservation_key_matches(mpp, (uint8_t *)&mpp->reservation_key, type) == YNU_YES)
- return true;
- return false;
-}
-
int do_mpath_persistent_reserve_out(vector curmp, vector pathvec, int fd,
int rq_servact, int rq_scope, unsigned int rq_type,
struct prout_param_descriptor *paramp, int noisy)