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