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