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 <bmarz...@redhat.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 92c3ea7e..e312d577 100644
--- a/libmpathpersist/mpath_persist_int.c
+++ b/libmpathpersist/mpath_persist_int.c
@@ -74,7 +74,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;
@@ -728,6 +728,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*/
@@ -747,7 +751,6 @@ int update_map_pr(struct multipath *mpp, struct path *pp)
                        mpp->alias);
                goto out;
        }
-       mpp->prflag = PRFLAG_UNSET;
        if (pp)
                ret = prin_do_scsi_ioctl(pp->dev, MPATH_PRIN_RKEY_SA, resp,
                                         noisy);
@@ -757,9 +760,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 )
        {
-- 
2.48.1


Reply via email to