From: Martin Wilck <mwilck@xxxxxxxx> The libmpathpersist library exports symbols that are not part of the public API. Move the respective code into a separate source file. Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> --- libmpathpersist/Makefile | 2 +- libmpathpersist/libmpathpersist.version | 27 +- libmpathpersist/mpath_persist.c | 776 +---------------------- libmpathpersist/mpath_persist_int.c | 779 ++++++++++++++++++++++++ libmpathpersist/mpath_persist_int.h | 17 + libmpathpersist/mpathpr.h | 12 - mpathpersist/main.c | 1 + multipathd/main.c | 1 + 8 files changed, 818 insertions(+), 797 deletions(-) create mode 100644 libmpathpersist/mpath_persist_int.c create mode 100644 libmpathpersist/mpath_persist_int.h diff --git a/libmpathpersist/Makefile b/libmpathpersist/Makefile index 1e6399d..fbc401e 100644 --- a/libmpathpersist/Makefile +++ b/libmpathpersist/Makefile @@ -10,7 +10,7 @@ LDFLAGS += -L$(multipathdir) -L$(mpathcmddir) LIBDEPS += -lmultipath -lmpathcmd -ldevmapper -lpthread -ldl -OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o +OBJS = mpath_persist.o mpath_updatepr.o mpath_pr_ioctl.o mpath_persist_int.o all: $(DEVLIB) man diff --git a/libmpathpersist/libmpathpersist.version b/libmpathpersist/libmpathpersist.version index fa312f6..a8c6aae 100644 --- a/libmpathpersist/libmpathpersist.version +++ b/libmpathpersist/libmpathpersist.version @@ -10,27 +10,28 @@ * * See libmultipath.version for general policy about version numbers. */ -LIBMPATHPERSIST_2.0.0 { +LIBMPATHPERSIST_2.1.0 { global: - - __mpath_persistent_reserve_in; - __mpath_persistent_reserve_out; - dumpHex; - mpath_alloc_prin_response; + /* public API as defined in mpath_persist.h */ + libmpathpersist_exit; + libmpathpersist_init; mpath_lib_exit; mpath_lib_init; mpath_mx_alloc_len; + mpath_persistent_reserve_free_vecs; + __mpath_persistent_reserve_in; mpath_persistent_reserve_in; mpath_persistent_reserve_init_vecs; + __mpath_persistent_reserve_out; mpath_persistent_reserve_out; - mpath_persistent_reserve_free_vecs; +local: *; +}; + +__LIBMPATHPERSIST_INT_1.0.0 { + /* Internal use by multipath-tools */ + dumpHex; + mpath_alloc_prin_response; prin_do_scsi_ioctl; prout_do_scsi_ioctl; update_map_pr; - - /* added in 1.1.0 */ - libmpathpersist_init; - libmpathpersist_exit; - -local: *; }; diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c index 3097c81..6cfcdde 100644 --- a/libmpathpersist/mpath_persist.c +++ b/libmpathpersist/mpath_persist.c @@ -1,39 +1,13 @@ #include <libdevmapper.h> -#include "defaults.h" -#include <sys/stat.h> -#include <sys/types.h> -#include <fcntl.h> -#include "vector.h" -#include "checkers.h" -#include "structs.h" -#include "structs_vec.h" -#include <libudev.h> -#include "prio.h" -#include <unistd.h> -#include "devmapper.h" -#include "debug.h" -#include "config.h" -#include "switchgroup.h" -#include "discovery.h" -#include "configure.h" -#include "dmparser.h" -#include <ctype.h> -#include "propsel.h" #include "util.h" -#include "unaligned.h" +#include "vector.h" +#include "config.h" +#include "debug.h" +#include "devmapper.h" #include "mpath_persist.h" -#include "mpathpr.h" -#include "mpath_pr_ioctl.h" - -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#define __STDC_FORMAT_MACROS 1 +#include "mpath_persist_int.h" extern struct udev *udev; @@ -97,42 +71,6 @@ int libmpathpersist_exit(void) return 0; } -int -mpath_prin_activepath (struct multipath *mpp, int rq_servact, - struct prin_resp * resp, int noisy) -{ - int i,j, ret = MPATH_PR_DMMP_ERROR; - struct pathgroup *pgp = NULL; - struct path *pp = NULL; - - vector_foreach_slot (mpp->pg, pgp, j){ - vector_foreach_slot (pgp->paths, pp, i){ - if (!((pp->state == PATH_UP) || - (pp->state == PATH_GHOST))){ - condlog(2, "%s: %s not available. Skip.", - mpp->wwid, pp->dev); - condlog(3, "%s: status = %d.", - mpp->wwid, pp->state); - continue; - } - - condlog(3, "%s: sending pr in command to %s ", - mpp->wwid, pp->dev); - ret = mpath_send_prin_activepath(pp->dev, rq_servact, - resp, noisy); - switch(ret) - { - case MPATH_PR_SUCCESS: - case MPATH_PR_SENSE_INVALID_OP: - return ret; - default: - continue; - } - } - } - return ret; -} - static vector curmp; static vector pathvec; @@ -182,83 +120,6 @@ int mpath_persistent_reserve_init_vecs(int verbose) return __mpath_persistent_reserve_init_vecs(&curmp, &pathvec, verbose); } -static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, - struct multipath **pmpp) -{ - int ret = MPATH_PR_DMMP_ERROR; - struct stat info; - int major, minor; - char *alias; - struct multipath *mpp; - - if (fstat(fd, &info) != 0){ - condlog(0, "stat error fd=%d", fd); - return MPATH_PR_FILE_ERROR; - } - if(!S_ISBLK(info.st_mode)){ - condlog(3, "Failed to get major:minor. fd=%d", fd); - return MPATH_PR_FILE_ERROR; - } - - major = major(info.st_rdev); - minor = minor(info.st_rdev); - condlog(4, "Device %d:%d", major, minor); - - /* get alias from major:minor*/ - alias = dm_mapname(major, minor); - if (!alias){ - condlog(0, "%d:%d failed to get device alias.", major, minor); - return MPATH_PR_DMMP_ERROR; - } - - condlog(3, "alias = %s", alias); - - if (dm_map_present(alias) && dm_is_mpath(alias) != 1){ - condlog(3, "%s: not a multipath device.", alias); - goto out; - } - - /* get info of all paths from the dm device */ - if (get_mpvec(curmp, pathvec, alias)){ - condlog(0, "%s: failed to get device info.", alias); - goto out; - } - - mpp = find_mp_by_alias(curmp, alias); - - if (!mpp) { - condlog(0, "%s: devmap not registered.", alias); - goto out; - } - - ret = MPATH_PR_SUCCESS; - if (pmpp) - *pmpp = mpp; - if (palias) { - *palias = alias; - alias = NULL; - } -out: - free(alias); - return ret; -} - -static int do_mpath_persistent_reserve_in (vector curmp, vector pathvec, - int fd, int rq_servact, struct prin_resp *resp, int noisy) -{ - struct multipath *mpp; - int ret; - - ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - - ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy); - - return ret; -} - - int __mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp, int noisy) { @@ -266,86 +127,6 @@ int __mpath_persistent_reserve_in (int fd, int rq_servact, resp, noisy); } -static 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) -{ - struct multipath *mpp; - char *alias; - int ret; - uint64_t prkey; - struct config *conf; - - ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); - if (ret != MPATH_PR_SUCCESS) - return ret; - - conf = get_multipath_config(); - select_reservation_key(conf, mpp); - select_all_tg_pt(conf, mpp); - put_multipath_config(conf); - - memcpy(&prkey, paramp->sa_key, 8); - if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && - (rq_servact == MPATH_PROUT_REG_IGN_SA || - (rq_servact == MPATH_PROUT_REG_SA && - (!get_be64(mpp->reservation_key) || - memcmp(paramp->key, &mpp->reservation_key, 8) == 0)))) { - memcpy(&mpp->reservation_key, paramp->sa_key, 8); - if (update_prkey_flags(alias, get_be64(mpp->reservation_key), - paramp->sa_flags)) { - condlog(0, "%s: failed to set prkey for multipathd.", - alias); - ret = MPATH_PR_DMMP_ERROR; - goto out1; - } - } - - if (memcmp(paramp->key, &mpp->reservation_key, 8) && - memcmp(paramp->sa_key, &mpp->reservation_key, 8) && - (prkey || rq_servact != MPATH_PROUT_REG_IGN_SA)) { - condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); - ret = MPATH_PR_SYNTAX_ERROR; - goto out1; - } - - switch(rq_servact) - { - case MPATH_PROUT_REG_SA: - case MPATH_PROUT_REG_IGN_SA: - ret= mpath_prout_reg(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); - break; - case MPATH_PROUT_RES_SA : - case MPATH_PROUT_PREE_SA : - case MPATH_PROUT_PREE_AB_SA : - case MPATH_PROUT_CLEAR_SA: - ret = mpath_prout_common(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); - break; - case MPATH_PROUT_REL_SA: - ret = mpath_prout_rel(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); - break; - default: - ret = MPATH_PR_OTHER; - goto out1; - } - - if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_REG_SA) || - (rq_servact == MPATH_PROUT_REG_IGN_SA))) - { - if (prkey == 0) { - update_prflag(alias, 0); - update_prkey(alias, 0); - } else - update_prflag(alias, 1); - } else if ((ret == MPATH_PR_SUCCESS) && (rq_servact == MPATH_PROUT_CLEAR_SA)) { - update_prflag(alias, 0); - update_prkey(alias, 0); - } -out1: - free(alias); - return ret; -} - int __mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy) @@ -384,550 +165,3 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, __mpath_persistent_reserve_free_vecs(curmp, pathvec); return ret; } - -int -get_mpvec (vector curmp, vector pathvec, char * refwwid) -{ - int i; - struct multipath *mpp; - - vector_foreach_slot (curmp, mpp, i){ - /* - * discard out of scope maps - */ - if (!mpp->alias) { - condlog(0, "%s: map with empty alias!", __func__); - continue; - } - - if (mpp->pg != NULL) - /* Already seen this one */ - continue; - - if (refwwid && strncmp (mpp->alias, refwwid, WWID_SIZE - 1)) - continue; - - if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || - update_mpp_paths(mpp, pathvec)) { - condlog(1, "error parsing map %s", mpp->wwid); - remove_map(mpp, pathvec, curmp); - i--; - } else - extract_hwe_from_path(mpp); - } - return MPATH_PR_SUCCESS ; -} - -int mpath_send_prin_activepath (char * dev, int rq_servact, - struct prin_resp * resp, int noisy) -{ - - int rc; - - rc = prin_do_scsi_ioctl(dev, rq_servact, resp, noisy); - - return (rc); -} - -int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy) -{ - - int i, j, k; - struct pathgroup *pgp = NULL; - struct path *pp = NULL; - int rollback = 0; - int active_pathcount=0; - int rc; - int count=0; - int status = MPATH_PR_SUCCESS; - int all_tg_pt; - uint64_t sa_key = 0; - - if (!mpp) - return MPATH_PR_DMMP_ERROR; - - all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON || - paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK); - active_pathcount = count_active_paths(mpp); - - if (active_pathcount == 0) { - condlog (0, "%s: no path available", mpp->wwid); - return MPATH_PR_DMMP_ERROR; - } - - struct threadinfo thread[active_pathcount]; - int hosts[active_pathcount]; - - memset(thread, 0, sizeof(thread)); - - /* init thread parameter */ - for (i =0; i< active_pathcount; i++){ - hosts[i] = -1; - thread[i].param.rq_servact = rq_servact; - thread[i].param.rq_scope = rq_scope; - thread[i].param.rq_type = rq_type; - thread[i].param.paramp = paramp; - thread[i].param.noisy = noisy; - thread[i].param.status = MPATH_PR_SKIP; - - condlog (3, "THREAD ID [%d] INFO]", i); - condlog (3, "rq_servact=%d ", thread[i].param.rq_servact); - condlog (3, "rq_scope=%d ", thread[i].param.rq_scope); - condlog (3, "rq_type=%d ", thread[i].param.rq_type); - condlog (3, "rkey="); - condlog (3, "paramp->sa_flags =%02x ", - thread[i].param.paramp->sa_flags); - condlog (3, "noisy=%d ", thread[i].param.noisy); - condlog (3, "status=%d ", thread[i].param.status); - } - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - vector_foreach_slot (mpp->pg, pgp, j){ - vector_foreach_slot (pgp->paths, pp, i){ - if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ - condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev); - continue; - } - if (all_tg_pt && pp->sg_id.host_no != -1) { - for (k = 0; k < count; k++) { - if (pp->sg_id.host_no == hosts[k]) { - condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no); - break; - } - } - if (k < count) - continue; - } - strlcpy(thread[count].param.dev, pp->dev, - FILE_NAME_SIZE); - - if (count && (thread[count].param.paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)){ - /* - * Clearing SPEC_I_PT as transportids are already registered by now. - */ - thread[count].param.paramp->sa_flags &= (~MPATH_F_SPEC_I_PT_MASK); - } - - condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); - - rc = pthread_create(&thread[count].id, &attr, mpath_prout_pthread_fn, (void *)(&thread[count].param)); - if (rc){ - condlog (0, "%s: failed to create thread %d", mpp->wwid, rc); - thread[count].param.status = MPATH_PR_THREAD_ERROR; - } - else - hosts[count] = pp->sg_id.host_no; - count = count + 1; - } - } - for( i=0; i < count ; i++){ - if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join(thread[i].id, NULL); - if (rc){ - condlog (0, "%s: Thread[%d] failed to join thread %d", mpp->wwid, i, rc); - } - } - if (!rollback && (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)){ - rollback = 1; - sa_key = get_unaligned_be64(¶mp->sa_key[0]); - status = MPATH_PR_RESERV_CONFLICT ; - } - if (!rollback && (status == MPATH_PR_SUCCESS)){ - status = thread[i].param.status; - } - } - if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){ - condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid); - memcpy(¶mp->key, ¶mp->sa_key, 8); - memset(¶mp->sa_key, 0, 8); - for( i=0 ; i < count ; i++){ - if(thread[i].param.status == MPATH_PR_SUCCESS) { - rc = pthread_create(&thread[i].id, &attr, mpath_prout_pthread_fn, - (void *)(&thread[i].param)); - if (rc){ - condlog (0, "%s: failed to create thread for rollback. %d", mpp->wwid, rc); - thread[i].param.status = MPATH_PR_THREAD_ERROR; - } - } else - thread[i].param.status = MPATH_PR_SKIP; - } - for(i=0; i < count ; i++){ - if (thread[i].param.status != MPATH_PR_SKIP && - thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join(thread[i].id, NULL); - if (rc){ - condlog (3, "%s: failed to join thread while rolling back %d", - mpp->wwid, i); - } - } - } - } - - pthread_attr_destroy(&attr); - return (status); -} - -void * mpath_prout_pthread_fn(void *p) -{ - int ret; - struct prout_param * param = (struct prout_param *)p; - - ret = prout_do_scsi_ioctl( param->dev,param->rq_servact, param->rq_scope, - param->rq_type, param->paramp, param->noisy); - param->status = ret; - pthread_exit(NULL); -} - -int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor* paramp, int noisy) -{ - int i,j, ret; - struct pathgroup *pgp = NULL; - struct path *pp = NULL; - - vector_foreach_slot (mpp->pg, pgp, j){ - vector_foreach_slot (pgp->paths, pp, i){ - if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ - condlog (1, "%s: %s path not up. Skip", - mpp->wwid, pp->dev); - continue; - } - - condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); - ret = send_prout_activepath(pp->dev, rq_servact, - rq_scope, rq_type, - paramp, noisy); - return ret ; - } - } - condlog (0, "%s: no path available", mpp->wwid); - return MPATH_PR_DMMP_ERROR; -} - -int send_prout_activepath(char * dev, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy) -{ - struct prout_param param; - param.rq_servact = rq_servact; - param.rq_scope = rq_scope; - param.rq_type = rq_type; - param.paramp = paramp; - param.noisy = noisy; - param.status = -1; - - pthread_t thread; - pthread_attr_t attr; - int rc; - - memset(&thread, 0, sizeof(thread)); - strlcpy(param.dev, dev, FILE_NAME_SIZE); - /* Initialize and set thread joinable attribute */ - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - rc = pthread_create(&thread, &attr, mpath_prout_pthread_fn, (void *)(¶m)); - if (rc){ - condlog (3, "%s: failed to create thread %d", dev, rc); - return MPATH_PR_THREAD_ERROR; - } - /* Free attribute and wait for the other threads */ - pthread_attr_destroy(&attr); - rc = pthread_join(thread, NULL); - - return (param.status); -} - -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; - pthread_attr_t attr; - int rc, found = 0; - int count = 0; - int status = MPATH_PR_SUCCESS; - struct prin_resp resp; - struct prout_param_descriptor *pamp; - struct prin_resp *pr_buff; - int length; - struct transportid *pptr; - - if (!mpp) - return MPATH_PR_DMMP_ERROR; - - active_pathcount = count_active_paths(mpp); - - if (active_pathcount == 0) { - condlog (0, "%s: no path available", mpp->wwid); - return MPATH_PR_DMMP_ERROR; - } - - struct threadinfo thread[active_pathcount]; - memset(thread, 0, sizeof(thread)); - for (i = 0; i < active_pathcount; i++){ - thread[i].param.rq_servact = rq_servact; - thread[i].param.rq_scope = rq_scope; - thread[i].param.rq_type = rq_type; - thread[i].param.paramp = paramp; - thread[i].param.noisy = noisy; - thread[i].param.status = MPATH_PR_SKIP; - - condlog (3, " path count = %d", i); - condlog (3, "rq_servact=%d ", thread[i].param.rq_servact); - condlog (3, "rq_scope=%d ", thread[i].param.rq_scope); - condlog (3, "rq_type=%d ", thread[i].param.rq_type); - condlog (3, "noisy=%d ", thread[i].param.noisy); - condlog (3, "status=%d ", thread[i].param.status); - } - - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); - - vector_foreach_slot (mpp->pg, pgp, j){ - vector_foreach_slot (pgp->paths, pp, i){ - if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ - condlog (1, "%s: %s path not up.", mpp->wwid, pp->dev); - continue; - } - - strlcpy(thread[count].param.dev, pp->dev, - FILE_NAME_SIZE); - condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); - rc = pthread_create (&thread[count].id, &attr, mpath_prout_pthread_fn, - (void *) (&thread[count].param)); - if (rc) { - condlog (0, "%s: failed to create thread. %d", mpp->wwid, rc); - thread[count].param.status = MPATH_PR_THREAD_ERROR; - } - count = count + 1; - } - } - pthread_attr_destroy (&attr); - for (i = 0; i < count; i++){ - if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { - rc = pthread_join (thread[i].id, NULL); - if (rc){ - condlog (1, "%s: failed to join thread. %d", mpp->wwid, rc); - } - } - } - - for (i = 0; i < count; i++){ - /* check thread status here and return the status */ - - if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT) - status = MPATH_PR_RESERV_CONFLICT; - else if (status == MPATH_PR_SUCCESS - && thread[i].param.status != MPATH_PR_RESERV_CONFLICT) - status = thread[i].param.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; - } - condlog (2, "%s: Path holding reservation is not avialable.", mpp->wwid); - - pr_buff = mpath_alloc_prin_response(MPATH_PRIN_RFSTAT_SA); - if (!pr_buff){ - condlog (0, "%s: failed to alloc pr in response buffer.", mpp->wwid); - return MPATH_PR_OTHER; - } - - status = mpath_prin_activepath (mpp, MPATH_PRIN_RFSTAT_SA, pr_buff, noisy); - - if (status != MPATH_PR_SUCCESS){ - condlog (0, "%s: pr in read full status command failed.", mpp->wwid); - goto out; - } - - num = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; - if (0 == num){ - goto out; - } - length = sizeof (struct prout_param_descriptor) + (sizeof (struct transportid *)); - - pamp = (struct prout_param_descriptor *)malloc (length); - if (!pamp){ - condlog (0, "%s: failed to alloc pr out parameter.", mpp->wwid); - goto out1; - } - - memset(pamp, 0, length); - - pamp->trnptid_list[0] = (struct transportid *) malloc (sizeof (struct transportid)); - if (!pamp->trnptid_list[0]){ - condlog (0, "%s: failed to alloc pr out transportid.", mpp->wwid); - goto out1; - } - - if (get_be64(mpp->reservation_key)){ - memcpy (pamp->key, &mpp->reservation_key, 8); - condlog (3, "%s: reservation key set.", mpp->wwid); - } - - status = mpath_prout_common (mpp, MPATH_PROUT_CLEAR_SA, - rq_scope, rq_type, pamp, noisy); - - if (status) { - condlog(0, "%s: failed to send CLEAR_SA", mpp->wwid); - goto out1; - } - - pamp->num_transportid = 1; - pptr=pamp->trnptid_list[0]; - - for (i = 0; i < num; i++){ - if (get_be64(mpp->reservation_key) && - memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, - &mpp->reservation_key, 8)){ - /*register with tarnsport id*/ - memset(pamp, 0, length); - pamp->trnptid_list[0] = pptr; - memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); - memcpy (pamp->sa_key, - pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8); - pamp->sa_flags = MPATH_F_SPEC_I_PT_MASK; - pamp->num_transportid = 1; - - memcpy (pamp->trnptid_list[0], - &pr_buff->prin_descriptor.prin_readfd.descriptors[i]->trnptid, - sizeof (struct transportid)); - status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type, - pamp, noisy); - - pamp->sa_flags = 0; - memcpy (pamp->key, pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8); - memset (pamp->sa_key, 0, 8); - pamp->num_transportid = 0; - status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type, - pamp, noisy); - } - else - { - if (get_be64(mpp->reservation_key)) - found = 1; - } - - - } - - if (found){ - memset (pamp, 0, length); - memcpy (pamp->sa_key, &mpp->reservation_key, 8); - memset (pamp->key, 0, 8); - status = mpath_prout_reg(mpp, MPATH_PROUT_REG_SA, rq_scope, rq_type, pamp, noisy); - } - - - free(pptr); -out1: - free (pamp); -out: - free (pr_buff); - return (status); -} - -void * mpath_alloc_prin_response(int prin_sa) -{ - void * ptr = NULL; - int size=0; - switch (prin_sa) - { - case MPATH_PRIN_RKEY_SA: - size = sizeof(struct prin_readdescr); - break; - case MPATH_PRIN_RRES_SA: - size = sizeof(struct prin_resvdescr); - break; - case MPATH_PRIN_RCAP_SA: - size=sizeof(struct prin_capdescr); - break; - case MPATH_PRIN_RFSTAT_SA: - size = sizeof(struct print_fulldescr_list) + - sizeof(struct prin_fulldescr *)*MPATH_MX_TIDS; - break; - } - if (size > 0) - { - ptr = calloc(size, 1); - } - return ptr; -} - -int update_map_pr(struct multipath *mpp) -{ - int noisy=0; - struct prin_resp *resp; - unsigned int i; - int ret, isFound; - - if (!get_be64(mpp->reservation_key)) - { - /* Nothing to do. Assuming pr mgmt feature is disabled*/ - condlog(4, "%s: reservation_key not set in multipath.conf", - mpp->alias); - return MPATH_PR_SUCCESS; - } - - resp = mpath_alloc_prin_response(MPATH_PRIN_RKEY_SA); - if (!resp) - { - condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); - return MPATH_PR_OTHER; - } - ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); - - if (ret != MPATH_PR_SUCCESS ) - { - condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); - free(resp); - return ret; - } - - if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) - { - condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); - free(resp); - return MPATH_PR_SUCCESS; - } - - condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, - get_be64(mpp->reservation_key)); - - isFound =0; - for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ ) - { - condlog(2, "%s: PR IN READKEYS[%d] reservation key:", mpp->alias, i); - dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , 1); - - if (!memcmp(&mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8)) - { - condlog(2, "%s: reservation key found in pr in readkeys response", mpp->alias); - isFound =1; - } - } - - if (isFound) - { - mpp->prflag = 1; - condlog(2, "%s: prflag flag set.", mpp->alias ); - } - - free(resp); - return MPATH_PR_SUCCESS; -} diff --git a/libmpathpersist/mpath_persist_int.c b/libmpathpersist/mpath_persist_int.c new file mode 100644 index 0000000..7f6ac04 --- /dev/null +++ b/libmpathpersist/mpath_persist_int.c @@ -0,0 +1,779 @@ +#include <libdevmapper.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <libudev.h> +#include <unistd.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> + +#include "vector.h" +#include "defaults.h" +#include "checkers.h" +#include "structs.h" +#include "structs_vec.h" +#include "prio.h" +#include "devmapper.h" +#include "debug.h" +#include "config.h" +#include "switchgroup.h" +#include "discovery.h" +#include "configure.h" +#include "dmparser.h" +#include "propsel.h" +#include "util.h" +#include "unaligned.h" + +#include "mpath_persist.h" +#include "mpath_persist_int.h" +#include "mpathpr.h" +#include "mpath_pr_ioctl.h" + + +#define __STDC_FORMAT_MACROS 1 + +static int mpath_send_prin_activepath (char * dev, int rq_servact, + struct prin_resp * resp, int noisy) +{ + + int rc; + + rc = prin_do_scsi_ioctl(dev, rq_servact, resp, noisy); + + return (rc); +} + +static int mpath_prin_activepath (struct multipath *mpp, int rq_servact, + struct prin_resp * resp, int noisy) +{ + int i,j, ret = MPATH_PR_DMMP_ERROR; + struct pathgroup *pgp = NULL; + struct path *pp = NULL; + + vector_foreach_slot (mpp->pg, pgp, j){ + vector_foreach_slot (pgp->paths, pp, i){ + if (!((pp->state == PATH_UP) || + (pp->state == PATH_GHOST))){ + condlog(2, "%s: %s not available. Skip.", + mpp->wwid, pp->dev); + condlog(3, "%s: status = %d.", + mpp->wwid, pp->state); + continue; + } + + condlog(3, "%s: sending pr in command to %s ", + mpp->wwid, pp->dev); + ret = mpath_send_prin_activepath(pp->dev, rq_servact, + resp, noisy); + switch(ret) + { + case MPATH_PR_SUCCESS: + case MPATH_PR_SENSE_INVALID_OP: + return ret; + default: + continue; + } + } + } + return ret; +} + +void *mpath_alloc_prin_response(int prin_sa) +{ + void * ptr = NULL; + int size=0; + switch (prin_sa) + { + case MPATH_PRIN_RKEY_SA: + size = sizeof(struct prin_readdescr); + break; + case MPATH_PRIN_RRES_SA: + size = sizeof(struct prin_resvdescr); + break; + case MPATH_PRIN_RCAP_SA: + size=sizeof(struct prin_capdescr); + break; + case MPATH_PRIN_RFSTAT_SA: + size = sizeof(struct print_fulldescr_list) + + sizeof(struct prin_fulldescr *)*MPATH_MX_TIDS; + break; + } + if (size > 0) + { + ptr = calloc(size, 1); + } + return ptr; +} + +static int get_mpvec(vector curmp, vector pathvec, char *refwwid) +{ + int i; + struct multipath *mpp; + + vector_foreach_slot (curmp, mpp, i){ + /* + * discard out of scope maps + */ + if (!mpp->alias) { + condlog(0, "%s: map with empty alias!", __func__); + continue; + } + + if (mpp->pg != NULL) + /* Already seen this one */ + continue; + + if (refwwid && strncmp (mpp->alias, refwwid, WWID_SIZE - 1)) + continue; + + if (update_multipath_table(mpp, pathvec, DI_CHECKER) != DMP_OK || + update_mpp_paths(mpp, pathvec)) { + condlog(1, "error parsing map %s", mpp->wwid); + remove_map(mpp, pathvec, curmp); + i--; + } else + extract_hwe_from_path(mpp); + } + return MPATH_PR_SUCCESS ; +} + +static int mpath_get_map(vector curmp, vector pathvec, int fd, char **palias, + struct multipath **pmpp) +{ + int ret = MPATH_PR_DMMP_ERROR; + struct stat info; + int major, minor; + char *alias; + struct multipath *mpp; + + if (fstat(fd, &info) != 0){ + condlog(0, "stat error fd=%d", fd); + return MPATH_PR_FILE_ERROR; + } + if(!S_ISBLK(info.st_mode)){ + condlog(3, "Failed to get major:minor. fd=%d", fd); + return MPATH_PR_FILE_ERROR; + } + + major = major(info.st_rdev); + minor = minor(info.st_rdev); + condlog(4, "Device %d:%d", major, minor); + + /* get alias from major:minor*/ + alias = dm_mapname(major, minor); + if (!alias){ + condlog(0, "%d:%d failed to get device alias.", major, minor); + return MPATH_PR_DMMP_ERROR; + } + + condlog(3, "alias = %s", alias); + + if (dm_map_present(alias) && dm_is_mpath(alias) != 1){ + condlog(3, "%s: not a multipath device.", alias); + goto out; + } + + /* get info of all paths from the dm device */ + if (get_mpvec(curmp, pathvec, alias)){ + condlog(0, "%s: failed to get device info.", alias); + goto out; + } + + mpp = find_mp_by_alias(curmp, alias); + + if (!mpp) { + condlog(0, "%s: devmap not registered.", alias); + goto out; + } + + ret = MPATH_PR_SUCCESS; + if (pmpp) + *pmpp = mpp; + if (palias) { + *palias = alias; + alias = NULL; + } +out: + free(alias); + return ret; +} + +int do_mpath_persistent_reserve_in(vector curmp, vector pathvec, + int fd, int rq_servact, + struct prin_resp *resp, int noisy) +{ + struct multipath *mpp; + int ret; + + ret = mpath_get_map(curmp, pathvec, fd, NULL, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + + ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy); + + return ret; +} + +static void *mpath_prout_pthread_fn(void *p) +{ + int ret; + struct prout_param * param = (struct prout_param *)p; + + ret = prout_do_scsi_ioctl( param->dev,param->rq_servact, param->rq_scope, + param->rq_type, param->paramp, param->noisy); + param->status = ret; + pthread_exit(NULL); +} + +static int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, + unsigned int rq_type, + struct prout_param_descriptor * paramp, int noisy) +{ + + int i, j, k; + struct pathgroup *pgp = NULL; + struct path *pp = NULL; + int rollback = 0; + int active_pathcount=0; + int rc; + int count=0; + int status = MPATH_PR_SUCCESS; + int all_tg_pt; + uint64_t sa_key = 0; + + if (!mpp) + return MPATH_PR_DMMP_ERROR; + + all_tg_pt = (mpp->all_tg_pt == ALL_TG_PT_ON || + paramp->sa_flags & MPATH_F_ALL_TG_PT_MASK); + active_pathcount = count_active_paths(mpp); + + if (active_pathcount == 0) { + condlog (0, "%s: no path available", mpp->wwid); + return MPATH_PR_DMMP_ERROR; + } + + struct threadinfo thread[active_pathcount]; + int hosts[active_pathcount]; + + memset(thread, 0, sizeof(thread)); + + /* init thread parameter */ + for (i =0; i< active_pathcount; i++){ + hosts[i] = -1; + thread[i].param.rq_servact = rq_servact; + thread[i].param.rq_scope = rq_scope; + thread[i].param.rq_type = rq_type; + thread[i].param.paramp = paramp; + thread[i].param.noisy = noisy; + thread[i].param.status = MPATH_PR_SKIP; + + condlog (3, "THREAD ID [%d] INFO]", i); + condlog (3, "rq_servact=%d ", thread[i].param.rq_servact); + condlog (3, "rq_scope=%d ", thread[i].param.rq_scope); + condlog (3, "rq_type=%d ", thread[i].param.rq_type); + condlog (3, "rkey="); + condlog (3, "paramp->sa_flags =%02x ", + thread[i].param.paramp->sa_flags); + condlog (3, "noisy=%d ", thread[i].param.noisy); + condlog (3, "status=%d ", thread[i].param.status); + } + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + vector_foreach_slot (mpp->pg, pgp, j){ + vector_foreach_slot (pgp->paths, pp, i){ + if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ + condlog (1, "%s: %s path not up. Skip.", mpp->wwid, pp->dev); + continue; + } + if (all_tg_pt && pp->sg_id.host_no != -1) { + for (k = 0; k < count; k++) { + if (pp->sg_id.host_no == hosts[k]) { + condlog(3, "%s: %s host %d matches skip.", pp->wwid, pp->dev, pp->sg_id.host_no); + break; + } + } + if (k < count) + continue; + } + strlcpy(thread[count].param.dev, pp->dev, + FILE_NAME_SIZE); + + if (count && (thread[count].param.paramp->sa_flags & MPATH_F_SPEC_I_PT_MASK)){ + /* + * Clearing SPEC_I_PT as transportids are already registered by now. + */ + thread[count].param.paramp->sa_flags &= (~MPATH_F_SPEC_I_PT_MASK); + } + + condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); + + rc = pthread_create(&thread[count].id, &attr, mpath_prout_pthread_fn, (void *)(&thread[count].param)); + if (rc){ + condlog (0, "%s: failed to create thread %d", mpp->wwid, rc); + thread[count].param.status = MPATH_PR_THREAD_ERROR; + } + else + hosts[count] = pp->sg_id.host_no; + count = count + 1; + } + } + for( i=0; i < count ; i++){ + if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { + rc = pthread_join(thread[i].id, NULL); + if (rc){ + condlog (0, "%s: Thread[%d] failed to join thread %d", mpp->wwid, i, rc); + } + } + if (!rollback && (thread[i].param.status == MPATH_PR_RESERV_CONFLICT)){ + rollback = 1; + sa_key = get_unaligned_be64(¶mp->sa_key[0]); + status = MPATH_PR_RESERV_CONFLICT ; + } + if (!rollback && (status == MPATH_PR_SUCCESS)){ + status = thread[i].param.status; + } + } + if (rollback && ((rq_servact == MPATH_PROUT_REG_SA) && sa_key != 0 )){ + condlog (3, "%s: ERROR: initiating pr out rollback", mpp->wwid); + memcpy(¶mp->key, ¶mp->sa_key, 8); + memset(¶mp->sa_key, 0, 8); + for( i=0 ; i < count ; i++){ + if(thread[i].param.status == MPATH_PR_SUCCESS) { + rc = pthread_create(&thread[i].id, &attr, mpath_prout_pthread_fn, + (void *)(&thread[i].param)); + if (rc){ + condlog (0, "%s: failed to create thread for rollback. %d", mpp->wwid, rc); + thread[i].param.status = MPATH_PR_THREAD_ERROR; + } + } else + thread[i].param.status = MPATH_PR_SKIP; + } + for(i=0; i < count ; i++){ + if (thread[i].param.status != MPATH_PR_SKIP && + thread[i].param.status != MPATH_PR_THREAD_ERROR) { + rc = pthread_join(thread[i].id, NULL); + if (rc){ + condlog (3, "%s: failed to join thread while rolling back %d", + mpp->wwid, i); + } + } + } + } + + pthread_attr_destroy(&attr); + return (status); +} + +static int send_prout_activepath(char *dev, int rq_servact, int rq_scope, + unsigned int rq_type, + struct prout_param_descriptor * paramp, int noisy) +{ + struct prout_param param; + param.rq_servact = rq_servact; + param.rq_scope = rq_scope; + param.rq_type = rq_type; + param.paramp = paramp; + param.noisy = noisy; + param.status = -1; + + pthread_t thread; + pthread_attr_t attr; + int rc; + + memset(&thread, 0, sizeof(thread)); + strlcpy(param.dev, dev, FILE_NAME_SIZE); + /* Initialize and set thread joinable attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + rc = pthread_create(&thread, &attr, mpath_prout_pthread_fn, (void *)(¶m)); + if (rc){ + condlog (3, "%s: failed to create thread %d", dev, rc); + return MPATH_PR_THREAD_ERROR; + } + /* Free attribute and wait for the other threads */ + pthread_attr_destroy(&attr); + rc = pthread_join(thread, NULL); + + return (param.status); +} + +static int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, + unsigned int rq_type, + struct prout_param_descriptor* paramp, int noisy) +{ + int i,j, ret; + struct pathgroup *pgp = NULL; + struct path *pp = NULL; + + vector_foreach_slot (mpp->pg, pgp, j){ + vector_foreach_slot (pgp->paths, pp, i){ + if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ + condlog (1, "%s: %s path not up. Skip", + mpp->wwid, pp->dev); + continue; + } + + condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); + ret = send_prout_activepath(pp->dev, rq_servact, + rq_scope, rq_type, + paramp, noisy); + return ret ; + } + } + condlog (0, "%s: no path available", mpp->wwid); + return MPATH_PR_DMMP_ERROR; +} + +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; + pthread_attr_t attr; + int rc, found = 0; + int count = 0; + int status = MPATH_PR_SUCCESS; + struct prin_resp resp; + struct prout_param_descriptor *pamp; + struct prin_resp *pr_buff; + int length; + struct transportid *pptr; + + if (!mpp) + return MPATH_PR_DMMP_ERROR; + + active_pathcount = count_active_paths(mpp); + + if (active_pathcount == 0) { + condlog (0, "%s: no path available", mpp->wwid); + return MPATH_PR_DMMP_ERROR; + } + + struct threadinfo thread[active_pathcount]; + memset(thread, 0, sizeof(thread)); + for (i = 0; i < active_pathcount; i++){ + thread[i].param.rq_servact = rq_servact; + thread[i].param.rq_scope = rq_scope; + thread[i].param.rq_type = rq_type; + thread[i].param.paramp = paramp; + thread[i].param.noisy = noisy; + thread[i].param.status = MPATH_PR_SKIP; + + condlog (3, " path count = %d", i); + condlog (3, "rq_servact=%d ", thread[i].param.rq_servact); + condlog (3, "rq_scope=%d ", thread[i].param.rq_scope); + condlog (3, "rq_type=%d ", thread[i].param.rq_type); + condlog (3, "noisy=%d ", thread[i].param.noisy); + condlog (3, "status=%d ", thread[i].param.status); + } + + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); + + vector_foreach_slot (mpp->pg, pgp, j){ + vector_foreach_slot (pgp->paths, pp, i){ + if (!((pp->state == PATH_UP) || (pp->state == PATH_GHOST))){ + condlog (1, "%s: %s path not up.", mpp->wwid, pp->dev); + continue; + } + + strlcpy(thread[count].param.dev, pp->dev, + FILE_NAME_SIZE); + condlog (3, "%s: sending pr out command to %s", mpp->wwid, pp->dev); + rc = pthread_create (&thread[count].id, &attr, mpath_prout_pthread_fn, + (void *) (&thread[count].param)); + if (rc) { + condlog (0, "%s: failed to create thread. %d", mpp->wwid, rc); + thread[count].param.status = MPATH_PR_THREAD_ERROR; + } + count = count + 1; + } + } + pthread_attr_destroy (&attr); + for (i = 0; i < count; i++){ + if (thread[i].param.status != MPATH_PR_THREAD_ERROR) { + rc = pthread_join (thread[i].id, NULL); + if (rc){ + condlog (1, "%s: failed to join thread. %d", mpp->wwid, rc); + } + } + } + + for (i = 0; i < count; i++){ + /* check thread status here and return the status */ + + if (thread[i].param.status == MPATH_PR_RESERV_CONFLICT) + status = MPATH_PR_RESERV_CONFLICT; + else if (status == MPATH_PR_SUCCESS + && thread[i].param.status != MPATH_PR_RESERV_CONFLICT) + status = thread[i].param.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; + } + condlog (2, "%s: Path holding reservation is not avialable.", mpp->wwid); + + pr_buff = mpath_alloc_prin_response(MPATH_PRIN_RFSTAT_SA); + if (!pr_buff){ + condlog (0, "%s: failed to alloc pr in response buffer.", mpp->wwid); + return MPATH_PR_OTHER; + } + + status = mpath_prin_activepath (mpp, MPATH_PRIN_RFSTAT_SA, pr_buff, noisy); + + if (status != MPATH_PR_SUCCESS){ + condlog (0, "%s: pr in read full status command failed.", mpp->wwid); + goto out; + } + + num = pr_buff->prin_descriptor.prin_readfd.number_of_descriptor; + if (0 == num){ + goto out; + } + length = sizeof (struct prout_param_descriptor) + (sizeof (struct transportid *)); + + pamp = (struct prout_param_descriptor *)malloc (length); + if (!pamp){ + condlog (0, "%s: failed to alloc pr out parameter.", mpp->wwid); + goto out1; + } + + memset(pamp, 0, length); + + pamp->trnptid_list[0] = (struct transportid *) malloc (sizeof (struct transportid)); + if (!pamp->trnptid_list[0]){ + condlog (0, "%s: failed to alloc pr out transportid.", mpp->wwid); + goto out1; + } + + if (get_be64(mpp->reservation_key)){ + memcpy (pamp->key, &mpp->reservation_key, 8); + condlog (3, "%s: reservation key set.", mpp->wwid); + } + + status = mpath_prout_common (mpp, MPATH_PROUT_CLEAR_SA, + rq_scope, rq_type, pamp, noisy); + + if (status) { + condlog(0, "%s: failed to send CLEAR_SA", mpp->wwid); + goto out1; + } + + pamp->num_transportid = 1; + pptr=pamp->trnptid_list[0]; + + for (i = 0; i < num; i++){ + if (get_be64(mpp->reservation_key) && + memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, + &mpp->reservation_key, 8)){ + /*register with tarnsport id*/ + memset(pamp, 0, length); + pamp->trnptid_list[0] = pptr; + memset (pamp->trnptid_list[0], 0, sizeof (struct transportid)); + memcpy (pamp->sa_key, + pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8); + pamp->sa_flags = MPATH_F_SPEC_I_PT_MASK; + pamp->num_transportid = 1; + + memcpy (pamp->trnptid_list[0], + &pr_buff->prin_descriptor.prin_readfd.descriptors[i]->trnptid, + sizeof (struct transportid)); + status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type, + pamp, noisy); + + pamp->sa_flags = 0; + memcpy (pamp->key, pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key, 8); + memset (pamp->sa_key, 0, 8); + pamp->num_transportid = 0; + status = mpath_prout_common (mpp, MPATH_PROUT_REG_SA, 0, rq_type, + pamp, noisy); + } + else + { + if (get_be64(mpp->reservation_key)) + found = 1; + } + + + } + + if (found){ + memset (pamp, 0, length); + memcpy (pamp->sa_key, &mpp->reservation_key, 8); + memset (pamp->key, 0, 8); + status = mpath_prout_reg(mpp, MPATH_PROUT_REG_SA, rq_scope, rq_type, pamp, noisy); + } + + + free(pptr); +out1: + free (pamp); +out: + free (pr_buff); + return (status); +} + +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) +{ + struct multipath *mpp; + char *alias; + int ret; + uint64_t prkey; + struct config *conf; + + ret = mpath_get_map(curmp, pathvec, fd, &alias, &mpp); + if (ret != MPATH_PR_SUCCESS) + return ret; + + conf = get_multipath_config(); + select_reservation_key(conf, mpp); + select_all_tg_pt(conf, mpp); + put_multipath_config(conf); + + memcpy(&prkey, paramp->sa_key, 8); + if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey && + (rq_servact == MPATH_PROUT_REG_IGN_SA || + (rq_servact == MPATH_PROUT_REG_SA && + (!get_be64(mpp->reservation_key) || + memcmp(paramp->key, &mpp->reservation_key, 8) == 0)))) { + memcpy(&mpp->reservation_key, paramp->sa_key, 8); + if (update_prkey_flags(alias, get_be64(mpp->reservation_key), + paramp->sa_flags)) { + condlog(0, "%s: failed to set prkey for multipathd.", + alias); + ret = MPATH_PR_DMMP_ERROR; + goto out1; + } + } + + if (memcmp(paramp->key, &mpp->reservation_key, 8) && + memcmp(paramp->sa_key, &mpp->reservation_key, 8) && + (prkey || rq_servact != MPATH_PROUT_REG_IGN_SA)) { + condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key)); + ret = MPATH_PR_SYNTAX_ERROR; + goto out1; + } + + switch(rq_servact) + { + case MPATH_PROUT_REG_SA: + case MPATH_PROUT_REG_IGN_SA: + ret= mpath_prout_reg(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); + break; + case MPATH_PROUT_RES_SA : + case MPATH_PROUT_PREE_SA : + case MPATH_PROUT_PREE_AB_SA : + case MPATH_PROUT_CLEAR_SA: + ret = mpath_prout_common(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); + break; + case MPATH_PROUT_REL_SA: + ret = mpath_prout_rel(mpp, rq_servact, rq_scope, rq_type, paramp, noisy); + break; + default: + ret = MPATH_PR_OTHER; + goto out1; + } + + if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_REG_SA) || + (rq_servact == MPATH_PROUT_REG_IGN_SA))) + { + if (prkey == 0) { + update_prflag(alias, 0); + update_prkey(alias, 0); + } else + update_prflag(alias, 1); + } else if ((ret == MPATH_PR_SUCCESS) && (rq_servact == MPATH_PROUT_CLEAR_SA)) { + update_prflag(alias, 0); + update_prkey(alias, 0); + } +out1: + free(alias); + return ret; +} + +int update_map_pr(struct multipath *mpp) +{ + int noisy=0; + struct prin_resp *resp; + unsigned int i; + int ret, isFound; + + if (!get_be64(mpp->reservation_key)) + { + /* Nothing to do. Assuming pr mgmt feature is disabled*/ + condlog(4, "%s: reservation_key not set in multipath.conf", + mpp->alias); + return MPATH_PR_SUCCESS; + } + + resp = mpath_alloc_prin_response(MPATH_PRIN_RKEY_SA); + if (!resp) + { + condlog(0,"%s : failed to alloc resp in update_map_pr", mpp->alias); + return MPATH_PR_OTHER; + } + ret = mpath_prin_activepath(mpp, MPATH_PRIN_RKEY_SA, resp, noisy); + + if (ret != MPATH_PR_SUCCESS ) + { + condlog(0,"%s : pr in read keys service action failed Error=%d", mpp->alias, ret); + free(resp); + return ret; + } + + if (resp->prin_descriptor.prin_readkeys.additional_length == 0 ) + { + condlog(3,"%s: No key found. Device may not be registered. ", mpp->alias); + free(resp); + return MPATH_PR_SUCCESS; + } + + condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, + get_be64(mpp->reservation_key)); + + isFound =0; + for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ ) + { + condlog(2, "%s: PR IN READKEYS[%d] reservation key:", mpp->alias, i); + dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , 1); + + if (!memcmp(&mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8)) + { + condlog(2, "%s: reservation key found in pr in readkeys response", mpp->alias); + isFound =1; + } + } + + if (isFound) + { + mpp->prflag = 1; + condlog(2, "%s: prflag flag set.", mpp->alias ); + } + + free(resp); + return MPATH_PR_SUCCESS; +} diff --git a/libmpathpersist/mpath_persist_int.h b/libmpathpersist/mpath_persist_int.h new file mode 100644 index 0000000..58d9c33 --- /dev/null +++ b/libmpathpersist/mpath_persist_int.h @@ -0,0 +1,17 @@ +#ifndef _MPATH_PERSIST_INT_H +#define _MPATH_PERSIST_INT_H + +struct multipath; + +void * mpath_alloc_prin_response(int prin_sa); +int do_mpath_persistent_reserve_in(vector curmp, vector pathvec, + int fd, int rq_servact, + struct prin_resp *resp, int noisy); +void *mpath_alloc_prin_response(int prin_sa); +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); + +#endif /* _MPATH_PERSIST_INT_H */ diff --git a/libmpathpersist/mpathpr.h b/libmpathpersist/mpathpr.h index 5ea8cd6..59411e6 100644 --- a/libmpathpersist/mpathpr.h +++ b/libmpathpersist/mpathpr.h @@ -31,20 +31,8 @@ int prin_do_scsi_ioctl(char * dev, int rq_servact, struct prin_resp * resp, int int prout_do_scsi_ioctl( char * dev, int rq_servact, int rq_scope, unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy); void * _mpath_pr_update (void *arg); -int mpath_send_prin_activepath (char * dev, int rq_servact, struct prin_resp * resp, int noisy); -int get_mpvec (vector curmp, vector pathvec, char * refwwid); -void * mpath_prout_pthread_fn(void *p); void dumpHex(const char* , int len, int no_ascii); -int mpath_prout_reg(struct multipath *mpp,int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy); -int mpath_prout_common(struct multipath *mpp,int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy); -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 send_prout_activepath(char * dev, int rq_servact, int rq_scope, - unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy); - int update_prflag(char *mapname, int set); int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags); #define update_prkey(mapname, prkey) update_prkey_flags(mapname, prkey, 0) diff --git a/mpathpersist/main.c b/mpathpersist/main.c index 14245cc..4bdd55c 100644 --- a/mpathpersist/main.c +++ b/mpathpersist/main.c @@ -10,6 +10,7 @@ #include <getopt.h> #include <libudev.h> #include "mpath_persist.h" +#include "mpath_persist_int.h" #include "main.h" #include "debug.h" #include <pthread.h> diff --git a/multipathd/main.c b/multipathd/main.c index 7a57a79..1db34ac 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -66,6 +66,7 @@ #include "mpath_cmd.h" #include "mpath_persist.h" +#include "mpath_persist_int.h" #include "prioritizers/alua_rtpg.h" -- 2.34.1 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/dm-devel