On Wed, 2025-09-10 at 18:58 -0400, Benjamin Marzinski wrote:
> All Registrants reservations (types 7 and 8) are held by key 0x0.
> When
> preempting one, all registrations are cleared, except for the one on
> the
> path that issued the PREEMPT. libmpathpersist needs to handle this
> just
> like the other cases of self-preemption, so that all the paths of the
> preempting multipath device have their registrations restored while
> the
> device is suspended.
>
> Signed-off-by: Benjamin Marzinski <[email protected]>
> ---
> libmpathpersist/mpath_persist_int.c | 31 +++++++++++++++++++++++++--
> --
> 1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/libmpathpersist/mpath_persist_int.c
> b/libmpathpersist/mpath_persist_int.c
> index 9f301859..ab3d70cd 100644
> --- a/libmpathpersist/mpath_persist_int.c
> +++ b/libmpathpersist/mpath_persist_int.c
> @@ -569,8 +569,9 @@ static int mpath_prout_reg(struct multipath
> *mpp,int rq_servact, int rq_scope,
> * is suspended before issuing the preemption, and the keys are
> reregistered
> * before resuming it.
> */
> -static int preempt_self(struct multipath *mpp, int rq_servact, int
> rq_scope,
> - unsigned int rq_type, int noisy, bool
> do_release)
> +static int do_preempt_self(struct multipath *mpp, struct be64
> sa_key,
> + int rq_servact, int rq_scope, unsigned
> int rq_type,
> + int noisy, bool do_release)
> {
> int status, rel_status = MPATH_PR_SUCCESS;
> struct path *pp = NULL;
> @@ -583,7 +584,7 @@ static int preempt_self(struct multipath *mpp,
> int rq_servact, int rq_scope,
> }
>
> memcpy(paramp.key, &mpp->reservation_key, 8);
> - memcpy(paramp.sa_key, &mpp->reservation_key, 8);
> + memcpy(paramp.sa_key, &sa_key, 8);
> status = mpath_prout_common(mpp, rq_servact, rq_scope,
> rq_type,
> ¶mp, noisy, &pp);
> if (status != MPATH_PR_SUCCESS) {
> @@ -619,6 +620,21 @@ fail_resume:
> return (rel_status != MPATH_PR_SUCCESS) ? rel_status :
> status;
> }
>
> +static int preempt_self(struct multipath *mpp, int rq_servact, int
> rq_scope,
> + unsigned int rq_type, int noisy, bool
> do_release)
> +{
> + return do_preempt_self(mpp, mpp->reservation_key,
> rq_servact, rq_scope,
> + rq_type, noisy, do_release);
> +}
> +
> +static int preempt_all(struct multipath *mpp, int rq_servact, int
> rq_scope,
> + unsigned int rq_type, int noisy)
> +{
> + struct be64 zerokey = {0};
> + return do_preempt_self(mpp, zerokey, rq_servact, rq_scope,
> rq_type,
> + noisy, 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)
> @@ -889,8 +905,15 @@ int do_mpath_persistent_reserve_out(vector
> curmp, vector pathvec, int fd,
> break;
> case MPATH_PROUT_PREE_SA:
> case MPATH_PROUT_PREE_AB_SA:
> - if (reservation_key_matches(mpp, paramp->sa_key,
> noisy) == YNU_YES)
> + if (reservation_key_matches(mpp, paramp->sa_key,
> noisy) == YNU_YES) {
> preempting_reservation = true;
> + if (memcmp(paramp->sa_key, &zerokey, 8) ==
> 0) {
Don't you need to check if pr_type is 7 or 8 here?
> + /* all registrants case */
> + ret = preempt_all(mpp, rq_servact,
> rq_scope,
> + rq_type, noisy);
> + break;
> + }
> + }
> /* if we are preempting ourself */
> if (memcmp(paramp->sa_key, paramp->key, 8) == 0) {
> ret = preempt_self(mpp, rq_servact,
> rq_scope, rq_type,