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))) {
+ if (update_prkey_flags(alias, get_be64(mpp->reservation_key),
+ paramp->sa_flags)) {
condlog(0, "%s: failed to set prkey for multipathd.",
alias);
ret = MPATH_PR_DMMP_ERROR;
#include <stdio.h>
#include <unistd.h>
-#include <errno.h>
-
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/un.h>
#include <poll.h>
#include <errno.h>
+#include <libudev.h>
+#include <mpath_persist.h>
#include "debug.h"
#include "mpath_cmd.h"
#include "uxsock.h"
return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus");
}
-int update_prkey(char *mapname, uint64_t prkey) {
+int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags) {
char str[256];
+ char *flagstr = "";
+ if (sa_flags & MPATH_F_APTPL_MASK)
+ flagstr = ":aptpl";
if (prkey)
- sprintf(str, "setprkey key %" PRIx64, prkey);
+ sprintf(str, "setprkey key %" PRIx64 "%s", prkey, flagstr);
else
sprintf(str, "unsetprkey");
return do_update_pr(mapname, str);
unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy);
int update_prflag(char *mapname, int set);
-int update_prkey(char *mapname, uint64_t prkey);
+int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags);
+#define update_prkey(mapname, prkey) update_prkey_flags(mapname, prkey, 0)
void * mpath_alloc_prin_response(int prin_sa);
int update_map_pr(struct multipath *mpp);
DEVLIB = libmultipath.so
LIBS = $(DEVLIB).$(SONAME)
-CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir)
+CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir)
LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathcmddir) -lmpathcmd -lurcu -laio
char * prio_args;
int prkey_source;
struct be64 reservation_key;
+ uint8_t sa_flags;
int pgpolicy;
int pgfailback;
int rr_weight;
int prkey_source;
int all_tg_pt;
struct be64 reservation_key;
+ uint8_t sa_flags;
vector keywords;
vector mptable;
#include "util.h"
#include <errno.h>
#include <inttypes.h>
+#include <libudev.h>
+#include <mpath_persist.h>
#include "mpath_cmd.h"
#include "dict.h"
}
static int
-set_reservation_key(vector strvec, struct be64 *be64_ptr, int *source_ptr)
+set_reservation_key(vector strvec, struct be64 *be64_ptr, uint8_t *flags_ptr,
+ int *source_ptr)
{
char *buff;
uint64_t prkey;
+ uint8_t sa_flags;
buff = set_value(strvec);
if (!buff)
if (strcmp(buff, "file") == 0) {
*source_ptr = PRKEY_SOURCE_FILE;
+ *flags_ptr = 0;
put_be64(*be64_ptr, 0);
FREE(buff);
return 0;
}
- if (parse_prkey(buff, &prkey) != 0) {
+ if (parse_prkey_flags(buff, &prkey, &sa_flags) != 0) {
FREE(buff);
return 1;
}
*source_ptr = PRKEY_SOURCE_CONF;
+ *flags_ptr = sa_flags;
put_be64(*be64_ptr, prkey);
FREE(buff);
return 0;
}
int
-print_reservation_key(char * buff, int len, struct be64 key, int source)
+print_reservation_key(char * buff, int len, struct be64 key, uint8_t flags,
+ int source)
{
+ char *flagstr = "";
if (source == PRKEY_SOURCE_NONE)
return 0;
if (source == PRKEY_SOURCE_FILE)
return snprintf(buff, len, "file");
- return snprintf(buff, len, "0x%" PRIx64, get_be64(key));
+ if (flags & MPATH_F_APTPL_MASK)
+ flagstr = ":aptpl";
+ return snprintf(buff, len, "0x%" PRIx64 "%s", get_be64(key),
+ flagstr);
}
static int
def_reservation_key_handler(struct config *conf, vector strvec)
{
return set_reservation_key(strvec, &conf->reservation_key,
+ &conf->sa_flags,
&conf->prkey_source);
}
const void * data)
{
return print_reservation_key(buff, len, conf->reservation_key,
+ conf->sa_flags,
conf->prkey_source);
}
if (!mpe)
return 1;
return set_reservation_key(strvec, &mpe->reservation_key,
+ &mpe->sa_flags,
&mpe->prkey_source);
}
{
const struct mpentry * mpe = (const struct mpentry *)data;
return print_reservation_key(buff, len, mpe->reservation_key,
+ mpe->sa_flags,
mpe->prkey_source);
}
int print_no_path_retry(char *buff, int len, long v);
int print_fast_io_fail(char *buff, int len, long v);
int print_dev_loss(char *buff, int len, unsigned long v);
-int print_reservation_key(char * buff, int len, struct be64 key, int source);
+int print_reservation_key(char * buff, int len, struct be64 key, uint8_t
+ flags, int source);
int print_off_int_undef(char *buff, int len, long v);
#endif /* _DICT_H */
#include <string.h>
#include <inttypes.h>
#include <errno.h>
+#include <libudev.h>
+#include <mpath_persist.h>
#define PRKEY_READ 0
#define PRKEY_WRITE 1
return 0;
}
-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey)
+int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey,
+ uint8_t *sa_flags)
{
int fd;
int unused;
ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ);
if (ret)
goto out_file;
+ *sa_flags = 0;
+ if (strchr(keystr, 'X'))
+ *sa_flags = MPATH_F_APTPL_MASK;
ret = !!parse_prkey(keystr, prkey);
out_file:
close(fd);
return ret;
}
-int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey)
+int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey,
+ uint8_t sa_flags)
{
int fd;
int can_write = 1;
if (!strlen(mpp->wwid))
goto out;
+ if (sa_flags & ~MPATH_F_APTPL_MASK) {
+ condlog(0, "unsupported pr flags, 0x%x",
+ sa_flags & ~MPATH_F_APTPL_MASK);
+ sa_flags &= MPATH_F_APTPL_MASK;
+ }
+
fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER);
if (fd < 0)
goto out;
goto out_file;
}
if (prkey) {
- snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey);
+ /* using the capitalization of the 'x' is a hack, but
+ * it's unlikely that mpath_persist will support more options
+ * since sg_persist doesn't, and this lets us keep the
+ * same file format as before instead of needing to change
+ * the format of the prkeys file */
+ if (sa_flags)
+ snprintf(keystr, PRKEY_SIZE, "0X%016" PRIx64, prkey);
+ else
+ snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey);
keystr[PRKEY_SIZE - 1] = '\0';
ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_WRITE);
}
"# prkey wwid\n" \
"#\n"
-int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey);
-int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey);
+int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey,
+ uint8_t sa_flags);
+int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey,
+ uint8_t *sa_flags);
#endif /* _PRKEY_H */
if (src && src->prkey_source != PRKEY_SOURCE_NONE) { \
mp->prkey_source = src->prkey_source; \
mp->reservation_key = src->reservation_key; \
+ mp->sa_flags = src->sa_flags; \
origin = msg; \
goto out; \
} \
do_prkey_set(mp->mpe, multipaths_origin);
do_prkey_set(conf, conf_origin);
put_be64(mp->reservation_key, 0);
+ mp->sa_flags = 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(conf, mp, &prkey) != 0)
+ if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0)
put_be64(mp->reservation_key, 0);
else
put_be64(mp->reservation_key, prkey);
}
print_reservation_key(buff, PRKEY_SIZE, mp->reservation_key,
- mp->prkey_source);
+ mp->sa_flags, mp->prkey_source);
condlog(3, "%s: reservation_key = %s %s%s", mp->alias, buff, origin,
from_file);
return 0;
/* persistent management data*/
int prkey_source;
struct be64 reservation_key;
+ uint8_t sa_flags;
unsigned char prflag;
int all_tg_pt;
struct gen_multipath generic_mp;
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
+#include <libudev.h>
+#include <mpath_persist.h>
#include "util.h"
#include "debug.h"
return 0;
}
+int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags)
+{
+ char *flagstr;
+
+ flagstr = strchr(ptr, ':');
+ *flags = 0;
+ if (flagstr) {
+ *flagstr++ = '\0';
+ if (strlen(flagstr) == 5 && strcmp(flagstr, "aptpl") == 0)
+ *flags = MPATH_F_APTPL_MASK;
+ }
+ return parse_prkey(ptr, prkey);
+}
+
int safe_write(int fd, const void *buf, size_t count)
{
while (count > 0) {
int systemd_service_enabled(const char *dev);
int get_linux_version_code(void);
int parse_prkey(char *ptr, uint64_t *prkey);
+int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags);
int safe_write(int fd, const void *buf, size_t count);
#define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc))
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.
+device server to identify the I_T nexus. If the \fI--param-aptpl\fR option is
+used when registering the key with mpathpersist, \fB:aptpl\fR must be appended
+to the end of the reservation key.
.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.
+\fIprkeys_file\fR. The prkeys file will automatically keep track of whether
+the key was registered with \fI--param-aptpl\fR.
.TP
The default is: \fB<unset>\fR
.RE
#include "sysfs.h"
#include <errno.h>
#include <libudev.h>
+#include <mpath_persist.h>
#include "util.h"
#include "prkey.h"
#include "propsel.h"
struct multipath * mpp;
struct vectors * vecs = (struct vectors *)data;
char *mapname = get_keyparam(v, MAP);
+ char *flagstr = "";
mapname = convert_dev(mapname, 0);
condlog(3, "%s: get persistent reservation key (operator)", mapname);
*len = strlen(*reply) + 1;
return 0;
}
- snprintf(*reply, 20, "0x%" PRIx64 "\n",
- get_be64(mpp->reservation_key));
+ if (mpp->sa_flags & MPATH_F_APTPL_MASK)
+ flagstr = ":aptpl";
+ snprintf(*reply, 20, "0x%" PRIx64 "%s\n",
+ get_be64(mpp->reservation_key), flagstr);
(*reply)[19] = '\0';
*len = strlen(*reply) + 1;
return 0;
conf = get_multipath_config();
pthread_cleanup_push(put_multipath_config, conf);
- ret = set_prkey(conf, mpp, 0);
+ ret = set_prkey(conf, mpp, 0, 0);
pthread_cleanup_pop(1);
return ret;
char *mapname = get_keyparam(v, MAP);
char *keyparam = get_keyparam(v, KEY);
uint64_t prkey;
+ uint8_t flags;
int ret;
struct config *conf;
if (!mpp)
return 1;
- if (parse_prkey(keyparam, &prkey) != 0) {
+ if (parse_prkey_flags(keyparam, &prkey, &flags) != 0) {
condlog(0, "%s: invalid prkey : '%s'", mapname, keyparam);
return 1;
}
conf = get_multipath_config();
pthread_cleanup_push(put_multipath_config, conf);
- ret = set_prkey(conf, mpp, prkey);
+ ret = set_prkey(conf, mpp, prkey, flags);
pthread_cleanup_pop(1);
return ret;
param= malloc(sizeof(struct prout_param_descriptor));
memset(param, 0 , sizeof(struct prout_param_descriptor));
+ param->sa_flags = mpp->sa_flags;
memcpy(param->sa_key, &mpp->reservation_key, 8);
param->num_transportid = 0;