1 #include "mpath_persist.h"
2 #include <libdevmapper.h>
5 #include <linux/kdev_t.h>
10 #include <structs_vec.h>
14 #include <devmapper.h>
17 #include <switchgroup.h>
18 #include <discovery.h>
24 #include "mpath_pr_ioctl.h"
31 #define __STDC_FORMAT_MACROS 1
37 if (load_config(DEFAULT_CONFIGFILE)){
38 condlog(0, "Failed to initialize multipath config.");
58 updatepaths (struct multipath * mpp)
61 struct pathgroup * pgp;
67 vector_foreach_slot (mpp->pg, pgp, i){
71 vector_foreach_slot (pgp->paths, pp, j){
72 if (!strlen(pp->dev)){
73 if (devt2devname(pp->dev, pp->dev_t)){
75 * path is not in sysfs anymore
77 pp->state = PATH_DOWN;
81 pathinfo(pp, conf->hwtable, DI_ALL);
85 if (pp->state == PATH_UNCHECKED ||
86 pp->state == PATH_WILD)
87 pathinfo(pp, conf->hwtable, DI_CHECKER);
89 if (pp->priority == PRIO_UNDEF)
90 pathinfo(pp, conf->hwtable, DI_PRIO);
97 mpath_prin_activepath (struct multipath *mpp, int rq_servact,
98 struct prin_resp * resp, int noisy)
100 int i,j, ret = MPATH_PR_DMMP_ERROR;
101 struct pathgroup *pgp = NULL;
102 struct path *pp = NULL;
104 vector_foreach_slot (mpp->pg, pgp, j){
105 vector_foreach_slot (pgp->paths, pp, i){
106 if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
107 condlog(2, "%s: %s not available. Skip.", mpp->wwid, pp->dev);
108 condlog(3, "%s: status = %d.", mpp->wwid, pp->state);
112 condlog(3, "%s: sending pr in command to %s ", mpp->wwid, pp->dev);
113 ret = mpath_send_prin_activepath(pp->dev, rq_servact, resp, noisy);
116 case MPATH_PR_SUCCESS:
117 case MPATH_PR_SENSE_INVALID_OP:
127 int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp, int noisy, int verbose)
131 vector pathvec = NULL;
133 struct multipath * mpp;
138 conf->verbosity = verbose;
140 if (fstat( fd, &info) != 0){
141 condlog(0, "stat error %d", fd);
142 return MPATH_PR_FILE_ERROR;
144 if(!S_ISBLK(info.st_mode)){
145 condlog(0, "Failed to get major:minor. fd = %d", fd);
146 return MPATH_PR_FILE_ERROR;
149 major = (int)MAJOR(info.st_rdev);
150 minor = (int)MINOR(info.st_rdev);
151 condlog(4, "Device %d:%d: ", major, minor);
153 /* get alias from major:minor*/
154 alias = dm_mapname(major, minor);
156 condlog(0, "%d:%d failed to get device alias.", major, minor);
157 return MPATH_PR_DMMP_ERROR;
160 condlog(3, "alias = %s", alias);
161 map_present = dm_map_present(alias);
162 if (map_present && dm_type(alias, TGT_MPATH) <= 0){
163 condlog( 0, "%s: not a multipath device.", alias);
164 ret = MPATH_PR_DMMP_ERROR;
169 * allocate core vectors to store paths and multipaths
171 curmp = vector_alloc ();
172 pathvec = vector_alloc ();
174 if (!curmp || !pathvec){
175 condlog (0, "%s: vector allocation failed.", alias);
176 ret = MPATH_PR_DMMP_ERROR;
180 if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER))
183 /* get info of all paths from the dm device */
184 if (get_mpvec (curmp, pathvec, alias)){
185 condlog(0, "%s: failed to get device info.", alias);
186 ret = MPATH_PR_DMMP_ERROR;
190 mpp = find_mp_by_alias(curmp, alias);
192 condlog(0, "%s: devmap not registered.", alias);
193 ret = MPATH_PR_DMMP_ERROR;
197 ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy);
200 free_multipathvec(curmp, KEEP_PATHS);
201 free_pathvec(pathvec, FREE_PATHS);
207 int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
208 unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose)
214 vector pathvec = NULL;
217 struct multipath * mpp;
225 conf->verbosity = verbose;
227 if (fstat( fd, &info) != 0){
228 condlog(0, "stat error fd=%d", fd);
229 return MPATH_PR_FILE_ERROR;
232 if(!S_ISBLK(info.st_mode)){
233 condlog(3, "Failed to get major:minor. fd=%d", fd);
234 return MPATH_PR_FILE_ERROR;
237 major = (int)MAJOR(info.st_rdev);
238 minor = (int)MINOR(info.st_rdev);
239 condlog(4, "Device %d:%d", major, minor);
241 /* get WWN of the device from major:minor*/
242 alias = dm_mapname(major, minor);
244 return MPATH_PR_DMMP_ERROR;
247 condlog(3, "alias = %s", alias);
248 map_present = dm_map_present(alias);
250 if (map_present && dm_type(alias, TGT_MPATH) <= 0){
251 condlog(3, "%s: not a multipath device.", alias);
252 ret = MPATH_PR_DMMP_ERROR;
257 * allocate core vectors to store paths and multipaths
259 curmp = vector_alloc ();
260 pathvec = vector_alloc ();
262 if (!curmp || !pathvec){
263 condlog (0, "%s: vector allocation failed.", alias);
264 ret = MPATH_PR_DMMP_ERROR;
268 if (path_discovery(pathvec, conf, DI_SYSFS | DI_CHECKER))
271 /* get info of all paths from the dm device */
272 if (get_mpvec(curmp, pathvec, alias)){
273 condlog(0, "%s: failed to get device info.", alias);
274 ret = MPATH_PR_DMMP_ERROR;
278 mpp = find_mp_by_alias(curmp, alias);
281 condlog(0, "%s: devmap not registered.", alias);
282 ret = MPATH_PR_DMMP_ERROR;
286 select_reservation_key(mpp);
290 case MPATH_PROUT_REG_SA:
291 case MPATH_PROUT_REG_IGN_SA:
292 ret= mpath_prout_reg(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
294 case MPATH_PROUT_RES_SA :
295 case MPATH_PROUT_PREE_SA :
296 case MPATH_PROUT_PREE_AB_SA :
297 case MPATH_PROUT_CLEAR_SA:
298 ret = mpath_prout_common(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
300 case MPATH_PROUT_REL_SA:
301 ret = mpath_prout_rel(mpp, rq_servact, rq_scope, rq_type, paramp, noisy);
304 ret = MPATH_PR_OTHER;
308 if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_REG_SA) ||
309 (rq_servact == MPATH_PROUT_REG_IGN_SA)))
313 for (j = 0; j < 8; ++j) {
320 update_prflag(alias, "unset", noisy);
322 update_prflag(alias, "set", noisy);
324 if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_CLEAR_SA) ||
325 (rq_servact == MPATH_PROUT_PREE_AB_SA ))){
326 update_prflag(alias, "unset", noisy);
330 free_multipathvec(curmp, KEEP_PATHS);
331 free_pathvec(pathvec, FREE_PATHS);
339 get_mpvec (vector curmp, vector pathvec, char * refwwid)
342 struct multipath *mpp;
343 char params[PARAMS_SIZE], status[PARAMS_SIZE];
345 if (dm_get_maps (curmp)){
349 vector_foreach_slot (curmp, mpp, i){
351 * discard out of scope maps
353 if (mpp->alias && refwwid && strncmp (mpp->alias, refwwid, WWID_SIZE)){
354 free_multipath (mpp, KEEP_PATHS);
355 vector_del_slot (curmp, i);
360 dm_get_map(mpp->alias, &mpp->size, params);
361 condlog(3, "params = %s", params);
362 dm_get_status(mpp->alias, status);
363 condlog(3, "status = %s", status);
364 disassemble_map (pathvec, params, mpp);
367 * disassemble_map() can add new paths to pathvec.
368 * If not in "fast list mode", we need to fetch information
372 mpp->bestpg = select_path_group (mpp);
373 disassemble_status (status, mpp);
376 return MPATH_PR_SUCCESS ;
379 void * mpath_prin_pthread_fn (void *p)
382 struct prin_param * pparam = (struct prin_param *)p;
384 ret = prin_do_scsi_ioctl(pparam->dev, pparam->rq_servact, pparam->resp, pparam->noisy);
385 pparam->status = ret;
389 int mpath_send_prin_activepath (char * dev, int rq_servact, struct prin_resp * resp, int noisy)
394 rc = prin_do_scsi_ioctl(dev, rq_servact, resp, noisy);
399 int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope,
400 unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
404 struct pathgroup *pgp = NULL;
405 struct path *pp = NULL;
407 int active_pathcount=0;
410 int status = MPATH_PR_SUCCESS;
414 return MPATH_PR_DMMP_ERROR;
416 active_pathcount = pathcount(mpp, PATH_UP) + pathcount(mpp, PATH_GHOST);
418 if (active_pathcount == 0) {
419 condlog (0, "%s: no path available", mpp->wwid);
420 return MPATH_PR_DMMP_ERROR;
423 if ( paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK ) {
424 condlog (1, "Warning: ALL_TG_PT is set. Configuration not supported");
427 struct threadinfo thread[active_pathcount];
429 memset(thread, 0, sizeof(thread));
431 /* init thread parameter */
432 for (i =0; i< active_pathcount; i++){
433 thread[i].param.rq_servact = rq_servact;
434 thread[i].param.rq_scope = rq_scope;
435 thread[i].param.rq_type = rq_type;
436 thread[i].param.paramp = paramp;
437 thread[i].param.noisy = noisy;
438 thread[i].param.status = -1;
440 condlog (3, "THRED ID [%d] INFO]", i);
441 condlog (3, "rq_servact=%d ", thread[i].param.rq_servact);
442 condlog (3, "rq_scope=%d ", thread[i].param.rq_scope);
443 condlog (3, "rq_type=%d ", thread[i].param.rq_type);
444 condlog (3, "rkey=");
445 condlog (3, "paramp->sa_flags =%02x ", thread[i].param.paramp->sa_flags);
446 condlog (3, "noisy=%d ", thread[i].param.noisy);
447 condlog (3, "status=%d ", thread[i].param.status);
451 pthread_attr_init(&attr);
452 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
454 vector_foreach_slot (mpp->pg, pgp, j){
455 vector_foreach_slot (pgp->paths, pp, i){
456 if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
457 condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev);
460 strncpy(thread[count].param.dev, pp->dev, FILE_NAME_SIZE);
462 if (count && (thread[count].param.paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)){
464 * Clearing SPEC_I_PT as transportids are already registered by now.
466 thread[count].param.paramp->sa_flags &= (~MPATH_F_SPEC_I_PT_MASK);
469 condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
471 rc = pthread_create(&thread[count].id, &attr, mpath_prout_pthread_fn, (void *)(&thread[count].param));
473 condlog (0, "%s: failed to create thread %d", mpp->wwid, rc);
478 for( i=0; i < active_pathcount ; i++){
479 rc = pthread_join(thread[i].id, NULL);
481 condlog (0, "%s: Thread[%d] failed to join thread %d", mpp->wwid, i, rc);
483 if (!rollback && (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)){
486 for (i = 0; i < 8; ++i){
489 sa_key |= paramp->sa_key[i];
491 status = MPATH_PR_RESERV_CONFLICT ;
493 if (!rollback && (status == MPATH_PR_SUCCESS)){
494 status = thread[i].param.status;
497 if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){
498 condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid);
499 for( i=0 ; i < active_pathcount ; i++){
500 if((thread[i].param.status == MPATH_PR_SUCCESS) &&
501 ((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
502 memcpy(&thread[i].param.paramp->key, &thread[i].param.paramp->sa_key, 8);
503 memset(&thread[i].param.paramp->sa_key, 0, 8);
504 thread[i].param.status = MPATH_PR_SUCCESS;
505 rc = pthread_create(&thread[i].id, &attr, mpath_prout_pthread_fn,
506 (void *)(&thread[count].param));
508 condlog (0, "%s: failed to create thread for rollback. %d", mpp->wwid, rc);
512 for(i=0; i < active_pathcount ; i++){
513 rc = pthread_join(thread[i].id, NULL);
515 condlog (3, "%s: failed to join thread while rolling back %d",
521 pthread_attr_destroy(&attr);
525 void * mpath_prout_pthread_fn(void *p)
528 struct prout_param * param = (struct prout_param *)p;
530 ret = prout_do_scsi_ioctl( param->dev,param->rq_servact, param->rq_scope,
531 param->rq_type, param->paramp, param->noisy);
536 int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope,
537 unsigned int rq_type, struct prout_param_descriptor* paramp, int noisy)
540 struct pathgroup *pgp = NULL;
541 struct path *pp = NULL;
543 vector_foreach_slot (mpp->pg, pgp, j){
544 vector_foreach_slot (pgp->paths, pp, i){
545 if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
546 condlog (1, "%s: %s path not up. Skip", mpp->wwid, pp->dev);
550 condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
551 ret = send_prout_activepath(pp->dev, rq_servact, rq_scope, rq_type,
556 return MPATH_PR_SUCCESS;
559 int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
560 unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
562 struct prout_param param;
563 param.rq_servact = rq_servact;
564 param.rq_scope = rq_scope;
565 param.rq_type = rq_type;
566 param.paramp = paramp;
574 memset(&thread, 0, sizeof(thread));
575 strncpy(param.dev, dev, FILE_NAME_SIZE);
576 /* Initialize and set thread joinable attribute */
577 pthread_attr_init(&attr);
578 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
580 rc = pthread_create(&thread, &attr, mpath_prout_pthread_fn, (void *)(¶m));
582 condlog (3, "%s: failed to create thread %d", dev, rc);
585 /* Free attribute and wait for the other threads */
586 pthread_attr_destroy(&attr);
587 rc = pthread_join(thread, NULL);
589 return (param.status);
592 int mpath_prout_rel(struct multipath *mpp,int rq_servact, int rq_scope,
593 unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy)
597 struct pathgroup *pgp = NULL;
598 struct path *pp = NULL;
599 int active_pathcount = 0;
603 int status = MPATH_PR_SUCCESS;
604 struct prin_resp resp;
605 struct prout_param_descriptor *pamp;
606 struct prin_resp *pr_buff;
608 struct transportid *pptr;
611 return MPATH_PR_DMMP_ERROR;
613 active_pathcount = pathcount (mpp, PATH_UP) + pathcount (mpp, PATH_GHOST);
615 struct threadinfo thread[active_pathcount];
616 memset(thread, 0, sizeof(thread));
617 for (i = 0; i < active_pathcount; i++){
618 thread[i].param.rq_servact = rq_servact;
619 thread[i].param.rq_scope = rq_scope;
620 thread[i].param.rq_type = rq_type;
621 thread[i].param.paramp = paramp;
622 thread[i].param.noisy = noisy;
623 thread[i].param.status = -1;
625 condlog (3, " path count = %d", i);
626 condlog (3, "rq_servact=%d ", thread[i].param.rq_servact);
627 condlog (3, "rq_scope=%d ", thread[i].param.rq_scope);
628 condlog (3, "rq_type=%d ", thread[i].param.rq_type);
629 condlog (3, "noisy=%d ", thread[i].param.noisy);
630 condlog (3, "status=%d ", thread[i].param.status);
633 pthread_attr_init (&attr);
634 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
636 vector_foreach_slot (mpp->pg, pgp, j){
637 vector_foreach_slot (pgp->paths, pp, i){
638 if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){
639 condlog (1, "%s: %s path not up.", mpp->wwid, pp->dev);
643 strncpy(thread[count].param.dev, pp->dev, FILE_NAME_SIZE);
644 condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev);
645 rc = pthread_create (&thread[count].id, &attr, mpath_prout_pthread_fn,
646 (void *) (&thread[count].param));
648 condlog (0, "%s: failed to create thread. %d", mpp->wwid, rc);
652 pthread_attr_destroy (&attr);
653 for (i = 0; i < active_pathcount; i++){
654 rc = pthread_join (thread[i].id, NULL);
656 condlog (1, "%s: failed to join thread. %d", mpp->wwid, rc);
660 for (i = 0; i < active_pathcount; i++){
661 /* check thread status here and return the status */
663 if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)
664 status = MPATH_PR_RESERV_CONFLICT;
665 else if (status == MPATH_PR_SUCCESS
666 && thread[i].param.status != MPATH_PR_RESERV_CONFLICT)
667 status = thread[i].param.status;
670 status = mpath_prin_activepath (mpp, MPATH_PRIN_RRES_SA, &resp, noisy);
671 if (status != MPATH_PR_SUCCESS){
672 condlog (0, "%s: pr in read reservation command failed.", mpp->wwid);
673 return MPATH_PR_OTHER;
676 num = resp.prin_descriptor.prin_readresv.additional_length / 8;
678 condlog (2, "%s: Path holding reservation is released.", mpp->wwid);
679 return MPATH_PR_SUCCESS;
681 condlog (2, "%s: Path holding reservation is not avialable.", mpp->wwid);
683 pr_buff = mpath_alloc_prin_response(MPATH_PRIN_RFSTAT_SA);
685 condlog (0, "%s: failed to alloc pr in response buffer.", mpp->wwid);
686 return MPATH_PR_OTHER;
689 status = mpath_prin_activepath (mpp, MPATH_PRIN_RFSTAT_SA, pr_buff, noisy);
691 if (status != MPATH_PR_SUCCESS){
692 condlog (0, "%s: pr in read full status command failed.", mpp->wwid);
696 num = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor;
700 length = sizeof (struct prout_param_descriptor) + (sizeof (struct transportid *));
702 pamp = (struct prout_param_descriptor *)malloc (length);
704 condlog (0, "%s: failed to alloc pr out parameter.", mpp->wwid);
708 memset(pamp, 0, length);
710 pamp->trnptid_list[0] = (struct transportid *) malloc (sizeof (struct transportid));
711 if (!pamp->trnptid_list[0]){
712 condlog (0, "%s: failed to alloc pr out transportid.", mpp->wwid);
716 if (mpp->reservation_key ){
717 memcpy (pamp->key, mpp->reservation_key, 8);
718 condlog (3, "%s: reservation key set.", mpp->wwid);
721 mpath_prout_common (mpp, MPATH_PROUT_CLEAR_SA, rq_scope, rq_type, pamp,
724 pamp->num_transportid = 1;
725 pptr=pamp->trnptid_list[0];
727 for (i = 0; i < num; i++){
728 if (mpp->reservation_key &&
729 memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key,
730 mpp->reservation_key, 8)){
731 /*register with tarnsport id*/
732 memset(pamp, 0, length);
733 pamp->trnptid_list[0] = pptr;
734 memset (pamp->trnptid_list[0], 0, sizeof (struct transportid));
735 memcpy (pamp->sa_key,
736 pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8);
737 pamp->sa_flags = MPATH_F_SPEC_I_PT_MASK;
738 pamp->num_transportid = 1;
740 memcpy (pamp->trnptid_list[0],
741 &pr_buff->prin_descriptor.prin_readfd.descriptors[i]->trnptid,
742 sizeof (struct transportid));
743 status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type,
747 memcpy (pamp->key, pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8);
748 memset (pamp->sa_key, 0, 8);
749 pamp->num_transportid = 0;
750 status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type,
755 if (mpp->reservation_key)
763 memset (pamp, 0, length);
764 memcpy (pamp->sa_key, mpp->reservation_key, 8);
765 memset (pamp->key, 0, 8);
766 status = mpath_prout_reg(mpp, MPATH_PROUT_REG_SA, rq_scope, rq_type, pamp, noisy);
778 void * mpath_alloc_prin_response(int prin_sa)
784 case MPATH_PRIN_RKEY_SA:
785 size = sizeof(struct prin_readdescr);
787 memset(ptr, 0, size);
789 case MPATH_PRIN_RRES_SA:
790 size = sizeof(struct prin_resvdescr);
792 memset(ptr, 0, size);
794 case MPATH_PRIN_RCAP_SA:
795 size=sizeof(struct prin_capdescr);
797 memset(ptr, 0, size);
799 case MPATH_PRIN_RFSTAT_SA:
800 size = sizeof(struct print_fulldescr_list) +
801 sizeof(struct prin_fulldescr *)*MPATH_MX_TIDS;
803 memset(ptr, 0, size);
809 int update_map_pr(struct multipath *mpp)
812 struct prin_resp *resp;
813 int i,j, ret, isFound;
817 if (!mpp->reservation_key)
819 /* Nothing to do. Assuming pr mgmt feature is disabled*/
820 condlog(3, "%s: reservation_key not set in multiapth.conf", mpp->alias);
821 return MPATH_PR_SUCCESS;
824 resp = mpath_alloc_prin_response(MPATH_PRIN_RKEY_SA);
827 condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias);
828 return MPATH_PR_OTHER;
830 ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy);
832 if (ret != MPATH_PR_SUCCESS )
834 condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret);
839 if (resp->prin_descriptor.prin_readkeys.additional_length == 0 )
841 condlog(0,"%s: No key found. Device may not be registered. ", mpp->alias);
843 return MPATH_PR_SUCCESS;
847 keyp = mpp->reservation_key;
848 for (j = 0; j < 8; ++j) {
854 condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, prkey);
857 for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ )
859 condlog(2, "%s: PR IN READKEYS[%d] reservation key:", mpp->alias, i);
860 dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , 1);
862 if (!memcmp(mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
864 condlog(2, "%s: reservation key found in pr in readkeys response", mpp->alias);
872 condlog(2, "%s: prflag flag set.", mpp->alias );
876 return MPATH_PR_SUCCESS;