[dm-devel] [RFC PATCH 5/7] libmpathpersist: factor out initialization and teardown
Martin Wilck
mwilck at suse.com
Fri May 17 22:57:01 UTC 2019
mpath_presistent_reserve_{in,out} share a lot of common code
for initial data structure initialization (discovery) and teardown.
Factor this code out into mpath_persistent_reserve_init_vecs()
(global data structure initialization),
mpath_persistent_reserve_free_vecs (global teardown) and mpath_get_map()
(struct multipath setup for given map device).
Provide __mpath_presistent_reserve_{in,out}, which are the same
as their counterparts without leading underscores, but do not
call the global setup and teardown routines. This allows running
several PR commands in a row without having to re-initialize in
between. Because libmpathpersist is a public API, the previously
known functions don't change behavior.
Don't call path_discovery() any more during global initialization.
We rather do this lazily in the get_mpvec() call chain. dm_get_maps(),
OTOH, is part of the global initialization procedure. In get_mpvec(),
we don't delete non-matching maps any more, because we way want to
act on them later on.
---
libmpathpersist/mpath_persist.c | 231 ++++++++++++++------------------
libmpathpersist/mpath_persist.h | 40 ++++++
2 files changed, 142 insertions(+), 129 deletions(-)
diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c
index fee1db72..ce72da67 100644
--- a/libmpathpersist/mpath_persist.c
+++ b/libmpathpersist/mpath_persist.c
@@ -164,48 +164,47 @@ mpath_prin_activepath (struct multipath *mpp, int rq_servact,
int mpath_persistent_reserve_in (int fd, int rq_servact,
struct prin_resp *resp, int noisy, int verbose)
{
- struct stat info;
- vector curmp = NULL;
- vector pathvec = NULL;
- char * alias;
- struct multipath * mpp;
- int map_present;
- int major, minor;
- int ret;
- struct config *conf;
+ int ret = mpath_persistent_reserve_init_vecs(verbose);
- conf = get_multipath_config();
- conf->verbosity = verbose;
- put_multipath_config(conf);
+ if (ret != MPATH_PR_SUCCESS)
+ return ret;
+ ret = __mpath_persistent_reserve_in(fd, rq_servact, resp, noisy);
+ mpath_persistent_reserve_free_vecs();
+ return ret;
+}
- if (fstat( fd, &info) != 0){
- condlog(0, "stat error %d", fd);
- return MPATH_PR_FILE_ERROR;
- }
- if(!S_ISBLK(info.st_mode)){
- condlog(0, "Failed to get major:minor. fd = %d", fd);
- return MPATH_PR_FILE_ERROR;
- }
+int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
+ unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose)
+{
+ int ret = mpath_persistent_reserve_init_vecs(verbose);
- major = major(info.st_rdev);
- minor = minor(info.st_rdev);
- condlog(4, "Device %d:%d: ", major, minor);
+ if (ret != MPATH_PR_SUCCESS)
+ return ret;
+ ret = __mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type,
+ paramp, noisy);
+ mpath_persistent_reserve_free_vecs();
+ return ret;
+}
- /* 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;
- }
+static vector curmp;
+static vector pathvec;
- condlog(3, "alias = %s", alias);
- map_present = dm_map_present(alias);
- if (map_present && dm_is_mpath(alias) != 1){
- condlog( 0, "%s: not a multipath device.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out;
- }
+void mpath_persistent_reserve_free_vecs(void)
+{
+ free_multipathvec(curmp, KEEP_PATHS);
+ free_pathvec(pathvec, FREE_PATHS);
+ curmp = pathvec = NULL;
+}
+
+int mpath_persistent_reserve_init_vecs(int verbose)
+{
+ struct config *conf = get_multipath_config();
+ conf->verbosity = verbose;
+ put_multipath_config(conf);
+
+ if (curmp)
+ return MPATH_PR_SUCCESS;
/*
* allocate core vectors to store paths and multipaths
*/
@@ -213,70 +212,32 @@ int mpath_persistent_reserve_in (int fd, int rq_servact,
pathvec = vector_alloc ();
if (!curmp || !pathvec){
- condlog (0, "%s: vector allocation failed.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- if (curmp)
- vector_free(curmp);
- if (pathvec)
- vector_free(pathvec);
- goto out;
- }
-
- if (path_discovery(pathvec, DI_SYSFS | DI_CHECKER) < 0) {
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
+ condlog (0, "vector allocation failed.");
+ goto err;
}
- /* get info of all paths from the dm device */
- if (get_mpvec (curmp, pathvec, alias)){
- condlog(0, "%s: failed to get device info.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
- }
+ if (dm_get_maps(curmp))
+ goto err;
- mpp = find_mp_by_alias(curmp, alias);
- if (!mpp){
- condlog(0, "%s: devmap not registered.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
- }
-
- ret = mpath_prin_activepath(mpp, rq_servact, resp, noisy);
+ return MPATH_PR_SUCCESS;
-out1:
- free_multipathvec(curmp, KEEP_PATHS);
- free_pathvec(pathvec, FREE_PATHS);
-out:
- FREE(alias);
- return ret;
+err:
+ mpath_persistent_reserve_free_vecs();
+ return MPATH_PR_DMMP_ERROR;
}
-int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
- unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy, int verbose)
+static int mpath_get_map(int fd, char **palias, struct multipath **pmpp)
{
-
+ int ret = MPATH_PR_DMMP_ERROR;
struct stat info;
-
- vector curmp = NULL;
- vector pathvec = NULL;
-
- char * alias;
- struct multipath * mpp;
- int map_present;
int major, minor;
- int ret;
- uint64_t prkey;
- struct config *conf;
-
- conf = get_multipath_config();
- conf->verbosity = verbose;
- put_multipath_config(conf);
+ char *alias;
+ struct multipath *mpp;
- if (fstat( fd, &info) != 0){
+ 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;
@@ -286,57 +247,73 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
minor = minor(info.st_rdev);
condlog(4, "Device %d:%d", major, minor);
- /* get WWN of the device from 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);
- map_present = dm_map_present(alias);
- if (map_present && dm_is_mpath(alias) != 1){
+ if (dm_map_present(alias) && dm_is_mpath(alias) != 1){
condlog(3, "%s: not a multipath device.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out;
- }
-
- /*
- * allocate core vectors to store paths and multipaths
- */
- curmp = vector_alloc ();
- pathvec = vector_alloc ();
-
- if (!curmp || !pathvec){
- condlog (0, "%s: vector allocation failed.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- if (curmp)
- vector_free(curmp);
- if (pathvec)
- vector_free(pathvec);
goto out;
}
- if (path_discovery(pathvec, DI_SYSFS | DI_CHECKER) < 0) {
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
- }
-
/* get info of all paths from the dm device */
if (get_mpvec(curmp, pathvec, alias)){
condlog(0, "%s: failed to get device info.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
+ goto out;
}
mpp = find_mp_by_alias(curmp, alias);
if (!mpp) {
condlog(0, "%s: devmap not registered.", alias);
- ret = MPATH_PR_DMMP_ERROR;
- goto out1;
+ goto out;
}
+ ret = MPATH_PR_SUCCESS;
+ if (pmpp)
+ *pmpp = mpp;
+ if (palias) {
+ *palias = alias;
+ alias = NULL;
+ }
+out:
+ FREE(alias);
+ return ret;
+}
+
+int __mpath_persistent_reserve_in (int fd, int rq_servact,
+ struct prin_resp *resp, int noisy)
+{
+ struct multipath *mpp;
+ int ret;
+
+ ret = mpath_get_map(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_out ( 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(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);
@@ -397,10 +374,6 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
update_prkey(alias, 0);
}
out1:
- free_multipathvec(curmp, KEEP_PATHS);
- free_pathvec(pathvec, FREE_PATHS);
-
-out:
FREE(alias);
return ret;
}
@@ -412,22 +385,22 @@ get_mpvec (vector curmp, vector pathvec, char * refwwid)
struct multipath *mpp;
char params[PARAMS_SIZE], status[PARAMS_SIZE];
- if (dm_get_maps (curmp)){
- return 1;
- }
-
vector_foreach_slot (curmp, mpp, i){
/*
* discard out of scope maps
*/
- if (mpp->alias && refwwid &&
- strncmp (mpp->alias, refwwid, WWID_SIZE - 1)){
- free_multipath (mpp, KEEP_PATHS);
- vector_del_slot (curmp, i);
- i--;
+ 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;
+
dm_get_map(mpp->alias, &mpp->size, params);
condlog(3, "params = %s", params);
dm_get_status(mpp->alias, status);
diff --git a/libmpathpersist/mpath_persist.h b/libmpathpersist/mpath_persist.h
index 9a84bc9c..7cf4faf9 100644
--- a/libmpathpersist/mpath_persist.h
+++ b/libmpathpersist/mpath_persist.h
@@ -213,6 +213,15 @@ extern int mpath_lib_exit (struct config *conf);
extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp *resp,
int noisy, int verbose);
+/*
+ * DESCRIPTION :
+ * This function is like mpath_persistent_reserve_in(), except that it doesn't call
+ * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs()
+ * before and after the actual PR call.
+ */
+extern int __mpath_persistent_reserve_in(int fd, int rq_servact,
+ struct prin_resp *resp, int noisy);
+
/*
* DESCRIPTION :
* This function sends PROUT command to the DM device and get the response.
@@ -238,6 +247,37 @@ extern int mpath_persistent_reserve_in (int fd, int rq_servact, struct prin_resp
extern int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope,
unsigned int rq_type, struct prout_param_descriptor *paramp, int noisy,
int verbose);
+/*
+ * DESCRIPTION :
+ * This function is like mpath_persistent_reserve_out(), except that it doesn't call
+ * mpath_persistent_reserve_init_vecs() and mpath_persistent_reserve_free_vecs()
+ * before and after the actual PR call.
+ */
+extern int __mpath_persistent_reserve_out( int fd, int rq_servact, int rq_scope,
+ unsigned int rq_type, struct prout_param_descriptor *paramp,
+ int noisy);
+
+/*
+ * DESCRIPTION :
+ * This function allocates data structures and performs basic initialization and
+ * device discovery for later calls of __mpath_persistent_reserve_in() or
+ * __mpath_persistent_reserve_out().
+ * @verbose: Set verbosity level. Input argument. value:0 to 3. 0->disabled, 3->Max verbose
+ *
+ * RESTRICTIONS:
+ *
+ * RETURNS: MPATH_PR_SUCCESS if successful else returns any of the status specified
+ * above in RETURN_STATUS.
+ */
+int mpath_persistent_reserve_init_vecs(int verbose);
+
+/*
+ * DESCRIPTION :
+ * This function frees data structures allocated by
+ * mpath_persistent_reserve_init_vecs().
+ */
+void mpath_persistent_reserve_free_vecs(void);
+
#ifdef __cplusplus
}
--
2.21.0
More information about the dm-devel
mailing list