You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1175 lines
30 KiB
1175 lines
30 KiB
--- |
|
libmpathpersist/mpath_persist.c | 230 +++++++++++------------ |
|
libmpathpersist/mpath_persist.h | 40 ++++ |
|
mpathpersist/main.c | 223 ++++++++++++++++++----- |
|
mpathpersist/main.h | 1 |
|
mpathpersist/mpathpersist.8 | 385 ++++++++++++++++++++++++++++++---------- |
|
5 files changed, 616 insertions(+), 263 deletions(-) |
|
|
|
Index: multipath-tools-130222/mpathpersist/main.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/mpathpersist/main.c |
|
+++ multipath-tools-130222/mpathpersist/main.c |
|
@@ -18,6 +18,7 @@ |
|
#include <pthread.h> |
|
#include <ctype.h> |
|
#include <string.h> |
|
+#include <errno.h> |
|
|
|
static const char * pr_type_strs[] = { |
|
"obsolete [0]", |
|
@@ -46,9 +47,101 @@ int construct_transportid(const char * i |
|
int logsink; |
|
unsigned int mpath_mx_alloc_len; |
|
|
|
-int main (int argc, char * argv[]) |
|
+static int verbose, loglevel, noisy; |
|
+ |
|
+static int handle_args(int argc, char * argv[], int line); |
|
+ |
|
+static int do_batch_file(const char *batch_fn) |
|
{ |
|
- int fd, c, res; |
|
+ char command[] = "mpathpersist"; |
|
+ const int ARGV_CHUNK = 2; |
|
+ const char delims[] = " \t\n"; |
|
+ size_t len = 0; |
|
+ char *line = NULL; |
|
+ ssize_t n; |
|
+ int nline = 0; |
|
+ int argl = ARGV_CHUNK; |
|
+ FILE *fl; |
|
+ char **argv = calloc(argl, sizeof(*argv)); |
|
+ int ret = MPATH_PR_SUCCESS; |
|
+ |
|
+ if (argv == NULL) |
|
+ return MPATH_PR_OTHER; |
|
+ |
|
+ fl = fopen(batch_fn, "r"); |
|
+ if (fl == NULL) { |
|
+ fprintf(stderr, "unable to open %s: %s\n", |
|
+ batch_fn, strerror(errno)); |
|
+ free(argv); |
|
+ return MPATH_PR_SYNTAX_ERROR; |
|
+ } else { |
|
+ if (verbose >= 2) |
|
+ fprintf(stderr, "running batch file %s\n", |
|
+ batch_fn); |
|
+ } |
|
+ |
|
+ while ((n = getline(&line, &len, fl)) != -1) { |
|
+ char *_token, *token; |
|
+ int argc = 0; |
|
+ int rv; |
|
+ |
|
+ nline++; |
|
+ argv[argc++] = command; |
|
+ |
|
+ if (line[n-1] == '\n') |
|
+ line[n-1] = '\0'; |
|
+ if (verbose >= 3) |
|
+ fprintf(stderr, "processing line %d: %s\n", |
|
+ nline, line); |
|
+ |
|
+ for (token = strtok_r(line, delims, &_token); |
|
+ token != NULL && *token != '#'; |
|
+ token = strtok_r(NULL, delims, &_token)) { |
|
+ |
|
+ if (argc >= argl) { |
|
+ int argn = argl + ARGV_CHUNK; |
|
+ char **tmp; |
|
+ |
|
+ tmp = realloc(argv, argn * sizeof(*argv)); |
|
+ if (tmp == NULL) |
|
+ break; |
|
+ argv = tmp; |
|
+ argl = argn; |
|
+ } |
|
+ |
|
+ if (argc == 1 && !strcmp(token, command)) |
|
+ continue; |
|
+ |
|
+ argv[argc++] = token; |
|
+ } |
|
+ |
|
+ if (argc <= 1) |
|
+ continue; |
|
+ |
|
+ if (verbose >= 2) { |
|
+ int i; |
|
+ |
|
+ fprintf(stderr, "## file %s line %d:", batch_fn, nline); |
|
+ for (i = 0; i < argc; i++) |
|
+ fprintf(stderr, " %s", argv[i]); |
|
+ fprintf(stderr, "\n"); |
|
+ } |
|
+ |
|
+ optind = 0; |
|
+ rv = handle_args(argc, argv, nline); |
|
+ if (rv != MPATH_PR_SUCCESS) |
|
+ ret = rv; |
|
+ } |
|
+ |
|
+ fclose(fl); |
|
+ free(argv); |
|
+ free(line); |
|
+ return ret; |
|
+} |
|
+ |
|
+static int handle_args(int argc, char * argv[], int nline) |
|
+{ |
|
+ int fd, c; |
|
const char *device_name = NULL; |
|
int num_prin_sa = 0; |
|
int num_prout_sa = 0; |
|
@@ -69,45 +162,41 @@ int main (int argc, char * argv[]) |
|
int prin = 1; |
|
int prin_sa = -1; |
|
int prout_sa = -1; |
|
- int verbose = 0; |
|
- int loglevel = 0; |
|
- int noisy = 0; |
|
int num_transport =0; |
|
+ char *batch_fn = NULL; |
|
void *resp = NULL; |
|
struct transportid * tmp; |
|
- struct udev *udev = NULL; |
|
|
|
- if (optind == argc) |
|
- { |
|
- |
|
- fprintf (stderr, "No parameter used\n"); |
|
- usage (); |
|
- exit (1); |
|
- } |
|
- |
|
- if (getuid () != 0) |
|
- { |
|
- fprintf (stderr, "need to be root\n"); |
|
- exit (1); |
|
- } |
|
- |
|
- udev = udev_new(); |
|
- mpath_lib_init(udev); |
|
- memset(transportids,0,MPATH_MX_TIDS); |
|
+ memset(transportids, 0, MPATH_MX_TIDS * sizeof(struct transportid)); |
|
|
|
while (1) |
|
{ |
|
int option_index = 0; |
|
|
|
- c = getopt_long (argc, argv, "v:Cd:hHioZK:S:PAT:skrGILcRX:l:", |
|
+ c = getopt_long (argc, argv, "v:Cd:hHioZK:S:PAT:skrGILcRX:l:f:", |
|
long_options, &option_index); |
|
if (c == -1) |
|
break; |
|
|
|
switch (c) |
|
{ |
|
+ case 'f': |
|
+ if (nline != 0) { |
|
+ fprintf(stderr, |
|
+ "ERROR: -f option not allowed in batch file\n"); |
|
+ ret = MPATH_PR_SYNTAX_ERROR; |
|
+ goto out; |
|
+ } |
|
+ if (batch_fn != NULL) { |
|
+ fprintf(stderr, |
|
+ "ERROR: -f option can be used at most once\n"); |
|
+ ret = MPATH_PR_SYNTAX_ERROR; |
|
+ goto out; |
|
+ } |
|
+ batch_fn = strdup(optarg); |
|
+ break; |
|
case 'v': |
|
- if (1 != sscanf (optarg, "%d", &loglevel)) |
|
+ if (nline == 0 && 1 != sscanf (optarg, "%d", &loglevel)) |
|
{ |
|
fprintf (stderr, "bad argument to '--verbose'\n"); |
|
return MPATH_PR_SYNTAX_ERROR; |
|
@@ -241,8 +330,7 @@ int main (int argc, char * argv[]) |
|
break; |
|
|
|
default: |
|
- fprintf(stderr, "unrecognised switch " "code 0x%x ??\n", c); |
|
- usage (); |
|
+ fprintf(stderr, "unrecognised switch " "code 0x%x ??\n", c); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
@@ -260,27 +348,29 @@ int main (int argc, char * argv[]) |
|
{ |
|
for (; optind < argc; ++optind) |
|
fprintf (stderr, "Unexpected extra argument: %s\n", argv[optind]); |
|
- usage (); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
} |
|
|
|
- /* set verbosity */ |
|
- noisy = (loglevel >= 3) ? 1 : hex; |
|
- verbose = (loglevel >= 4)? 4 : loglevel; |
|
+ if (nline == 0) { |
|
+ /* set verbosity */ |
|
+ noisy = (loglevel >= 3) ? 1 : hex; |
|
+ verbose = (loglevel >= 4)? 4 : loglevel; |
|
+ ret = mpath_persistent_reserve_init_vecs(verbose); |
|
+ if (ret != MPATH_PR_SUCCESS) |
|
+ goto out; |
|
+ } |
|
|
|
- if ((prout_flag + prin_flag) == 0) |
|
+ if ((prout_flag + prin_flag) == 0 && batch_fn == NULL) |
|
{ |
|
fprintf (stderr, "choose either '--in' or '--out' \n"); |
|
- usage (); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
if ((prout_flag + prin_flag) > 1) |
|
{ |
|
fprintf (stderr, "choose either '--in' or '--out' \n"); |
|
- usage (); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
@@ -311,21 +401,19 @@ int main (int argc, char * argv[]) |
|
{ |
|
fprintf (stderr, |
|
" No service action given for Persistent Reserve IN\n"); |
|
- usage(); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
} |
|
else if (num_prin_sa > 1) |
|
{ |
|
fprintf (stderr, " Too many service actions given; choose " |
|
"one only\n"); |
|
- usage(); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
} |
|
} |
|
else |
|
{ |
|
- usage (); |
|
- ret = MPATH_PR_SYNTAX_ERROR; |
|
+ if (batch_fn == NULL) |
|
+ ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
|
|
@@ -333,7 +421,6 @@ int main (int argc, char * argv[]) |
|
{ |
|
fprintf (stderr, " --relative-target-port" |
|
" only useful with --register-move\n"); |
|
- usage (); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
@@ -355,7 +442,6 @@ int main (int argc, char * argv[]) |
|
if (device_name == NULL) |
|
{ |
|
fprintf (stderr, "No device name given \n"); |
|
- usage (); |
|
ret = MPATH_PR_SYNTAX_ERROR; |
|
goto out; |
|
} |
|
@@ -382,7 +468,7 @@ int main (int argc, char * argv[]) |
|
goto out; |
|
} |
|
|
|
- ret = mpath_persistent_reserve_in (fd, prin_sa, resp, noisy, verbose); |
|
+ ret = __mpath_persistent_reserve_in (fd, prin_sa, resp, noisy); |
|
if (ret != MPATH_PR_SUCCESS ) |
|
{ |
|
fprintf (stderr, "Persistent Reserve IN command failed\n"); |
|
@@ -442,8 +528,8 @@ int main (int argc, char * argv[]) |
|
} |
|
|
|
/* PROUT commands other than 'register and move' */ |
|
- ret = mpath_persistent_reserve_out (fd, prout_sa, 0, prout_type, |
|
- paramp, noisy, verbose); |
|
+ ret = __mpath_persistent_reserve_out (fd, prout_sa, 0, prout_type, |
|
+ paramp, noisy); |
|
for (j = 0 ; j < num_transport; j++) |
|
{ |
|
tmp = paramp->trnptid_list[j]; |
|
@@ -466,17 +552,57 @@ int main (int argc, char * argv[]) |
|
printf("PR out: command failed\n"); |
|
} |
|
|
|
- res = close (fd); |
|
- if (res < 0) |
|
+ close (fd); |
|
+ |
|
+out : |
|
+ if (ret == MPATH_PR_SYNTAX_ERROR) { |
|
+ free(batch_fn); |
|
+ if (nline == 0) |
|
+ usage(); |
|
+ else |
|
+ fprintf(stderr, "syntax error on line %d in batch file\n", |
|
+ nline); |
|
+ } else if (batch_fn != NULL) { |
|
+ int rv = do_batch_file(batch_fn); |
|
+ |
|
+ free(batch_fn); |
|
+ ret = ret == 0 ? rv : ret; |
|
+ } |
|
+ if (nline == 0) |
|
+ mpath_persistent_reserve_free_vecs(); |
|
+ return (ret >= 0) ? ret : MPATH_PR_OTHER; |
|
+} |
|
+ |
|
+int main(int argc, char *argv[]) |
|
+{ |
|
+ struct udev *udev; |
|
+ int ret; |
|
+ |
|
+ if (optind == argc) |
|
+ { |
|
+ |
|
+ fprintf (stderr, "No parameter used\n"); |
|
+ usage (); |
|
+ exit (1); |
|
+ } |
|
+ |
|
+ if (getuid () != 0) |
|
{ |
|
- mpath_lib_exit(); |
|
+ fprintf (stderr, "need to be root\n"); |
|
+ exit (1); |
|
+ } |
|
+ |
|
+ udev = udev_new(); |
|
+ if(mpath_lib_init(udev) != 0) { |
|
udev_unref(udev); |
|
- return MPATH_PR_FILE_ERROR; |
|
+ exit(1); |
|
} |
|
|
|
-out : |
|
+ ret = handle_args(argc, argv, 0); |
|
+ |
|
mpath_lib_exit(); |
|
udev_unref(udev); |
|
+ |
|
return (ret >= 0) ? ret : MPATH_PR_OTHER; |
|
} |
|
|
|
@@ -677,6 +803,7 @@ static void usage() |
|
" 4 Informational messages with trace enabled\n" |
|
" --clear|-C PR Out: Clear\n" |
|
" --device=DEVICE|-d DEVICE query or change DEVICE\n" |
|
+ " --batch-file|-f FILE run commands from FILE\n" |
|
" --help|-h output this usage message\n" |
|
" --hex|-H output response in hex\n" |
|
" --in|-i request PR In command \n" |
|
Index: multipath-tools-130222/mpathpersist/main.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/mpathpersist/main.h |
|
+++ multipath-tools-130222/mpathpersist/main.h |
|
@@ -2,6 +2,7 @@ static struct option long_options[] = { |
|
{"verbose", 1, 0, 'v'}, |
|
{"clear", 0, 0, 'C'}, |
|
{"device", 1, 0, 'd'}, |
|
+ {"batch-file", 1, 0, 'f' }, |
|
{"help", 0, 0, 'h'}, |
|
{"hex", 0, 0, 'H'}, |
|
{"in", 0, 0, 'i'}, |
|
Index: multipath-tools-130222/libmpathpersist/mpath_persist.c |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c |
|
+++ multipath-tools-130222/libmpathpersist/mpath_persist.c |
|
@@ -16,6 +16,7 @@ |
|
#include <config.h> |
|
#include <switchgroup.h> |
|
#include <discovery.h> |
|
+#include <configure.h> |
|
#include <dmparser.h> |
|
#include <ctype.h> |
|
#include <propsel.h> |
|
@@ -80,17 +81,21 @@ updatepaths (struct multipath * mpp) |
|
pp->state = PATH_DOWN; |
|
continue; |
|
} |
|
- pp->mpp = mpp; |
|
- pathinfo(pp, conf->hwtable, DI_ALL); |
|
- continue; |
|
} |
|
pp->mpp = mpp; |
|
+ if (pp->udev == NULL) { |
|
+ pp->udev = udev_device_new_from_devnum(conf->udev, 'b', parse_devt(pp->dev_t)); |
|
+ if (pp->udev == NULL) { |
|
+ pp->state = PATH_DOWN; |
|
+ continue; |
|
+ } |
|
+ pathinfo(pp, conf->hwtable, |
|
+ DI_SYSFS|DI_CHECKER); |
|
+ continue; |
|
+ } |
|
if (pp->state == PATH_UNCHECKED || |
|
pp->state == PATH_WILD) |
|
pathinfo(pp, conf->hwtable, DI_CHECKER); |
|
- |
|
- if (pp->priority == PRIO_UNDEF) |
|
- pathinfo(pp, conf->hwtable, DI_PRIO); |
|
} |
|
} |
|
return 0; |
|
@@ -129,45 +134,44 @@ mpath_prin_activepath (struct multipath |
|
|
|
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; |
|
+ int ret = mpath_persistent_reserve_init_vecs(verbose); |
|
|
|
- conf->verbosity = verbose; |
|
+ 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 = (int)MAJOR(info.st_rdev); |
|
- minor = (int)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)){ |
|
- 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) |
|
+{ |
|
+ conf->verbosity = verbose; |
|
|
|
+ if (curmp) |
|
+ return MPATH_PR_SUCCESS; |
|
/* |
|
* allocate core vectors to store paths and multipaths |
|
*/ |
|
@@ -175,63 +179,32 @@ int mpath_persistent_reserve_in (int fd, |
|
pathvec = vector_alloc (); |
|
|
|
if (!curmp || !pathvec){ |
|
- condlog (0, "%s: vector allocation failed.", alias); |
|
- ret = MPATH_PR_DMMP_ERROR; |
|
- goto out; |
|
- } |
|
- |
|
- if (path_discovery(pathvec, conf, 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; |
|
+ condlog (0, "vector allocation failed."); |
|
+ 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; |
|
- } |
|
+ if (dm_get_maps(curmp)) |
|
+ goto err; |
|
|
|
- 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; |
|
- |
|
- conf->verbosity = verbose; |
|
+ 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; |
|
@@ -241,53 +214,72 @@ int mpath_persistent_reserve_out ( int f |
|
minor = (int)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)){ |
|
+ if (dm_map_present(alias) && !dm_is_mpath(alias)){ |
|
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; |
|
goto out; |
|
} |
|
|
|
- if (path_discovery(pathvec, conf, 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; |
|
+ |
|
+ ret = mpath_get_map(fd, &alias, &mpp); |
|
+ if (ret != MPATH_PR_SUCCESS) |
|
+ return ret; |
|
+ |
|
select_reservation_key(mpp); |
|
select_all_tg_pt(mpp); |
|
|
|
@@ -350,10 +342,6 @@ int mpath_persistent_reserve_out ( int f |
|
} |
|
} |
|
out1: |
|
- free_multipathvec(curmp, KEEP_PATHS); |
|
- free_pathvec(pathvec, FREE_PATHS); |
|
- |
|
-out: |
|
FREE(alias); |
|
return ret; |
|
} |
|
@@ -365,21 +353,22 @@ get_mpvec (vector curmp, vector pathvec, |
|
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)){ |
|
- 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); |
|
@@ -392,7 +381,6 @@ get_mpvec (vector curmp, vector pathvec, |
|
* about them |
|
*/ |
|
updatepaths(mpp); |
|
- mpp->bestpg = select_path_group (mpp); |
|
disassemble_status (status, mpp); |
|
|
|
} |
|
Index: multipath-tools-130222/libmpathpersist/mpath_persist.h |
|
=================================================================== |
|
--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.h |
|
+++ multipath-tools-130222/libmpathpersist/mpath_persist.h |
|
@@ -212,6 +212,15 @@ extern int mpath_persistent_reserve_in ( |
|
|
|
/* |
|
* 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. |
|
* |
|
* @fd: The file descriptor of a multipath device. Input argument. |
|
@@ -235,6 +244,37 @@ extern int mpath_persistent_reserve_in ( |
|
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 |
|
} |
|
Index: multipath-tools-130222/mpathpersist/mpathpersist.8 |
|
=================================================================== |
|
--- multipath-tools-130222.orig/mpathpersist/mpathpersist.8 |
|
+++ multipath-tools-130222/mpathpersist/mpathpersist.8 |
|
@@ -1,99 +1,296 @@ |
|
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.39.2. |
|
-.TH MPATHPERSIST "8" "April 2011" "mpathpersist" "User Commands" |
|
+.\" ---------------------------------------------------------------------------- |
|
+.\" Update the date below if you make any significant change. |
|
+.\" Make sure there are no errors with: |
|
+.\" groff -z -wall -b -e -t mpathpersist/mpathpersist.8 |
|
+.\" |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+.TH MPATHPERSIST 8 2019-05-27 "Linux" |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
.SH NAME |
|
-mpathpersist |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+mpathpersist \- Manages SCSI persistent reservations on dm multipath devices. |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
.SH SYNOPSIS |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
.B mpathpersist |
|
-[\fIOPTIONS\fR] [\fIDEVICE\fR] |
|
+.RB [\| OPTIONS \|] |
|
+.I device |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
.SH DESCRIPTION |
|
-.IP |
|
-Options: |
|
-.TP |
|
-\fB\-\-verbose\fR|\-v level |
|
-verbosity level |
|
-.TP |
|
-0 |
|
-Critical and error messages |
|
-.TP |
|
-1 |
|
-Warning messages |
|
-.TP |
|
-2 |
|
-Informational messages |
|
-.TP |
|
-3 |
|
-Informational messages with trace enabled |
|
-.TP |
|
-\fB\-\-clear\fR|\-C |
|
-PR Out: Clear |
|
-.TP |
|
-\fB\-\-device\fR=\fIDEVICE\fR|\-d DEVICE |
|
-query or change DEVICE |
|
-.TP |
|
-\fB\-\-help\fR|\-h |
|
-output this usage message |
|
-.TP |
|
-\fB\-\-hex\fR|\-H |
|
-output response in hex |
|
-.TP |
|
-\fB\-\-in\fR|\-i |
|
-request PR In command |
|
-.TP |
|
-\fB\-\-out\fR|\-o |
|
-request PR Out command |
|
-.TP |
|
-\fB\-\-param\-aptpl\fR|\-Z |
|
-PR Out parameter 'APTPL' |
|
-.TP |
|
-\fB\-\-read\-keys\fR|\-k |
|
-PR In: Read Keys |
|
-.TP |
|
-\fB\-\-param\-rk\fR=\fIRK\fR|\-K RK |
|
-PR Out parameter reservation key (RK is in hex) |
|
-.TP |
|
-\fB\-\-param\-sark\fR=\fISARK\fR|\-S SARK |
|
-PR Out parameter service action |
|
-reservation key (SARK is in hex) |
|
-.TP |
|
-\fB\-\-preempt\fR|\-P |
|
-PR Out: Preempt |
|
-.TP |
|
-\fB\-\-preempt\-abort\fR|\-A |
|
-PR Out: Preempt and Abort |
|
-.TP |
|
-\fB\-\-prout\-type\fR=\fITYPE\fR|\-T TYPE |
|
-PR Out command type |
|
-.TP |
|
-\fB\-\-read\-status\fR|\-s |
|
-PR In: Read Full Status |
|
-.TP |
|
-\fB\-\-read\-keys\fR|\-k |
|
-PR In: Read Keys |
|
-.TP |
|
-\fB\-\-read\-reservation\fR|\-r |
|
-PR In: Read Reservation |
|
-.TP |
|
-\fB\-\-register\fR|\-G |
|
-PR Out: Register |
|
-.TP |
|
-\fB\-\-register\-ignore\fR|\-I |
|
-PR Out: Register and Ignore |
|
-.TP |
|
-\fB\-\-release\fR|\-L |
|
-PR Out: Release |
|
-.TP |
|
-\fB\-\-report\-capabilities\fR|\-c |
|
-PR In: Report Capabilities |
|
-.TP |
|
-\fB\-\-reserve\fR|\-R |
|
-PR Out: Reserve |
|
-.TP |
|
-\fB\-\-transport\-id\fR=\fITIDS\fR|\-X TIDS |
|
-TransportIDs can be mentioned |
|
-in several forms |
|
-.IP |
|
-Examples: |
|
-.IP |
|
-mpathpersist \fB\-\-out\fR \fB\-\-register\fR \fB\-\-param\-sark\fR=\fI123abc\fR \fB\-\-prout\-type\fR=\fI5\fR /dev/mapper/mpath9 |
|
-mpathpersist \fB\-i\fR \fB\-k\fR /dev/mapper/mpath9 |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+This utility is used to manage SCSI persistent reservations on Device Mapper |
|
+Multipath devices. To be able to use this functionality, the \fIreservation_key\fR |
|
+attribute must be defined in the \fI/etc/multipath.conf\fR file. Otherwise the |
|
+\fBmultipathd\fR daemon will not check for persistent reservation for newly |
|
+discovered paths or reinstated paths. |
|
+. |
|
+.LP |
|
+\fBmpathpersist\fR supports the same command-line options as the |
|
+\fBsg_persist\fR utility. |
|
+. |
|
+Consult the \fBsg_persist (8)\fR manual page for an in-depth discussion of the |
|
+various options. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
+.SH OPTIONS |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+.TP |
|
+.BI \-verbose|\-v " level" |
|
+Verbosity: |
|
+.RS |
|
+.TP 5 |
|
+.I 0 |
|
+Critical messages. |
|
+.TP |
|
+.I 1 |
|
+Error messages. |
|
+.TP |
|
+.I 2 |
|
+Warning messages. |
|
+.TP |
|
+.I 3 |
|
+Informational messages. |
|
+.TP |
|
+.I 4 |
|
+Informational messages with trace enabled. |
|
+.RE |
|
+. |
|
+.TP |
|
+.BI \--device=\fIDEVICE\fB|\-d " DEVICE" |
|
+Query or change DEVICE. |
|
+. |
|
+.TP |
|
+.BI \--batch-file=\fIDEVICE\fB|\-f " FILE" |
|
+Read commands from \fIFILE\fR. See section \(dqBATCH FILES\(dq below. This |
|
+option can be given at most once. |
|
+. |
|
+.TP |
|
+.B \--help|\-h |
|
+Output this usage message. |
|
+. |
|
+.TP |
|
+.B \--hex|\-H |
|
+Output response in hex. |
|
+. |
|
+.TP |
|
+.B \--in|\-i |
|
+Request PR In command. |
|
+. |
|
+.TP |
|
+.B \--out|\-o |
|
+Request PR Out command. |
|
+. |
|
+.TP |
|
+.B \--param-aptpl|\-Z |
|
+PR Out parameter 'APTPL'. |
|
+. |
|
+.TP |
|
+.B \--read-keys|\-k |
|
+PR In: Read Keys. |
|
+. |
|
+.TP |
|
+.BI \--param-rk=\fIRK\fB|\-K " RK" |
|
+PR Out parameter reservation key (RK is in hex, up to 8 bytes). |
|
+. |
|
+.TP |
|
+.BI \--param-sark=\fISARK\fB|\-S " SARK" |
|
+PR Out parameter service action reservation key (SARK is in hex). |
|
+. |
|
+.TP |
|
+.B \--preempt|\-P |
|
+PR Out: Preempt. |
|
+. |
|
+.TP |
|
+.B \--clear|\-C |
|
+PR Out: Clear registrations. |
|
+. |
|
+.TP |
|
+.B \--preempt-abort|\-A |
|
+PR Out: Preempt and Abort. |
|
+. |
|
+.TP |
|
+.BI \--prout-type=\fITYPE\fB|\-T " TYPE" |
|
+PR Out command type. |
|
+. |
|
+.TP |
|
+.B \--read-full-status|\-s |
|
+PR In: Read Full Status. |
|
+. |
|
+.TP |
|
+.B \--read-keys|\-k |
|
+PR In: Read Keys. |
|
+. |
|
+.TP |
|
+.B \--read-reservation|\-r |
|
+PR In: Read Reservation. |
|
+. |
|
+.TP |
|
+.B \--register|\-G |
|
+PR Out: Register. |
|
+. |
|
+.TP |
|
+.B \--register-ignore|\-I |
|
+PR Out: Register and Ignore. |
|
+. |
|
+.TP |
|
+.B \--release|\-L |
|
+PR Out: Release. |
|
+. |
|
+.TP |
|
+.B \--report-capabilities|\-c |
|
+PR In: Report Capabilities. |
|
+. |
|
+.TP |
|
+.B \--reserve|\-R |
|
+PR Out: Reserve. |
|
+. |
|
+.TP |
|
+.BI \--transport-id=\fITIDS\fB|\-X " TIDS" |
|
+TransportIDs can be mentioned in several forms. |
|
+. |
|
+.TP |
|
+.BI \--alloc-length=\fILEN\fB|\-l " LEN" |
|
+PR In: maximum allocation length. LEN is a decimal number between 0 and 8192. |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
+.SH EXAMPLE |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+.PP |
|
+Register the key \(dq123abc\(dq for the /dev/mapper/mpath9 device: |
|
+.RS |
|
+\fBmpathpersist --out --register --param-sark=\fI123abc /dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Read registered reservation keys for the /dev/mapper/mpath9 device: |
|
+.RS |
|
+\fBmpathpersist -i -k \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Create a reservation for the /dev/mapper/mpath9 device with the given |
|
+reservation key: |
|
+.RS |
|
+\fBmpathpersist --out --reserve --param-rk=\fI123abc \fB--prout-type=\fI8 \fB-d \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Read the reservation status of the /dev/mapper/mpath9 device: |
|
+.RS |
|
+\fBmpathpersist -i -s -d \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Release the previously created reservation (note that the prout-type needs to |
|
+be the same as above): |
|
+.RS |
|
+\fBmpathpersist --out --release --param-rk=\fI123abc \fB--prout-type=\fI8 \fB-d \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Remove the current key registered for this host (i.e. reset it to 0): |
|
+.RS |
|
+\fBmpathpersist --out --register-ignore -K \fI123abc\fB -S \fI0\fB \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+.PP |
|
+Remove current reservation, and unregister all registered keys from all I_T nexuses: |
|
+.RS |
|
+\fBmpathpersist -oCK \fI123abc \fI/dev/mapper/mpath9\fR |
|
+.RE |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
+.SH BATCH FILES |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+.PP |
|
+The option \fI--batch-file\fR (\fI-f\fR) sets an input file to be processed |
|
+by \fBmpathpersist\fR. Grouping commands in batch files can provide a speed |
|
+improvement in particular on large installments, because \fBmpathpersist\fR |
|
+needs to scan existing paths and maps only once during startup. |
|
+. |
|
+.PP |
|
+The input file is a text file that is parsed |
|
+line by line. Every line of the file is interpreted as a command line |
|
+(i.e. list of options and parameters) for \fBmpathpersist\fR. Options |
|
+and parameters are separated by one or more whitespace characters (space or TAB). |
|
+Lines can, but do not have to, begin with the word \(dqmpathpersist\(dq. |
|
+The \(dq#\(dq character, either at the beginning of the line or following |
|
+some whitespace, denotes the start of a comment that lasts until the end of the |
|
+line. Empty lines are allowed. Continuation of mpathpersist commands over |
|
+multiple lines is not supported. |
|
+. |
|
+.PP |
|
+All options listed in this man page, except \fI-f\fR and |
|
+\fI-v\fR, are allowed in batch files. Both short and long option formats may be used. |
|
+Using the \fI-f\fR option inside the batch file is an error. The \fI-v\fR |
|
+option is ignored in batch files. |
|
+. |
|
+.PP |
|
+The multipath map on which to act must be specified on every input line, e.g. using the \fI-d\fR option. |
|
+Commands acting on different multipath maps may be combined in a |
|
+batch file, and multiple commands may act on the same multipath |
|
+map. Commands are executed one by one, so |
|
+that commands further down in the file see status changes caused by previous |
|
+commands. |
|
+If \fBmpathpersist\fR encounters an error while processing a line in the |
|
+batch file, batch file processing is \fBnot\fR aborted; subsequent commands |
|
+are executed nonetheless. The exit status of \fBmpathpersist\fR is the status |
|
+of the first failed command, or 0 if all commands succeeded. |
|
+. |
|
+.PP |
|
+If other options and parameters are used along with |
|
+\fI-f\fR on the \fBmpathpersist\fR command line, the command line will be executed first, followed |
|
+by the commands from the the batch file. |
|
+. |
|
+.PP |
|
+Below is an example of a valid batch input file. |
|
+. |
|
.PP |
|
+.RS |
|
+.EX |
|
+# This is an mpathpersist input file. |
|
+# Short and long forms of the same command |
|
+-i -k /dev/dm-1 # short form, this comment is ignored |
|
+mpathpersist --in --read-keys --device=/dev/dm-1 |
|
+ |
|
+# Mixing of long and short options, variable white space |
|
+ --out --register -S abcde /dev/dm-1 |
|
+ |
|
+# Mixing of commands for different maps |
|
+-ir /dev/dm-0 |
|
+-ir /dev/dm-1 |
|
+ |
|
+mpathpersist --out --param-rk abcde --reserve --prout-type 5 /dev/dm-1 |
|
+# This should now show a reservation |
|
+-ir /dev/dm-1 |
|
+-oCK abcde /dev/dm-1 |
|
+--in --read-reservation /dev/dm-1 |
|
+.EE |
|
+.RE |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
+.SH "SEE ALSO" |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+.BR multipath (8), |
|
+.BR multipathd (8), |
|
+.BR sg_persist (8). |
|
+. |
|
+. |
|
+.\" ---------------------------------------------------------------------------- |
|
+.SH AUTHORS |
|
+.\" ---------------------------------------------------------------------------- |
|
+. |
|
+\fImultipath-tools\fR was developed by Christophe Varoqui <christophe.varoqui@opensvc.com> |
|
+and others. |
|
+.\" EOF
|
|
|