|
|
4728c8 |
---
|
|
|
4728c8 |
libmpathpersist/mpath_persist.c | 79 +++++++++---------
|
|
|
4728c8 |
libmpathpersist/mpath_updatepr.c | 40 +++++----
|
|
|
4728c8 |
libmpathpersist/mpathpr.h | 5 -
|
|
|
4728c8 |
libmultipath/Makefile | 2
|
|
|
4728c8 |
libmultipath/byteorder.h | 43 ++++++++++
|
|
|
4728c8 |
libmultipath/checkers/rbd.c | 16 ---
|
|
|
4728c8 |
libmultipath/config.c | 9 +-
|
|
|
4728c8 |
libmultipath/config.h | 9 +-
|
|
|
4728c8 |
libmultipath/defaults.h | 1
|
|
|
4728c8 |
libmultipath/dict.c | 140 ++++++++++++--------------------
|
|
|
4728c8 |
libmultipath/prkey.c | 167 +++++++++++++++++++++++++++++++++++++++
|
|
|
4728c8 |
libmultipath/prkey.h | 19 ++++
|
|
|
4728c8 |
libmultipath/propsel.c | 58 ++++++-------
|
|
|
4728c8 |
libmultipath/structs.h | 14 ++-
|
|
|
4728c8 |
libmultipath/util.c | 34 +++++++
|
|
|
4728c8 |
libmultipath/util.h | 4
|
|
|
4728c8 |
mpathpersist/main.c | 5 -
|
|
|
4728c8 |
multipath/multipath.conf.5 | 18 +++-
|
|
|
4728c8 |
multipathd/cli.c | 7 +
|
|
|
4728c8 |
multipathd/cli.h | 8 +
|
|
|
4728c8 |
multipathd/cli_handlers.c | 69 ++++++++++++++++
|
|
|
4728c8 |
multipathd/cli_handlers.h | 4
|
|
|
4728c8 |
multipathd/main.c | 29 ++----
|
|
|
4728c8 |
multipathd/multipathd.8 | 13 +++
|
|
|
4728c8 |
24 files changed, 576 insertions(+), 217 deletions(-)
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/libmpathpersist/mpath_persist.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmpathpersist/mpath_persist.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmpathpersist/mpath_persist.c
|
|
|
4728c8 |
@@ -221,9 +221,7 @@ int mpath_persistent_reserve_out ( int f
|
|
|
4728c8 |
int map_present;
|
|
|
4728c8 |
int major, minor;
|
|
|
4728c8 |
int ret;
|
|
|
4728c8 |
- int j;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey;
|
|
|
4728c8 |
+ uint64_t prkey;
|
|
|
4728c8 |
|
|
|
4728c8 |
conf->verbosity = verbose;
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -290,6 +288,27 @@ int mpath_persistent_reserve_out ( int f
|
|
|
4728c8 |
|
|
|
4728c8 |
select_reservation_key(mpp);
|
|
|
4728c8 |
|
|
|
4728c8 |
+ memcpy(&prkey, paramp->sa_key, 8);
|
|
|
4728c8 |
+ if (mpp->prkey_source == PRKEY_SOURCE_FILE && prkey &&
|
|
|
4728c8 |
+ ((!get_be64(mpp->reservation_key) &&
|
|
|
4728c8 |
+ rq_servact == MPATH_PROUT_REG_SA) ||
|
|
|
4728c8 |
+ rq_servact == MPATH_PROUT_REG_IGN_SA)) {
|
|
|
4728c8 |
+ memcpy(&mpp->reservation_key, paramp->sa_key, 8);
|
|
|
4728c8 |
+ if (update_prkey(alias, get_be64(mpp->reservation_key))) {
|
|
|
4728c8 |
+ condlog(0, "%s: failed to set prkey for multipathd.",
|
|
|
4728c8 |
+ alias);
|
|
|
4728c8 |
+ ret = MPATH_PR_DMMP_ERROR;
|
|
|
4728c8 |
+ goto out1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (memcmp(paramp->key, &mpp->reservation_key, 8) &&
|
|
|
4728c8 |
+ memcmp(paramp->sa_key, &mpp->reservation_key, 8)) {
|
|
|
4728c8 |
+ condlog(0, "%s: configured reservation key doesn't match: 0x%" PRIx64, alias, get_be64(mpp->reservation_key));
|
|
|
4728c8 |
+ ret = MPATH_PR_SYNTAX_ERROR;
|
|
|
4728c8 |
+ goto out1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+
|
|
|
4728c8 |
switch(rq_servact)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
case MPATH_PROUT_REG_SA:
|
|
|
4728c8 |
@@ -311,24 +330,19 @@ int mpath_persistent_reserve_out ( int f
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_REG_SA) ||
|
|
|
4728c8 |
- (rq_servact == MPATH_PROUT_REG_IGN_SA)))
|
|
|
4728c8 |
+ (rq_servact == MPATH_PROUT_REG_IGN_SA)))
|
|
|
4728c8 |
{
|
|
|
4728c8 |
- keyp=paramp->sa_key;
|
|
|
4728c8 |
- prkey = 0;
|
|
|
4728c8 |
- for (j = 0; j < 8; ++j) {
|
|
|
4728c8 |
- if (j > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- ++keyp;
|
|
|
4728c8 |
+ if (!prkey) {
|
|
|
4728c8 |
+ update_prflag(alias, 0);
|
|
|
4728c8 |
+ update_prkey(alias, 0);
|
|
|
4728c8 |
}
|
|
|
4728c8 |
- if (prkey == 0)
|
|
|
4728c8 |
- update_prflag(alias, "unset", noisy);
|
|
|
4728c8 |
else
|
|
|
4728c8 |
- update_prflag(alias, "set", noisy);
|
|
|
4728c8 |
+ update_prflag(alias, 1);
|
|
|
4728c8 |
} else {
|
|
|
4728c8 |
- if ((ret == MPATH_PR_SUCCESS) && ((rq_servact == MPATH_PROUT_CLEAR_SA) ||
|
|
|
4728c8 |
- (rq_servact == MPATH_PROUT_PREE_AB_SA ))){
|
|
|
4728c8 |
- update_prflag(alias, "unset", noisy);
|
|
|
4728c8 |
+ if ((ret == MPATH_PR_SUCCESS) &&
|
|
|
4728c8 |
+ (rq_servact == MPATH_PROUT_CLEAR_SA)) {
|
|
|
4728c8 |
+ update_prflag(alias, 0);
|
|
|
4728c8 |
+ update_prkey(alias, 0);
|
|
|
4728c8 |
}
|
|
|
4728c8 |
}
|
|
|
4728c8 |
out1:
|
|
|
4728c8 |
@@ -729,8 +743,8 @@ int mpath_prout_rel(struct multipath *mp
|
|
|
4728c8 |
goto out1;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (mpp->reservation_key ){
|
|
|
4728c8 |
- memcpy (pamp->key, mpp->reservation_key, 8);
|
|
|
4728c8 |
+ if (get_be64(mpp->reservation_key)){
|
|
|
4728c8 |
+ memcpy (pamp->key, &mpp->reservation_key, 8);
|
|
|
4728c8 |
condlog (3, "%s: reservation key set.", mpp->wwid);
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -741,9 +755,9 @@ int mpath_prout_rel(struct multipath *mp
|
|
|
4728c8 |
pptr=pamp->trnptid_list[0];
|
|
|
4728c8 |
|
|
|
4728c8 |
for (i = 0; i < num; i++){
|
|
|
4728c8 |
- if (mpp->reservation_key &&
|
|
|
4728c8 |
+ if (get_be64(mpp->reservation_key) &&
|
|
|
4728c8 |
memcmp(pr_buff->prin_descriptor.prin_readfd.descriptors[i]->key,
|
|
|
4728c8 |
- mpp->reservation_key, 8)){
|
|
|
4728c8 |
+ &mpp->reservation_key, 8)){
|
|
|
4728c8 |
/*register with tarnsport id*/
|
|
|
4728c8 |
memset(pamp, 0, length);
|
|
|
4728c8 |
pamp->trnptid_list[0] = pptr;
|
|
|
4728c8 |
@@ -768,7 +782,7 @@ int mpath_prout_rel(struct multipath *mp
|
|
|
4728c8 |
}
|
|
|
4728c8 |
else
|
|
|
4728c8 |
{
|
|
|
4728c8 |
- if (mpp->reservation_key)
|
|
|
4728c8 |
+ if (get_be64(mpp->reservation_key))
|
|
|
4728c8 |
found = 1;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -777,7 +791,7 @@ int mpath_prout_rel(struct multipath *mp
|
|
|
4728c8 |
|
|
|
4728c8 |
if (found){
|
|
|
4728c8 |
memset (pamp, 0, length);
|
|
|
4728c8 |
- memcpy (pamp->sa_key, mpp->reservation_key, 8);
|
|
|
4728c8 |
+ memcpy (pamp->sa_key, &mpp->reservation_key, 8);
|
|
|
4728c8 |
memset (pamp->key, 0, 8);
|
|
|
4728c8 |
status = mpath_prout_reg(mpp, MPATH_PROUT_REG_SA, rq_scope, rq_type, pamp, noisy);
|
|
|
4728c8 |
}
|
|
|
4728c8 |
@@ -826,11 +840,9 @@ int update_map_pr(struct multipath *mpp)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
int noisy=0;
|
|
|
4728c8 |
struct prin_resp *resp;
|
|
|
4728c8 |
- int i,j, ret, isFound;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey;
|
|
|
4728c8 |
+ int i, ret, isFound;
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!mpp->reservation_key)
|
|
|
4728c8 |
+ if (!get_be64(mpp->reservation_key))
|
|
|
4728c8 |
{
|
|
|
4728c8 |
/* Nothing to do. Assuming pr mgmt feature is disabled*/
|
|
|
4728c8 |
condlog(3, "%s: reservation_key not set in multipath.conf", mpp->alias);
|
|
|
4728c8 |
@@ -859,15 +871,8 @@ int update_map_pr(struct multipath *mpp)
|
|
|
4728c8 |
return MPATH_PR_SUCCESS;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- prkey = 0;
|
|
|
4728c8 |
- keyp = mpp->reservation_key;
|
|
|
4728c8 |
- for (j = 0; j < 8; ++j) {
|
|
|
4728c8 |
- if (j > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- ++keyp;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
- condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias, prkey);
|
|
|
4728c8 |
+ condlog(2, "%s: Multipath reservation_key: 0x%" PRIx64 " ", mpp->alias,
|
|
|
4728c8 |
+ get_be64(mpp->reservation_key));
|
|
|
4728c8 |
|
|
|
4728c8 |
isFound =0;
|
|
|
4728c8 |
for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ )
|
|
|
4728c8 |
@@ -875,7 +880,7 @@ int update_map_pr(struct multipath *mpp)
|
|
|
4728c8 |
condlog(2, "%s: PR IN READKEYS[%d] reservation key:", mpp->alias, i);
|
|
|
4728c8 |
dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , 1);
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!memcmp(mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
|
|
|
4728c8 |
+ if (!memcmp(&mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
|
|
|
4728c8 |
{
|
|
|
4728c8 |
condlog(2, "%s: reservation key found in pr in readkeys response", mpp->alias);
|
|
|
4728c8 |
isFound =1;
|
|
|
4728c8 |
Index: multipath-tools-130222/libmpathpersist/mpath_updatepr.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmpathpersist/mpath_updatepr.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmpathpersist/mpath_updatepr.c
|
|
|
4728c8 |
@@ -1,7 +1,7 @@
|
|
|
4728c8 |
-#include<stdio.h>
|
|
|
4728c8 |
-#include<unistd.h>
|
|
|
4728c8 |
+#include <stdio.h>
|
|
|
4728c8 |
+#include <unistd.h>
|
|
|
4728c8 |
#include <errno.h>
|
|
|
4728c8 |
-
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
#include <stdlib.h>
|
|
|
4728c8 |
#include <stdarg.h>
|
|
|
4728c8 |
#include <fcntl.h>
|
|
|
4728c8 |
@@ -18,10 +18,10 @@
|
|
|
4728c8 |
|
|
|
4728c8 |
unsigned long mem_allocated; /* Total memory used in Bytes */
|
|
|
4728c8 |
|
|
|
4728c8 |
-int update_prflag(char * arg1, char * arg2, int noisy)
|
|
|
4728c8 |
+static int do_update_pr(char * mapname, char * arg)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
int fd;
|
|
|
4728c8 |
- char str[64];
|
|
|
4728c8 |
+ char str[256];
|
|
|
4728c8 |
char *reply;
|
|
|
4728c8 |
int ret = 0;
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -31,25 +31,35 @@ int update_prflag(char * arg1, char * ar
|
|
|
4728c8 |
return 1 ;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- snprintf(str,sizeof(str),"map %s %s", arg1, arg2);
|
|
|
4728c8 |
- condlog (2, "%s: pr flag message=%s", arg1, str);
|
|
|
4728c8 |
+ snprintf(str,sizeof(str),"map %s %s", mapname, arg);
|
|
|
4728c8 |
+ condlog (2, "%s: pr message=%s", mapname, arg);
|
|
|
4728c8 |
send_packet(fd, str);
|
|
|
4728c8 |
ret = recv_packet(fd, &reply);
|
|
|
4728c8 |
if (ret < 0) {
|
|
|
4728c8 |
- condlog(2, "%s: message=%s recv error=%d", arg1, str, errno);
|
|
|
4728c8 |
+ condlog(2, "%s: message=%s recv error=%d", mapname, str, errno);
|
|
|
4728c8 |
ret = -2;
|
|
|
4728c8 |
} else {
|
|
|
4728c8 |
- condlog (2, "%s: message=%s reply=%s", arg1, str, reply);
|
|
|
4728c8 |
+ condlog (2, "%s: message=%s reply=%s", mapname, str, reply);
|
|
|
4728c8 |
if (!reply || strncmp(reply,"ok", 2) == 0)
|
|
|
4728c8 |
- ret = -1;
|
|
|
4728c8 |
- else if (strncmp(reply, "fail", 4) == 0)
|
|
|
4728c8 |
- ret = -2;
|
|
|
4728c8 |
- else{
|
|
|
4728c8 |
- ret = atoi(reply);
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
+ ret = 0;
|
|
|
4728c8 |
+ else ret = -1;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
free(reply);
|
|
|
4728c8 |
mpath_disconnect(fd);
|
|
|
4728c8 |
return ret;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int update_prflag(char *mapname, int set) {
|
|
|
4728c8 |
+ return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus");
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int update_prkey(char *mapname, uint64_t prkey) {
|
|
|
4728c8 |
+ char str[256];
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (prkey)
|
|
|
4728c8 |
+ snprintf(str, sizeof(str), "setprkey key %" PRIx64, prkey);
|
|
|
4728c8 |
+ else
|
|
|
4728c8 |
+ snprintf(str, sizeof(str), "unsetprkey");
|
|
|
4728c8 |
+ return do_update_pr(mapname, str);
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
Index: multipath-tools-130222/libmpathpersist/mpathpr.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmpathpersist/mpathpr.h
|
|
|
4728c8 |
+++ multipath-tools-130222/libmpathpersist/mpathpr.h
|
|
|
4728c8 |
@@ -1,6 +1,8 @@
|
|
|
4728c8 |
#ifndef MPATHPR_H
|
|
|
4728c8 |
#define MPATHPR_H
|
|
|
4728c8 |
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
+
|
|
|
4728c8 |
struct prin_param {
|
|
|
4728c8 |
char dev[FILE_NAME_SIZE];
|
|
|
4728c8 |
int rq_servact;
|
|
|
4728c8 |
@@ -47,7 +49,8 @@ int mpath_prout_rel(struct multipath *mp
|
|
|
4728c8 |
int send_prout_activepath(char * dev, int rq_servact, int rq_scope,
|
|
|
4728c8 |
unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy);
|
|
|
4728c8 |
|
|
|
4728c8 |
-int update_prflag(char * arg1, char * arg2, int noisy);
|
|
|
4728c8 |
+int update_prflag(char *mapname, int set);
|
|
|
4728c8 |
+int update_prkey(char *mapname, uint64_t prkey);
|
|
|
4728c8 |
void * mpath_alloc_prin_response(int prin_sa);
|
|
|
4728c8 |
int update_map_pr(struct multipath *mpp);
|
|
|
4728c8 |
int devt2devname (char *devname, char *devt);
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/byteorder.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- /dev/null
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/byteorder.h
|
|
|
4728c8 |
@@ -0,0 +1,43 @@
|
|
|
4728c8 |
+#ifndef BYTEORDER_H_INCLUDED
|
|
|
4728c8 |
+#define BYTEORDER_H_INCLUDED
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#ifdef __linux__
|
|
|
4728c8 |
+# include <endian.h>
|
|
|
4728c8 |
+# include <byteswap.h>
|
|
|
4728c8 |
+#else
|
|
|
4728c8 |
+# error unsupported
|
|
|
4728c8 |
+#endif
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#if BYTE_ORDER == LITTLE_ENDIAN
|
|
|
4728c8 |
+# define le16_to_cpu(x) (x)
|
|
|
4728c8 |
+# define be16_to_cpu(x) bswap_16(x)
|
|
|
4728c8 |
+# define le32_to_cpu(x) (x)
|
|
|
4728c8 |
+# define le64_to_cpu(x) (x)
|
|
|
4728c8 |
+# define be32_to_cpu(x) bswap_32(x)
|
|
|
4728c8 |
+# define be64_to_cpu(x) bswap_64(x)
|
|
|
4728c8 |
+#elif BYTE_ORDER == BIG_ENDIAN
|
|
|
4728c8 |
+# define le16_to_cpu(x) bswap_16(x)
|
|
|
4728c8 |
+# define be16_to_cpu(x) (x)
|
|
|
4728c8 |
+# define le32_to_cpu(x) bswap_32(x)
|
|
|
4728c8 |
+# define le64_to_cpu(x) bswap_64(x)
|
|
|
4728c8 |
+# define be32_to_cpu(x) (x)
|
|
|
4728c8 |
+# define be64_to_cpu(x) (x)
|
|
|
4728c8 |
+#else
|
|
|
4728c8 |
+# error unsupported
|
|
|
4728c8 |
+#endif
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#define cpu_to_le16(x) le16_to_cpu(x)
|
|
|
4728c8 |
+#define cpu_to_be16(x) be16_to_cpu(x)
|
|
|
4728c8 |
+#define cpu_to_le32(x) le32_to_cpu(x)
|
|
|
4728c8 |
+#define cpu_to_be32(x) be32_to_cpu(x)
|
|
|
4728c8 |
+#define cpu_to_le64(x) le64_to_cpu(x)
|
|
|
4728c8 |
+#define cpu_to_be64(x) be64_to_cpu(x)
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+struct be64 {
|
|
|
4728c8 |
+ uint64_t _v;
|
|
|
4728c8 |
+};
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#define get_be64(x) be64_to_cpu((x)._v)
|
|
|
4728c8 |
+#define put_be64(x, y) do { (x)._v = cpu_to_be64(y); } while (0)
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#endif /* BYTEORDER_H_INCLUDED */
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/checkers/rbd.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/checkers/rbd.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/checkers/rbd.c
|
|
|
4728c8 |
@@ -27,6 +27,7 @@
|
|
|
4728c8 |
|
|
|
4728c8 |
#include "../libmultipath/debug.h"
|
|
|
4728c8 |
#include "../libmultipath/uevent.h"
|
|
|
4728c8 |
+#include "../libmultipath/util.h"
|
|
|
4728c8 |
|
|
|
4728c8 |
struct rbd_checker_context;
|
|
|
4728c8 |
typedef int (thread_fn)(struct rbd_checker_context *ct, char *msg);
|
|
|
4728c8 |
@@ -355,21 +356,6 @@ int rbd_check(struct rbd_checker_context
|
|
|
4728c8 |
return PATH_UP;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
-int safe_write(int fd, const void *buf, size_t count)
|
|
|
4728c8 |
-{
|
|
|
4728c8 |
- while (count > 0) {
|
|
|
4728c8 |
- ssize_t r = write(fd, buf, count);
|
|
|
4728c8 |
- if (r < 0) {
|
|
|
4728c8 |
- if (errno == EINTR)
|
|
|
4728c8 |
- continue;
|
|
|
4728c8 |
- return -errno;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
- count -= r;
|
|
|
4728c8 |
- buf = (char *)buf + r;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
- return 0;
|
|
|
4728c8 |
-}
|
|
|
4728c8 |
-
|
|
|
4728c8 |
static int sysfs_write_rbd_bus(const char *which, const char *buf,
|
|
|
4728c8 |
size_t buf_len)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/config.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/config.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/config.c
|
|
|
4728c8 |
@@ -574,6 +574,9 @@ free_config (struct config * conf)
|
|
|
4728c8 |
if (conf->wwids_file)
|
|
|
4728c8 |
FREE(conf->wwids_file);
|
|
|
4728c8 |
|
|
|
4728c8 |
+ if (conf->prkeys_file)
|
|
|
4728c8 |
+ FREE(conf->prkeys_file);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
if (conf->prio_name)
|
|
|
4728c8 |
FREE(conf->prio_name);
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -589,9 +592,6 @@ free_config (struct config * conf)
|
|
|
4728c8 |
if (conf->config_dir)
|
|
|
4728c8 |
FREE(conf->config_dir);
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (conf->reservation_key)
|
|
|
4728c8 |
- FREE(conf->reservation_key);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
free_blacklist(conf->blist_devnode);
|
|
|
4728c8 |
free_blacklist(conf->blist_wwid);
|
|
|
4728c8 |
free_blacklist_device(conf->blist_device);
|
|
|
4728c8 |
@@ -666,6 +666,7 @@ load_config (char * file, struct udev *u
|
|
|
4728c8 |
get_sys_max_fds(&conf->max_fds);
|
|
|
4728c8 |
conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
|
|
|
4728c8 |
conf->wwids_file = set_default(DEFAULT_WWIDS_FILE);
|
|
|
4728c8 |
+ conf->prkeys_file = set_default(DEFAULT_PRKEYS_FILE);
|
|
|
4728c8 |
conf->bindings_read_only = 0;
|
|
|
4728c8 |
conf->multipath_dir = set_default(DEFAULT_MULTIPATHDIR);
|
|
|
4728c8 |
conf->features = set_default(DEFAULT_FEATURES);
|
|
|
4728c8 |
@@ -806,7 +807,7 @@ load_config (char * file, struct udev *u
|
|
|
4728c8 |
conf->bindings_file = set_default(DEFAULT_BINDINGS_FILE);
|
|
|
4728c8 |
|
|
|
4728c8 |
if (!conf->multipath_dir || !conf->bindings_file ||
|
|
|
4728c8 |
- !conf->wwids_file)
|
|
|
4728c8 |
+ !conf->wwids_file || !conf->prkeys_file)
|
|
|
4728c8 |
goto out;
|
|
|
4728c8 |
|
|
|
4728c8 |
if (conf->ignore_new_boot_devs)
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/config.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/config.h
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/config.h
|
|
|
4728c8 |
@@ -3,6 +3,8 @@
|
|
|
4728c8 |
|
|
|
4728c8 |
#include <sys/types.h>
|
|
|
4728c8 |
#include <stdint.h>
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
+#include "byteorder.h"
|
|
|
4728c8 |
|
|
|
4728c8 |
#define ORIGIN_DEFAULT 0
|
|
|
4728c8 |
#define ORIGIN_CONFIG 1
|
|
|
4728c8 |
@@ -80,7 +82,8 @@ struct mpentry {
|
|
|
4728c8 |
|
|
|
4728c8 |
char * prio_name;
|
|
|
4728c8 |
char * prio_args;
|
|
|
4728c8 |
- unsigned char * reservation_key;
|
|
|
4728c8 |
+ int prkey_source;
|
|
|
4728c8 |
+ struct be64 reservation_key;
|
|
|
4728c8 |
int pgpolicy;
|
|
|
4728c8 |
int pgfailback;
|
|
|
4728c8 |
int rr_weight;
|
|
|
4728c8 |
@@ -167,12 +170,14 @@ struct config {
|
|
|
4728c8 |
char * hwhandler;
|
|
|
4728c8 |
char * bindings_file;
|
|
|
4728c8 |
char * wwids_file;
|
|
|
4728c8 |
+ char * prkeys_file;
|
|
|
4728c8 |
char * prio_name;
|
|
|
4728c8 |
char * prio_args;
|
|
|
4728c8 |
char * checker_name;
|
|
|
4728c8 |
char * alias_prefix;
|
|
|
4728c8 |
char * config_dir;
|
|
|
4728c8 |
- unsigned char * reservation_key;
|
|
|
4728c8 |
+ int prkey_source;
|
|
|
4728c8 |
+ struct be64 reservation_key;
|
|
|
4728c8 |
|
|
|
4728c8 |
vector keywords;
|
|
|
4728c8 |
vector mptable;
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/defaults.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/defaults.h
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/defaults.h
|
|
|
4728c8 |
@@ -39,6 +39,7 @@
|
|
|
4728c8 |
#define DEFAULT_CONFIGFILE "/etc/multipath.conf"
|
|
|
4728c8 |
#define DEFAULT_BINDINGS_FILE "/etc/multipath/bindings"
|
|
|
4728c8 |
#define DEFAULT_WWIDS_FILE "/etc/multipath/wwids"
|
|
|
4728c8 |
+#define DEFAULT_PRKEYS_FILE "/etc/multipath/prkeys"
|
|
|
4728c8 |
#define DEFAULT_CONFIG_DIR "/etc/multipath/conf.d"
|
|
|
4728c8 |
|
|
|
4728c8 |
char * set_default (char * str);
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/dict.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/dict.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/dict.c
|
|
|
4728c8 |
@@ -20,6 +20,8 @@
|
|
|
4728c8 |
#include "defaults.h"
|
|
|
4728c8 |
#include "prio.h"
|
|
|
4728c8 |
#include "errno.h"
|
|
|
4728c8 |
+#include "util.h"
|
|
|
4728c8 |
+#include "prkey.h"
|
|
|
4728c8 |
#include <inttypes.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
/*
|
|
|
4728c8 |
@@ -554,46 +556,26 @@ static int
|
|
|
4728c8 |
def_reservation_key_handler(vector strvec)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
char *buff;
|
|
|
4728c8 |
- char *tbuff;
|
|
|
4728c8 |
- int j, k;
|
|
|
4728c8 |
- int len;
|
|
|
4728c8 |
- uint64_t prkey;
|
|
|
4728c8 |
+ uint64_t prkey = 0;
|
|
|
4728c8 |
|
|
|
4728c8 |
buff = set_value(strvec);
|
|
|
4728c8 |
if (!buff)
|
|
|
4728c8 |
return 1;
|
|
|
4728c8 |
|
|
|
4728c8 |
- tbuff = buff;
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- if (!memcmp("0x",buff, 2))
|
|
|
4728c8 |
- buff = buff + 2;
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- len = strlen(buff);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- k = strspn(buff, "0123456789aAbBcCdDeEfF");
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- if (len != k) {
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
- return 1;
|
|
|
4728c8 |
+ if (strlen(buff) == 4 && !strcmp(buff, "file")) {
|
|
|
4728c8 |
+ conf->prkey_source = PRKEY_SOURCE_FILE;
|
|
|
4728c8 |
+ put_be64(conf->reservation_key, 0);
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- if (1 != sscanf (buff, "%" SCNx64 "", &prkey))
|
|
|
4728c8 |
- {
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
+ else if (parse_prkey(buff, &prkey) != 0) {
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
return 1;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!conf->reservation_key)
|
|
|
4728c8 |
- conf->reservation_key = (unsigned char *) malloc(8);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- memset(conf->reservation_key, 0, 8);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- for (j = 7; j >= 0; --j) {
|
|
|
4728c8 |
- conf->reservation_key[j] = (prkey & 0xff);
|
|
|
4728c8 |
- prkey >>= 8;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
+ conf->prkey_source = PRKEY_SOURCE_CONF;
|
|
|
4728c8 |
+ put_be64(conf->reservation_key, prkey);
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -668,6 +650,19 @@ wwids_file_handler(vector strvec)
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
static int
|
|
|
4728c8 |
+prkeys_file_handler(vector strvec)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ if (conf->prkeys_file)
|
|
|
4728c8 |
+ FREE(conf->prkeys_file);
|
|
|
4728c8 |
+ conf->prkeys_file = set_value(strvec);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!conf->prkeys_file)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+static int
|
|
|
4728c8 |
def_retain_hwhandler_handler(vector strvec)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
char * buff;
|
|
|
4728c8 |
@@ -2282,10 +2277,7 @@ static int
|
|
|
4728c8 |
mp_reservation_key_handler (vector strvec)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
char *buff;
|
|
|
4728c8 |
- char *tbuff;
|
|
|
4728c8 |
struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- int j, k, len;
|
|
|
4728c8 |
uint64_t prkey;
|
|
|
4728c8 |
|
|
|
4728c8 |
if (!mpe)
|
|
|
4728c8 |
@@ -2295,35 +2287,20 @@ mp_reservation_key_handler (vector strve
|
|
|
4728c8 |
if (!buff)
|
|
|
4728c8 |
return 1;
|
|
|
4728c8 |
|
|
|
4728c8 |
- tbuff = buff;
|
|
|
4728c8 |
- if (!memcmp(buff, "0x", 2))
|
|
|
4728c8 |
- buff = buff + 2;
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- len = strlen(buff);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- k = strspn(buff, "0123456789aAbBcCdDeEfF");
|
|
|
4728c8 |
- if (len != k) {
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
- return 1;
|
|
|
4728c8 |
+ if (strlen(buff) == 4 && !strcmp(buff, "file")) {
|
|
|
4728c8 |
+ mpe->prkey_source = PRKEY_SOURCE_FILE;
|
|
|
4728c8 |
+ put_be64(mpe->reservation_key, 0);
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- if (1 != sscanf (buff, "%" SCNx64 "", &prkey))
|
|
|
4728c8 |
- {
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
+ else if (parse_prkey(buff, &prkey) != 0) {
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
return 1;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!mpe->reservation_key)
|
|
|
4728c8 |
- mpe->reservation_key = (unsigned char *) malloc(8);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- memset(mpe->reservation_key, 0, 8);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- for (j = 7; j >= 0; --j) {
|
|
|
4728c8 |
- mpe->reservation_key[j] = (prkey & 0xff);
|
|
|
4728c8 |
- prkey >>= 8;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- FREE(tbuff);
|
|
|
4728c8 |
+ mpe->prkey_source = PRKEY_SOURCE_CONF;
|
|
|
4728c8 |
+ put_be64(mpe->reservation_key, prkey);
|
|
|
4728c8 |
+ FREE(buff);
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -2714,22 +2691,14 @@ snprint_mp_prio_args(char * buff, int le
|
|
|
4728c8 |
static int
|
|
|
4728c8 |
snprint_mp_reservation_key (char * buff, int len, void * data)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
- int i;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey = 0;
|
|
|
4728c8 |
struct mpentry * mpe = (struct mpentry *)data;
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!mpe->reservation_key)
|
|
|
4728c8 |
+ if (mpe->prkey_source == PRKEY_SOURCE_NONE)
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
- keyp = (unsigned char *)mpe->reservation_key;
|
|
|
4728c8 |
- for (i = 0; i < 8; i++) {
|
|
|
4728c8 |
- if (i > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- keyp++;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- return snprintf(buff, len, "0x%" PRIx64, prkey);
|
|
|
4728c8 |
+ if (mpe->prkey_source == PRKEY_SOURCE_FILE)
|
|
|
4728c8 |
+ return snprintf(buff, len, "file");
|
|
|
4728c8 |
+ return snprintf(buff, len, "0x%" PRIx64,
|
|
|
4728c8 |
+ get_be64(mpe->reservation_key));
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
static int
|
|
|
4728c8 |
@@ -3551,22 +3520,22 @@ snprint_def_wwids_file (char * buff, int
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
static int
|
|
|
4728c8 |
-snprint_def_reservation_key(char * buff, int len, void * data)
|
|
|
4728c8 |
+snprint_def_prkeys_file (char * buff, int len, void * data)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
- int i;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey = 0;
|
|
|
4728c8 |
+ if (conf->prkeys_file == NULL)
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ return snprintf(buff, len, "%s", conf->prkeys_file);
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!conf->reservation_key)
|
|
|
4728c8 |
+static int
|
|
|
4728c8 |
+snprint_def_reservation_key(char * buff, int len, void * data)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ if (conf->prkey_source == PRKEY_SOURCE_NONE)
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
- keyp = (unsigned char *)conf->reservation_key;
|
|
|
4728c8 |
- for (i = 0; i < 8; i++) {
|
|
|
4728c8 |
- if (i > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- keyp++;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
- return snprintf(buff, len, "0x%" PRIx64, prkey);
|
|
|
4728c8 |
+ if (conf->prkey_source == PRKEY_SOURCE_FILE)
|
|
|
4728c8 |
+ return snprintf(buff, len, "file");
|
|
|
4728c8 |
+ return snprintf(buff, len, "0x%" PRIx64,
|
|
|
4728c8 |
+ get_be64(conf->reservation_key));
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
static int
|
|
|
4728c8 |
@@ -3788,6 +3757,7 @@ init_keywords(void)
|
|
|
4728c8 |
install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
|
|
|
4728c8 |
install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
|
|
|
4728c8 |
install_keyword("wwids_file", &wwids_file_handler, &snprint_def_wwids_file);
|
|
|
4728c8 |
+ install_keyword("prkeys_file", &prkeys_file_handler, &snprint_def_prkeys_file);
|
|
|
4728c8 |
install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
|
|
|
4728c8 |
install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
|
|
|
4728c8 |
install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/prkey.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- /dev/null
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/prkey.c
|
|
|
4728c8 |
@@ -0,0 +1,167 @@
|
|
|
4728c8 |
+#include "prkey.h"
|
|
|
4728c8 |
+#include "structs.h"
|
|
|
4728c8 |
+#include "file.h"
|
|
|
4728c8 |
+#include "debug.h"
|
|
|
4728c8 |
+#include "config.h"
|
|
|
4728c8 |
+#include "util.h"
|
|
|
4728c8 |
+#include "propsel.h"
|
|
|
4728c8 |
+#include <sys/types.h>
|
|
|
4728c8 |
+#include <unistd.h>
|
|
|
4728c8 |
+#include <stdio.h>
|
|
|
4728c8 |
+#include <string.h>
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
+#include <errno.h>
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#define KEYSIZE 19
|
|
|
4728c8 |
+#define PRKEY_READ 0
|
|
|
4728c8 |
+#define PRKEY_WRITE 1
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+static int do_prkey(int fd, char *wwid, char *keystr, int cmd)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ char buf[4097];
|
|
|
4728c8 |
+ char *ptr;
|
|
|
4728c8 |
+ off_t start = 0;
|
|
|
4728c8 |
+ int bytes;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ while (1) {
|
|
|
4728c8 |
+ if (lseek(fd, start, SEEK_SET) < 0) {
|
|
|
4728c8 |
+ condlog(0, "prkey file read lseek failed : %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ bytes = read(fd, buf, 4096);
|
|
|
4728c8 |
+ if (bytes < 0) {
|
|
|
4728c8 |
+ if (errno == EINTR || errno == EAGAIN)
|
|
|
4728c8 |
+ continue;
|
|
|
4728c8 |
+ condlog(0, "failed to read from prkey file : %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (!bytes) {
|
|
|
4728c8 |
+ ptr = NULL;
|
|
|
4728c8 |
+ break;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ buf[bytes] = '\0';
|
|
|
4728c8 |
+ ptr = strstr(buf, wwid);
|
|
|
4728c8 |
+ while (ptr) {
|
|
|
4728c8 |
+ if (ptr == buf || *(ptr - 1) != ' ' ||
|
|
|
4728c8 |
+ *(ptr + strlen(wwid)) != '\n')
|
|
|
4728c8 |
+ ptr = strstr(ptr + strlen(wwid), wwid);
|
|
|
4728c8 |
+ else
|
|
|
4728c8 |
+ break;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (ptr) {
|
|
|
4728c8 |
+ condlog(3, "found prkey for '%s'", wwid);
|
|
|
4728c8 |
+ ptr[strlen(wwid)] = '\0';
|
|
|
4728c8 |
+ if (ptr - KEYSIZE < buf ||
|
|
|
4728c8 |
+ (ptr - KEYSIZE != buf &&
|
|
|
4728c8 |
+ *(ptr - KEYSIZE - 1) != '\n')) {
|
|
|
4728c8 |
+ condlog(0, "malformed prkey file line for wwid: '%s'", ptr);
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ ptr = ptr - KEYSIZE;
|
|
|
4728c8 |
+ break;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ ptr = strrchr(buf, '\n');
|
|
|
4728c8 |
+ if (ptr == NULL) {
|
|
|
4728c8 |
+ condlog(4, "couldn't file newline, assuming end of file");
|
|
|
4728c8 |
+ break;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ start = start + (ptr - buf) + 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (cmd == PRKEY_READ) {
|
|
|
4728c8 |
+ if (!ptr || *ptr == '#')
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ memcpy(keystr, ptr, KEYSIZE - 1);
|
|
|
4728c8 |
+ keystr[KEYSIZE - 1] = '\0';
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (!ptr && !keystr)
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ if (ptr) {
|
|
|
4728c8 |
+ if (lseek(fd, start + (ptr - buf), SEEK_SET) < 0) {
|
|
|
4728c8 |
+ condlog(0, "prkey write lseek failed : %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (!keystr) {
|
|
|
4728c8 |
+ if (safe_write(fd, "#", 1) < 0) {
|
|
|
4728c8 |
+ condlog(0, "failed to write to prkey file : %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (!ptr) {
|
|
|
4728c8 |
+ if (lseek(fd, 0, SEEK_END) < 0) {
|
|
|
4728c8 |
+ condlog(0, "prkey write lseek failed : %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ bytes = sprintf(buf, "%s %s\n", keystr, wwid);
|
|
|
4728c8 |
+ if (safe_write(fd, buf, bytes) < 0) {
|
|
|
4728c8 |
+ condlog(0, "failed to write to prkey file: %s",
|
|
|
4728c8 |
+ strerror(errno));
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int get_prkey(struct multipath *mpp, uint64_t *prkey)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ int fd;
|
|
|
4728c8 |
+ int unused;
|
|
|
4728c8 |
+ int ret = 1;
|
|
|
4728c8 |
+ char keystr[KEYSIZE];
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!strlen(mpp->wwid))
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ fd = open_file(conf->prkeys_file, &unused, PRKEYS_FILE_HEADER);
|
|
|
4728c8 |
+ if (fd < 0)
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
+ ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ);
|
|
|
4728c8 |
+ if (ret)
|
|
|
4728c8 |
+ goto out_file;
|
|
|
4728c8 |
+ ret = !!parse_prkey(keystr, prkey);
|
|
|
4728c8 |
+out_file:
|
|
|
4728c8 |
+ close(fd);
|
|
|
4728c8 |
+out:
|
|
|
4728c8 |
+ return ret;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int set_prkey(struct multipath *mpp, uint64_t prkey)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ int fd;
|
|
|
4728c8 |
+ int can_write = 1;
|
|
|
4728c8 |
+ int ret = 1;
|
|
|
4728c8 |
+ char keystr[KEYSIZE];
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!strlen(mpp->wwid))
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER);
|
|
|
4728c8 |
+ if (fd < 0)
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
+ if (!can_write) {
|
|
|
4728c8 |
+ condlog(0, "cannot set prkey, prkeys file is read-only");
|
|
|
4728c8 |
+ goto out_file;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (prkey) {
|
|
|
4728c8 |
+ snprintf(keystr, KEYSIZE, "0x%016" PRIx64, prkey);
|
|
|
4728c8 |
+ keystr[KEYSIZE - 1] = '\0';
|
|
|
4728c8 |
+ ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_WRITE);
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ else
|
|
|
4728c8 |
+ ret = do_prkey(fd, mpp->wwid, NULL, PRKEY_WRITE);
|
|
|
4728c8 |
+ if (ret == 0)
|
|
|
4728c8 |
+ select_reservation_key(mpp);
|
|
|
4728c8 |
+ if (get_be64(mpp->reservation_key) != prkey)
|
|
|
4728c8 |
+ ret = 1;
|
|
|
4728c8 |
+out_file:
|
|
|
4728c8 |
+ close(fd);
|
|
|
4728c8 |
+out:
|
|
|
4728c8 |
+ return ret;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/prkey.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- /dev/null
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/prkey.h
|
|
|
4728c8 |
@@ -0,0 +1,19 @@
|
|
|
4728c8 |
+#ifndef _PRKEY_H
|
|
|
4728c8 |
+#define _PRKEY_H
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#include "structs.h"
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#define PRKEYS_FILE_HEADER \
|
|
|
4728c8 |
+"# Multipath persistent reservation keys, Version : 1.0\n" \
|
|
|
4728c8 |
+"# NOTE: this file is automatically maintained by the multipathd program.\n" \
|
|
|
4728c8 |
+"# You should not need to edit this file in normal circumstances.\n" \
|
|
|
4728c8 |
+"#\n" \
|
|
|
4728c8 |
+"# Format:\n" \
|
|
|
4728c8 |
+"# prkey wwid\n" \
|
|
|
4728c8 |
+"#\n"
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int set_prkey(struct multipath *mpp, uint64_t prkey);
|
|
|
4728c8 |
+int get_prkey(struct multipath *mpp, uint64_t *prkey);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+#endif /* _PRKEY_H */
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/propsel.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/propsel.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/propsel.c
|
|
|
4728c8 |
@@ -18,6 +18,7 @@
|
|
|
4728c8 |
#include "prio.h"
|
|
|
4728c8 |
#include "discovery.h"
|
|
|
4728c8 |
#include "prioritizers/alua_rtpg.h"
|
|
|
4728c8 |
+#include "prkey.h"
|
|
|
4728c8 |
#include <inttypes.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
pgpolicyfn *pgpolicies[] = {
|
|
|
4728c8 |
@@ -711,44 +712,39 @@ select_flush_on_last_del(struct multipat
|
|
|
4728c8 |
extern int
|
|
|
4728c8 |
select_reservation_key (struct multipath * mp)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
- int j;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey = 0;
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- mp->reservation_key = NULL;
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- if (mp->mpe && mp->mpe->reservation_key) {
|
|
|
4728c8 |
- keyp = mp->mpe->reservation_key;
|
|
|
4728c8 |
- for (j = 0; j < 8; ++j) {
|
|
|
4728c8 |
- if (j > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- ++keyp;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- condlog(3, "%s: reservation_key = 0x%" PRIx64 " "
|
|
|
4728c8 |
- "(multipath setting)", mp->alias, prkey);
|
|
|
4728c8 |
+ uint64_t prkey;
|
|
|
4728c8 |
+ char *origin = NULL;
|
|
|
4728c8 |
+ char *from_file = "";
|
|
|
4728c8 |
|
|
|
4728c8 |
+ if (mp->mpe && mp->mpe->prkey_source != PRKEY_SOURCE_NONE) {
|
|
|
4728c8 |
+ mp->prkey_source = mp->mpe->prkey_source;
|
|
|
4728c8 |
mp->reservation_key = mp->mpe->reservation_key;
|
|
|
4728c8 |
- return 0;
|
|
|
4728c8 |
+ origin = "multipath setting";
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (conf->reservation_key) {
|
|
|
4728c8 |
- keyp = conf->reservation_key;
|
|
|
4728c8 |
- for (j = 0; j < 8; ++j) {
|
|
|
4728c8 |
- if (j > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- ++keyp;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- condlog(3, "%s: reservation_key = 0x%" PRIx64
|
|
|
4728c8 |
- " (config file default)", mp->alias, prkey);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
+ if (conf->prkey_source != PRKEY_SOURCE_NONE) {
|
|
|
4728c8 |
+ mp->prkey_source = conf->prkey_source;
|
|
|
4728c8 |
mp->reservation_key = conf->reservation_key;
|
|
|
4728c8 |
- return 0;
|
|
|
4728c8 |
+ origin = "config file default";
|
|
|
4728c8 |
+ goto out;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
+ put_be64(mp->reservation_key, 0);
|
|
|
4728c8 |
+ mp->prkey_source = PRKEY_SOURCE_NONE;
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+out:
|
|
|
4728c8 |
+ if (mp->prkey_source == PRKEY_SOURCE_FILE) {
|
|
|
4728c8 |
+ from_file = " (from prkeys file)";
|
|
|
4728c8 |
+ if (get_prkey(mp, &prkey) != 0)
|
|
|
4728c8 |
+ put_be64(mp->reservation_key, 0);
|
|
|
4728c8 |
+ else
|
|
|
4728c8 |
+ put_be64(mp->reservation_key, prkey);
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ if (get_be64(mp->reservation_key))
|
|
|
4728c8 |
+ condlog(0, "%s: reservation_key = 0x%" PRIx64 " (%s)%s",
|
|
|
4728c8 |
+ mp->alias, get_be64(mp->reservation_key), origin,
|
|
|
4728c8 |
+ from_file);
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/structs.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/structs.h
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/structs.h
|
|
|
4728c8 |
@@ -2,8 +2,10 @@
|
|
|
4728c8 |
#define _STRUCTS_H
|
|
|
4728c8 |
|
|
|
4728c8 |
#include <sys/types.h>
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
#include "prio.h"
|
|
|
4728c8 |
+#include "byteorder.h"
|
|
|
4728c8 |
|
|
|
4728c8 |
#define WWID_SIZE 128
|
|
|
4728c8 |
#define SERIAL_SIZE 65
|
|
|
4728c8 |
@@ -27,7 +29,6 @@
|
|
|
4728c8 |
#define NO_PATH_RETRY_FAIL -1
|
|
|
4728c8 |
#define NO_PATH_RETRY_QUEUE -2
|
|
|
4728c8 |
|
|
|
4728c8 |
-
|
|
|
4728c8 |
enum free_path_mode {
|
|
|
4728c8 |
KEEP_PATHS,
|
|
|
4728c8 |
FREE_PATHS
|
|
|
4728c8 |
@@ -169,6 +170,12 @@ enum missing_udev_info_states {
|
|
|
4728c8 |
INFO_REQUESTED,
|
|
|
4728c8 |
};
|
|
|
4728c8 |
|
|
|
4728c8 |
+enum prkey_sources {
|
|
|
4728c8 |
+ PRKEY_SOURCE_NONE,
|
|
|
4728c8 |
+ PRKEY_SOURCE_CONF,
|
|
|
4728c8 |
+ PRKEY_SOURCE_FILE,
|
|
|
4728c8 |
+};
|
|
|
4728c8 |
+
|
|
|
4728c8 |
struct sg_id {
|
|
|
4728c8 |
int host_no;
|
|
|
4728c8 |
int channel;
|
|
|
4728c8 |
@@ -298,8 +305,9 @@ struct multipath {
|
|
|
4728c8 |
/* checkers shared data */
|
|
|
4728c8 |
void * mpcontext;
|
|
|
4728c8 |
|
|
|
4728c8 |
- /* persistent management data*/
|
|
|
4728c8 |
- unsigned char * reservation_key;
|
|
|
4728c8 |
+ /* persistent management data */
|
|
|
4728c8 |
+ int prkey_source;
|
|
|
4728c8 |
+ struct be64 reservation_key;
|
|
|
4728c8 |
unsigned char prflag;
|
|
|
4728c8 |
};
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/util.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/util.c
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/util.c
|
|
|
4728c8 |
@@ -5,12 +5,14 @@
|
|
|
4728c8 |
#include <unistd.h>
|
|
|
4728c8 |
#include <sys/vfs.h>
|
|
|
4728c8 |
#include <linux/magic.h>
|
|
|
4728c8 |
+#include <errno.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
#include "debug.h"
|
|
|
4728c8 |
#include "memory.h"
|
|
|
4728c8 |
#include "checkers.h"
|
|
|
4728c8 |
#include "vector.h"
|
|
|
4728c8 |
#include "structs.h"
|
|
|
4728c8 |
+#include "util.h"
|
|
|
4728c8 |
|
|
|
4728c8 |
void
|
|
|
4728c8 |
strchop(char *str)
|
|
|
4728c8 |
@@ -297,3 +299,35 @@ int in_initrd(void) {
|
|
|
4728c8 |
|
|
|
4728c8 |
return saved;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int parse_prkey(char *ptr, uint64_t *prkey)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ if (!ptr)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ if (*ptr == '0')
|
|
|
4728c8 |
+ ptr++;
|
|
|
4728c8 |
+ if (*ptr == 'x' || *ptr == 'X')
|
|
|
4728c8 |
+ ptr++;
|
|
|
4728c8 |
+ if (*ptr == '\0' || strlen(ptr) > 16)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ if (strlen(ptr) != strspn(ptr, "0123456789aAbBcCdDeEfF"))
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ if (sscanf(ptr, "%" SCNx64 "", prkey) != 1)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int safe_write(int fd, const void *buf, size_t count)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ while (count > 0) {
|
|
|
4728c8 |
+ ssize_t r = write(fd, buf, count);
|
|
|
4728c8 |
+ if (r < 0) {
|
|
|
4728c8 |
+ if (errno == EINTR || errno == EAGAIN)
|
|
|
4728c8 |
+ continue;
|
|
|
4728c8 |
+ return -errno;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ count -= r;
|
|
|
4728c8 |
+ buf = (char *)buf + r;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/util.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/util.h
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/util.h
|
|
|
4728c8 |
@@ -1,6 +1,8 @@
|
|
|
4728c8 |
#ifndef _UTIL_H
|
|
|
4728c8 |
#define _UTIL_H
|
|
|
4728c8 |
|
|
|
4728c8 |
+#include <inttypes.h>
|
|
|
4728c8 |
+
|
|
|
4728c8 |
void strchop(char *);
|
|
|
4728c8 |
int basenamecpy (const char * src, char * dst, int);
|
|
|
4728c8 |
int filepresent (char * run);
|
|
|
4728c8 |
@@ -12,6 +14,8 @@ int devt2devname (char *, int, char *);
|
|
|
4728c8 |
dev_t parse_devt(const char *dev_t);
|
|
|
4728c8 |
char *convert_dev(char *dev, int is_path_device);
|
|
|
4728c8 |
int in_initrd(void);
|
|
|
4728c8 |
+int parse_prkey(char *ptr, uint64_t *prkey);
|
|
|
4728c8 |
+int safe_write(int fd, const void *buf, size_t count);
|
|
|
4728c8 |
|
|
|
4728c8 |
#define safe_sprintf(var, format, args...) \
|
|
|
4728c8 |
snprintf(var, sizeof(var), format, ##args) >= sizeof(var)
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/cli.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/cli.c
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/cli.c
|
|
|
4728c8 |
@@ -190,6 +190,10 @@ load_keys (void)
|
|
|
4728c8 |
r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0);
|
|
|
4728c8 |
r += add_key(keys, "format", FMT, 1);
|
|
|
4728c8 |
r += add_key(keys, "json", JSON, 0);
|
|
|
4728c8 |
+ r += add_key(keys, "getprkey", GETPRKEY, 0);
|
|
|
4728c8 |
+ r += add_key(keys, "setprkey", SETPRKEY, 0);
|
|
|
4728c8 |
+ r += add_key(keys, "unsetprkey", UNSETPRKEY, 0);
|
|
|
4728c8 |
+ r += add_key(keys, "key", KEY, 1);
|
|
|
4728c8 |
|
|
|
4728c8 |
if (r) {
|
|
|
4728c8 |
free_keys(keys);
|
|
|
4728c8 |
@@ -506,6 +510,9 @@ cli_init (void) {
|
|
|
4728c8 |
add_handler(GETPRSTATUS+MAP, NULL);
|
|
|
4728c8 |
add_handler(SETPRSTATUS+MAP, NULL);
|
|
|
4728c8 |
add_handler(UNSETPRSTATUS+MAP, NULL);
|
|
|
4728c8 |
+ add_handler(GETPRKEY+MAP, NULL);
|
|
|
4728c8 |
+ add_handler(SETPRKEY+MAP+KEY, NULL);
|
|
|
4728c8 |
+ add_handler(UNSETPRKEY+MAP, NULL);
|
|
|
4728c8 |
add_handler(FORCEQ+DAEMON, NULL);
|
|
|
4728c8 |
add_handler(RESTOREQ+DAEMON, NULL);
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/cli.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/cli.h
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/cli.h
|
|
|
4728c8 |
@@ -37,6 +37,10 @@ enum {
|
|
|
4728c8 |
__UNSETPRSTATUS,
|
|
|
4728c8 |
__FMT,
|
|
|
4728c8 |
__JSON,
|
|
|
4728c8 |
+ __GETPRKEY,
|
|
|
4728c8 |
+ __SETPRKEY,
|
|
|
4728c8 |
+ __UNSETPRKEY,
|
|
|
4728c8 |
+ __KEY,
|
|
|
4728c8 |
};
|
|
|
4728c8 |
|
|
|
4728c8 |
#define LIST (1 << __LIST)
|
|
|
4728c8 |
@@ -76,6 +80,10 @@ enum {
|
|
|
4728c8 |
#define UNSETPRSTATUS (1ULL << __UNSETPRSTATUS)
|
|
|
4728c8 |
#define FMT (1ULL << __FMT)
|
|
|
4728c8 |
#define JSON (1ULL << __JSON)
|
|
|
4728c8 |
+#define GETPRKEY (1ULL << __GETPRKEY)
|
|
|
4728c8 |
+#define SETPRKEY (1ULL << __SETPRKEY)
|
|
|
4728c8 |
+#define UNSETPRKEY (1ULL << __UNSETPRKEY)
|
|
|
4728c8 |
+#define KEY (1ULL << __KEY)
|
|
|
4728c8 |
|
|
|
4728c8 |
#define INITIAL_REPLY_LEN 1200
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/cli_handlers.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/cli_handlers.c
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/cli_handlers.c
|
|
|
4728c8 |
@@ -18,6 +18,7 @@
|
|
|
4728c8 |
#include <errno.h>
|
|
|
4728c8 |
#include <libudev.h>
|
|
|
4728c8 |
#include <util.h>
|
|
|
4728c8 |
+#include <prkey.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
#include "main.h"
|
|
|
4728c8 |
#include "cli.h"
|
|
|
4728c8 |
@@ -1234,3 +1235,71 @@ cli_unsetprstatus(void * v, char ** repl
|
|
|
4728c8 |
|
|
|
4728c8 |
return 0;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int
|
|
|
4728c8 |
+cli_getprkey(void * v, char ** reply, int * len, void * data)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ struct multipath * mpp;
|
|
|
4728c8 |
+ struct vectors * vecs = (struct vectors *)data;
|
|
|
4728c8 |
+ char *mapname = get_keyparam(v, MAP);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ mapname = convert_dev(mapname, 0);
|
|
|
4728c8 |
+ condlog(3, "%s: get persistent reservation key (operator)", mapname);
|
|
|
4728c8 |
+ mpp = find_mp_by_str(vecs->mpvec, mapname);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!mpp)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ *reply = malloc(20);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!get_be64(mpp->reservation_key)) {
|
|
|
4728c8 |
+ sprintf(*reply, "none\n");
|
|
|
4728c8 |
+ *len = strlen(*reply) + 1;
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+ snprintf(*reply, 20, "0x%" PRIx64 "\n",
|
|
|
4728c8 |
+ get_be64(mpp->reservation_key));
|
|
|
4728c8 |
+ (*reply)[19] = '\0';
|
|
|
4728c8 |
+ *len = strlen(*reply) + 1;
|
|
|
4728c8 |
+ return 0;
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int
|
|
|
4728c8 |
+cli_unsetprkey(void * v, char ** reply, int * len, void * data)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ struct multipath * mpp;
|
|
|
4728c8 |
+ struct vectors * vecs = (struct vectors *)data;
|
|
|
4728c8 |
+ char *mapname = get_keyparam(v, MAP);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ mapname = convert_dev(mapname, 0);
|
|
|
4728c8 |
+ condlog(3, "%s: unset persistent reservation key (operator)", mapname);
|
|
|
4728c8 |
+ mpp = find_mp_by_str(vecs->mpvec, mapname);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!mpp)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ return set_prkey(mpp, 0);
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+int cli_setprkey(void * v, char ** reply, int * len, void * data)
|
|
|
4728c8 |
+{
|
|
|
4728c8 |
+ struct multipath * mpp;
|
|
|
4728c8 |
+ struct vectors * vecs = (struct vectors *)data;
|
|
|
4728c8 |
+ char *mapname = get_keyparam(v, MAP);
|
|
|
4728c8 |
+ char *keyparam = get_keyparam(v, KEY);
|
|
|
4728c8 |
+ uint64_t prkey;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ mapname = convert_dev(mapname, 0);
|
|
|
4728c8 |
+ condlog(3, "%s: set persistent reservation key (operator)", mapname);
|
|
|
4728c8 |
+ mpp = find_mp_by_str(vecs->mpvec, mapname);
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (!mpp)
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ if (parse_prkey(keyparam, &prkey) != 0) {
|
|
|
4728c8 |
+ condlog(0, "%s: invalid prkey : '%s'", mapname, keyparam);
|
|
|
4728c8 |
+ return 1;
|
|
|
4728c8 |
+ }
|
|
|
4728c8 |
+
|
|
|
4728c8 |
+ return set_prkey(mpp, prkey);
|
|
|
4728c8 |
+}
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/cli_handlers.h
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/cli_handlers.h
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/cli_handlers.h
|
|
|
4728c8 |
@@ -42,4 +42,6 @@ int cli_reassign (void * v, char ** repl
|
|
|
4728c8 |
int cli_getprstatus(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
int cli_setprstatus(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
int cli_unsetprstatus(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
-
|
|
|
4728c8 |
+int cli_getprkey(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
+int cli_setprkey(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
+int cli_unsetprkey(void * v, char ** reply, int * len, void * data);
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/main.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/main.c
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/main.c
|
|
|
4728c8 |
@@ -57,6 +57,7 @@
|
|
|
4728c8 |
#include <uevent.h>
|
|
|
4728c8 |
#include <log.h>
|
|
|
4728c8 |
#include <file.h>
|
|
|
4728c8 |
+#include <prkey.h>
|
|
|
4728c8 |
|
|
|
4728c8 |
#include "main.h"
|
|
|
4728c8 |
#include "pidfile.h"
|
|
|
4728c8 |
@@ -1050,6 +1051,9 @@ uxlsnrloop (void * ap)
|
|
|
4728c8 |
set_handler_callback(GETPRSTATUS+MAP, cli_getprstatus);
|
|
|
4728c8 |
set_handler_callback(SETPRSTATUS+MAP, cli_setprstatus);
|
|
|
4728c8 |
set_handler_callback(UNSETPRSTATUS+MAP, cli_unsetprstatus);
|
|
|
4728c8 |
+ set_handler_callback(GETPRKEY+MAP, cli_getprkey);
|
|
|
4728c8 |
+ set_handler_callback(SETPRKEY+MAP+KEY, cli_setprkey);
|
|
|
4728c8 |
+ set_handler_callback(UNSETPRKEY+MAP, cli_unsetprkey);
|
|
|
4728c8 |
set_handler_callback(FORCEQ+DAEMON, cli_force_no_daemon_q);
|
|
|
4728c8 |
set_handler_callback(RESTOREQ+DAEMON, cli_restore_no_daemon_q);
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -2266,10 +2270,8 @@ main (int argc, char *argv[])
|
|
|
4728c8 |
void * mpath_pr_event_handler_fn (void * pathp )
|
|
|
4728c8 |
{
|
|
|
4728c8 |
struct multipath * mpp;
|
|
|
4728c8 |
- int i,j, ret, isFound;
|
|
|
4728c8 |
+ int i, ret, isFound;
|
|
|
4728c8 |
struct path * pp = (struct path *)pathp;
|
|
|
4728c8 |
- unsigned char *keyp;
|
|
|
4728c8 |
- uint64_t prkey;
|
|
|
4728c8 |
struct prout_param_descriptor *param;
|
|
|
4728c8 |
struct prin_resp *resp;
|
|
|
4728c8 |
|
|
|
4728c8 |
@@ -2297,22 +2299,15 @@ void * mpath_pr_event_handler_fn (void
|
|
|
4728c8 |
ret = MPATH_PR_SUCCESS;
|
|
|
4728c8 |
goto out;
|
|
|
4728c8 |
}
|
|
|
4728c8 |
- prkey = 0;
|
|
|
4728c8 |
- keyp = (unsigned char *)mpp->reservation_key;
|
|
|
4728c8 |
- for (j = 0; j < 8; ++j) {
|
|
|
4728c8 |
- if (j > 0)
|
|
|
4728c8 |
- prkey <<= 8;
|
|
|
4728c8 |
- prkey |= *keyp;
|
|
|
4728c8 |
- ++keyp;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
- condlog(2, "Multipath reservation_key: 0x%" PRIx64 " ", prkey);
|
|
|
4728c8 |
+ condlog(2, "Multipath reservation_key: 0x%" PRIx64 " ",
|
|
|
4728c8 |
+ get_be64(mpp->reservation_key));
|
|
|
4728c8 |
|
|
|
4728c8 |
isFound =0;
|
|
|
4728c8 |
for (i = 0; i < resp->prin_descriptor.prin_readkeys.additional_length/8; i++ )
|
|
|
4728c8 |
{
|
|
|
4728c8 |
condlog(2, "PR IN READKEYS[%d] reservation key:",i);
|
|
|
4728c8 |
dumpHex((char *)&resp->prin_descriptor.prin_readkeys.key_list[i*8], 8 , -1);
|
|
|
4728c8 |
- if (!memcmp(mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
|
|
|
4728c8 |
+ if (!memcmp(&mpp->reservation_key, &resp->prin_descriptor.prin_readkeys.key_list[i*8], 8))
|
|
|
4728c8 |
{
|
|
|
4728c8 |
condlog(2, "%s: pr key found in prin readkeys response", mpp->alias);
|
|
|
4728c8 |
isFound =1;
|
|
|
4728c8 |
@@ -2329,11 +2324,7 @@ void * mpath_pr_event_handler_fn (void
|
|
|
4728c8 |
|
|
|
4728c8 |
param= malloc(sizeof(struct prout_param_descriptor));
|
|
|
4728c8 |
memset(param, 0 , sizeof(struct prout_param_descriptor));
|
|
|
4728c8 |
-
|
|
|
4728c8 |
- for (j = 7; j >= 0; --j) {
|
|
|
4728c8 |
- param->sa_key[j] = (prkey & 0xff);
|
|
|
4728c8 |
- prkey >>= 8;
|
|
|
4728c8 |
- }
|
|
|
4728c8 |
+ memcpy(param->sa_key, &mpp->reservation_key, 8);
|
|
|
4728c8 |
param->num_transportid = 0;
|
|
|
4728c8 |
|
|
|
4728c8 |
condlog(3, "device %s:%s", pp->dev, pp->mpp->wwid);
|
|
|
4728c8 |
@@ -2360,7 +2351,7 @@ int mpath_pr_event_handle(struct path *p
|
|
|
4728c8 |
|
|
|
4728c8 |
mpp = pp->mpp;
|
|
|
4728c8 |
|
|
|
4728c8 |
- if (!mpp->reservation_key)
|
|
|
4728c8 |
+ if (!get_be64(mpp->reservation_key))
|
|
|
4728c8 |
return -1;
|
|
|
4728c8 |
|
|
|
4728c8 |
pthread_attr_init(&attr);
|
|
|
4728c8 |
Index: multipath-tools-130222/libmultipath/Makefile
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/libmultipath/Makefile
|
|
|
4728c8 |
+++ multipath-tools-130222/libmultipath/Makefile
|
|
|
4728c8 |
@@ -16,7 +16,7 @@ OBJS = memory.o parser.o vector.o devmap
|
|
|
4728c8 |
pgpolicies.o debug.o regex.o defaults.o uevent.o \
|
|
|
4728c8 |
switchgroup.o uxsock.o print.o alias.o log_pthread.o \
|
|
|
4728c8 |
log.o configure.o structs_vec.o sysfs.o prio.o checkers.o \
|
|
|
4728c8 |
- lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o
|
|
|
4728c8 |
+ lock.o waiter.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o
|
|
|
4728c8 |
|
|
|
4728c8 |
LIBDM_API_FLUSH = $(shell grep -Ecs '^[a-z]*[[:space:]]+dm_task_no_flush' /usr/include/libdevmapper.h)
|
|
|
4728c8 |
|
|
|
4728c8 |
Index: multipath-tools-130222/multipath/multipath.conf.5
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipath/multipath.conf.5
|
|
|
4728c8 |
+++ multipath-tools-130222/multipath/multipath.conf.5
|
|
|
4728c8 |
@@ -414,6 +414,13 @@ of the wwids for LUNs it has created mul
|
|
|
4728c8 |
Defaults to
|
|
|
4728c8 |
.I /etc/multipath/wwids
|
|
|
4728c8 |
.TP
|
|
|
4728c8 |
+.B prkeys_file
|
|
|
4728c8 |
+The full pathname of the prkeys file, which is used by multipathd to keep
|
|
|
4728c8 |
+track of the reservation key used for a specific WWID, when
|
|
|
4728c8 |
+\fIreservation_key\fR is set to \fIfile\fR.
|
|
|
4728c8 |
+Defaults to
|
|
|
4728c8 |
+.I /etc/multipath/prkeys
|
|
|
4728c8 |
+.TP
|
|
|
4728c8 |
.B log_checker_err
|
|
|
4728c8 |
If set to
|
|
|
4728c8 |
.I once
|
|
|
4728c8 |
@@ -428,7 +435,16 @@ This is the service action reservation k
|
|
|
4728c8 |
set for all multipath devices using persistent reservations, and it must be
|
|
|
4728c8 |
the same as the RESERVATION KEY field of the PERSISTENT RESERVE OUT parameter
|
|
|
4728c8 |
list which contains an 8-byte value provided by the application client to the
|
|
|
4728c8 |
-device server to identify the I_T nexus. It is unset by default.
|
|
|
4728c8 |
+device server to identify the I_T nexus.
|
|
|
4728c8 |
+.RS
|
|
|
4728c8 |
+.PP
|
|
|
4728c8 |
+Alternatively, this can be set to \fBfile\fR, which will store the RESERVATION
|
|
|
4728c8 |
+KEY registered by mpathpersist in the \fIprkeys_file\fR. multipathd will then
|
|
|
4728c8 |
+use this key to register additional paths as they appear. When the
|
|
|
4728c8 |
+registration is removed, the RESERVATION KEY is removed from the
|
|
|
4728c8 |
+\fIprkeys_file\fR.
|
|
|
4728c8 |
+It is unset by default.
|
|
|
4728c8 |
+.RE
|
|
|
4728c8 |
.TP
|
|
|
4728c8 |
.B retain_attached_hw_handler
|
|
|
4728c8 |
If set to
|
|
|
4728c8 |
Index: multipath-tools-130222/multipathd/multipathd.8
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/multipathd/multipathd.8
|
|
|
4728c8 |
+++ multipath-tools-130222/multipathd/multipathd.8
|
|
|
4728c8 |
@@ -161,6 +161,19 @@ Disable persistent reservation managemen
|
|
|
4728c8 |
.B map|multipath $map getprstatus
|
|
|
4728c8 |
Get the current persistent reservation management status of $map
|
|
|
4728c8 |
.TP
|
|
|
4728c8 |
+.B map|multipath $map getprkey
|
|
|
4728c8 |
+Get the current persistent reservation key associated with $map.
|
|
|
4728c8 |
+.TP
|
|
|
4728c8 |
+.B map|multipath $map setprkey key $key
|
|
|
4728c8 |
+Set the persistent reservation key associated with $map to $key in the
|
|
|
4728c8 |
+\fIprkeys_file\fR. This key will only be used by multipathd if
|
|
|
4728c8 |
+\fIreservation_key\fR is set to \fIfile\fR in \fI/etc/multipath.conf\fR.
|
|
|
4728c8 |
+.TP
|
|
|
4728c8 |
+.B map|multipath $map unsetprkey
|
|
|
4728c8 |
+Remove the persistent reservation key associated with $map from the
|
|
|
4728c8 |
+\fIprkeys_file\fR. This will only unset the key used by multipathd if
|
|
|
4728c8 |
+\fIreservation_key\fR is set to \fIfile\fR in \fI/etc/multipath.conf\fR.
|
|
|
4728c8 |
+.TP
|
|
|
4728c8 |
.B quit|exit
|
|
|
4728c8 |
End interactive session.
|
|
|
4728c8 |
.TP
|
|
|
4728c8 |
Index: multipath-tools-130222/mpathpersist/main.c
|
|
|
4728c8 |
===================================================================
|
|
|
4728c8 |
--- multipath-tools-130222.orig/mpathpersist/main.c
|
|
|
4728c8 |
+++ multipath-tools-130222/mpathpersist/main.c
|
|
|
4728c8 |
@@ -5,6 +5,7 @@
|
|
|
4728c8 |
#include <fcntl.h>
|
|
|
4728c8 |
#include <checkers.h>
|
|
|
4728c8 |
#include <vector.h>
|
|
|
4728c8 |
+#include <util.h>
|
|
|
4728c8 |
#include <structs.h>
|
|
|
4728c8 |
#include <getopt.h>
|
|
|
4728c8 |
#include <libudev.h>
|
|
|
4728c8 |
@@ -139,7 +140,7 @@ int main (int argc, char * argv[])
|
|
|
4728c8 |
++num_prout_param;
|
|
|
4728c8 |
break;
|
|
|
4728c8 |
case 'K':
|
|
|
4728c8 |
- if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_rk))
|
|
|
4728c8 |
+ if (parse_prkey(optarg, ¶m_rk) != 0)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
fprintf (stderr, "bad argument to '--param-rk'\n");
|
|
|
4728c8 |
return MPATH_PR_SYNTAX_ERROR;
|
|
|
4728c8 |
@@ -148,7 +149,7 @@ int main (int argc, char * argv[])
|
|
|
4728c8 |
break;
|
|
|
4728c8 |
|
|
|
4728c8 |
case 'S':
|
|
|
4728c8 |
- if (1 != sscanf (optarg, "%" SCNx64 "", ¶m_sark))
|
|
|
4728c8 |
+ if (parse_prkey(optarg, ¶m_sark) != 0)
|
|
|
4728c8 |
{
|
|
|
4728c8 |
fprintf (stderr, "bad argument to '--param-sark'\n");
|
|
|
4728c8 |
return MPATH_PR_SYNTAX_ERROR;
|