You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1414 lines
39 KiB

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