Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame^] | 1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | From: Benjamin Marzinski <bmarzins@redhat.com> |
| 3 | Date: Mon, 4 Jun 2018 22:04:44 -0500 |
| 4 | Subject: [PATCH] mpathpersist: fix aptpl support |
| 5 | |
| 6 | The "Active Persist Through Power Loss" flag must be set whenever a key |
| 7 | is registered. However, there is no way for multipathd to know if this |
| 8 | was set by mpathpersist. The result is that if a path goes down and |
| 9 | comes back up (or if it wasn't up when mpathpersist was first run) |
| 10 | multipathd will clear the aptpl flag when it reregisters the key on it. |
| 11 | |
| 12 | To fix this, multipath.conf now accepts an optional ":aptpl" appended |
| 13 | on the reservation_key value. If this is added to the reservation_key |
| 14 | multipathd will set the aptpl flag when it reregisters the key. If |
| 15 | reservation_key is set to "file", this will automatically be tracked |
| 16 | in the /etc/multipath/prkeys file. |
| 17 | |
| 18 | To track this flag in the prkeys file, without changing the format |
| 19 | I've made "0x<key>" stand for non-aptpl keys, and "0X<key>" stand |
| 20 | for aptpl keys. Since previously, all keys used a lower-case x, this |
| 21 | will default to the current behavior for existing keys. Obviously, the |
| 22 | next time mpathpersist is run, this will be changed if --param-aptpl |
| 23 | is used. Since there are no more flags that are in sg_persist that |
| 24 | multipathd needs to care about in mpathpersist, there shouldn't need |
| 25 | to be any more flags added to the prkeys file. |
| 26 | |
| 27 | Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> |
| 28 | --- |
| 29 | libmpathpersist/mpath_persist.c | 3 ++- |
| 30 | libmpathpersist/mpath_updatepr.c | 11 +++++++---- |
| 31 | libmpathpersist/mpathpr.h | 3 ++- |
| 32 | libmultipath/Makefile | 2 +- |
| 33 | libmultipath/config.h | 2 ++ |
| 34 | libmultipath/dict.c | 23 +++++++++++++++++++---- |
| 35 | libmultipath/dict.h | 3 ++- |
| 36 | libmultipath/prkey.c | 27 ++++++++++++++++++++++++--- |
| 37 | libmultipath/prkey.h | 6 ++++-- |
| 38 | libmultipath/propsel.c | 6 ++++-- |
| 39 | libmultipath/structs.h | 1 + |
| 40 | libmultipath/util.c | 16 ++++++++++++++++ |
| 41 | libmultipath/util.h | 1 + |
| 42 | multipath/multipath.conf.5 | 7 +++++-- |
| 43 | multipathd/cli_handlers.c | 15 ++++++++++----- |
| 44 | multipathd/main.c | 1 + |
| 45 | 16 files changed, 101 insertions(+), 26 deletions(-) |
| 46 | |
| 47 | diff --git a/libmpathpersist/mpath_persist.c b/libmpathpersist/mpath_persist.c |
| 48 | index ca91c55..6e9e67f 100644 |
| 49 | --- a/libmpathpersist/mpath_persist.c |
| 50 | +++ b/libmpathpersist/mpath_persist.c |
| 51 | @@ -344,7 +344,8 @@ int mpath_persistent_reserve_out ( int fd, int rq_servact, int rq_scope, |
| 52 | rq_servact == MPATH_PROUT_REG_SA) || |
| 53 | rq_servact == MPATH_PROUT_REG_IGN_SA)) { |
| 54 | memcpy(&mpp->reservation_key, paramp->sa_key, 8); |
| 55 | - if (update_prkey(alias, get_be64(mpp->reservation_key))) { |
| 56 | + if (update_prkey_flags(alias, get_be64(mpp->reservation_key), |
| 57 | + paramp->sa_flags)) { |
| 58 | condlog(0, "%s: failed to set prkey for multipathd.", |
| 59 | alias); |
| 60 | ret = MPATH_PR_DMMP_ERROR; |
| 61 | diff --git a/libmpathpersist/mpath_updatepr.c b/libmpathpersist/mpath_updatepr.c |
| 62 | index 8063e90..0aca28e 100644 |
| 63 | --- a/libmpathpersist/mpath_updatepr.c |
| 64 | +++ b/libmpathpersist/mpath_updatepr.c |
| 65 | @@ -1,7 +1,5 @@ |
| 66 | #include <stdio.h> |
| 67 | #include <unistd.h> |
| 68 | -#include <errno.h> |
| 69 | - |
| 70 | #include <stdlib.h> |
| 71 | #include <stdarg.h> |
| 72 | #include <fcntl.h> |
| 73 | @@ -11,6 +9,8 @@ |
| 74 | #include <sys/un.h> |
| 75 | #include <poll.h> |
| 76 | #include <errno.h> |
| 77 | +#include <libudev.h> |
| 78 | +#include <mpath_persist.h> |
| 79 | #include "debug.h" |
| 80 | #include "mpath_cmd.h" |
| 81 | #include "uxsock.h" |
| 82 | @@ -59,11 +59,14 @@ int update_prflag(char *mapname, int set) { |
| 83 | return do_update_pr(mapname, (set)? "setprstatus" : "unsetprstatus"); |
| 84 | } |
| 85 | |
| 86 | -int update_prkey(char *mapname, uint64_t prkey) { |
| 87 | +int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags) { |
| 88 | char str[256]; |
| 89 | + char *flagstr = ""; |
| 90 | |
| 91 | + if (sa_flags & MPATH_F_APTPL_MASK) |
| 92 | + flagstr = ":aptpl"; |
| 93 | if (prkey) |
| 94 | - sprintf(str, "setprkey key %" PRIx64, prkey); |
| 95 | + sprintf(str, "setprkey key %" PRIx64 "%s", prkey, flagstr); |
| 96 | else |
| 97 | sprintf(str, "unsetprkey"); |
| 98 | return do_update_pr(mapname, str); |
| 99 | diff --git a/libmpathpersist/mpathpr.h b/libmpathpersist/mpathpr.h |
| 100 | index 72feb60..5ea8cd6 100644 |
| 101 | --- a/libmpathpersist/mpathpr.h |
| 102 | +++ b/libmpathpersist/mpathpr.h |
| 103 | @@ -46,7 +46,8 @@ int send_prout_activepath(char * dev, int rq_servact, int rq_scope, |
| 104 | unsigned int rq_type, struct prout_param_descriptor * paramp, int noisy); |
| 105 | |
| 106 | int update_prflag(char *mapname, int set); |
| 107 | -int update_prkey(char *mapname, uint64_t prkey); |
| 108 | +int update_prkey_flags(char *mapname, uint64_t prkey, uint8_t sa_flags); |
| 109 | +#define update_prkey(mapname, prkey) update_prkey_flags(mapname, prkey, 0) |
| 110 | void * mpath_alloc_prin_response(int prin_sa); |
| 111 | int update_map_pr(struct multipath *mpp); |
| 112 | |
| 113 | diff --git a/libmultipath/Makefile b/libmultipath/Makefile |
| 114 | index f51786d..33f5269 100644 |
| 115 | --- a/libmultipath/Makefile |
| 116 | +++ b/libmultipath/Makefile |
| 117 | @@ -7,7 +7,7 @@ SONAME = 0 |
| 118 | DEVLIB = libmultipath.so |
| 119 | LIBS = $(DEVLIB).$(SONAME) |
| 120 | |
| 121 | -CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) |
| 122 | +CFLAGS += $(LIB_CFLAGS) -I$(mpathcmddir) -I$(mpathpersistdir) |
| 123 | |
| 124 | LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathcmddir) -lmpathcmd -lurcu -laio |
| 125 | |
| 126 | diff --git a/libmultipath/config.h b/libmultipath/config.h |
| 127 | index 1bf708a..fcbe3fc 100644 |
| 128 | --- a/libmultipath/config.h |
| 129 | +++ b/libmultipath/config.h |
| 130 | @@ -98,6 +98,7 @@ struct mpentry { |
| 131 | char * prio_args; |
| 132 | int prkey_source; |
| 133 | struct be64 reservation_key; |
| 134 | + uint8_t sa_flags; |
| 135 | int pgpolicy; |
| 136 | int pgfailback; |
| 137 | int rr_weight; |
| 138 | @@ -197,6 +198,7 @@ struct config { |
| 139 | int prkey_source; |
| 140 | int all_tg_pt; |
| 141 | struct be64 reservation_key; |
| 142 | + uint8_t sa_flags; |
| 143 | |
| 144 | vector keywords; |
| 145 | vector mptable; |
| 146 | diff --git a/libmultipath/dict.c b/libmultipath/dict.c |
| 147 | index 2557b8a..7ad0f5a 100644 |
| 148 | --- a/libmultipath/dict.c |
| 149 | +++ b/libmultipath/dict.c |
| 150 | @@ -22,6 +22,8 @@ |
| 151 | #include "util.h" |
| 152 | #include <errno.h> |
| 153 | #include <inttypes.h> |
| 154 | +#include <libudev.h> |
| 155 | +#include <mpath_persist.h> |
| 156 | #include "mpath_cmd.h" |
| 157 | #include "dict.h" |
| 158 | |
| 159 | @@ -1012,10 +1014,12 @@ snprint_def_log_checker_err (struct config *conf, char * buff, int len, |
| 160 | } |
| 161 | |
| 162 | static int |
| 163 | -set_reservation_key(vector strvec, struct be64 *be64_ptr, int *source_ptr) |
| 164 | +set_reservation_key(vector strvec, struct be64 *be64_ptr, uint8_t *flags_ptr, |
| 165 | + int *source_ptr) |
| 166 | { |
| 167 | char *buff; |
| 168 | uint64_t prkey; |
| 169 | + uint8_t sa_flags; |
| 170 | |
| 171 | buff = set_value(strvec); |
| 172 | if (!buff) |
| 173 | @@ -1023,35 +1027,43 @@ set_reservation_key(vector strvec, struct be64 *be64_ptr, int *source_ptr) |
| 174 | |
| 175 | if (strcmp(buff, "file") == 0) { |
| 176 | *source_ptr = PRKEY_SOURCE_FILE; |
| 177 | + *flags_ptr = 0; |
| 178 | put_be64(*be64_ptr, 0); |
| 179 | FREE(buff); |
| 180 | return 0; |
| 181 | } |
| 182 | |
| 183 | - if (parse_prkey(buff, &prkey) != 0) { |
| 184 | + if (parse_prkey_flags(buff, &prkey, &sa_flags) != 0) { |
| 185 | FREE(buff); |
| 186 | return 1; |
| 187 | } |
| 188 | *source_ptr = PRKEY_SOURCE_CONF; |
| 189 | + *flags_ptr = sa_flags; |
| 190 | put_be64(*be64_ptr, prkey); |
| 191 | FREE(buff); |
| 192 | return 0; |
| 193 | } |
| 194 | |
| 195 | int |
| 196 | -print_reservation_key(char * buff, int len, struct be64 key, int source) |
| 197 | +print_reservation_key(char * buff, int len, struct be64 key, uint8_t flags, |
| 198 | + int source) |
| 199 | { |
| 200 | + char *flagstr = ""; |
| 201 | if (source == PRKEY_SOURCE_NONE) |
| 202 | return 0; |
| 203 | if (source == PRKEY_SOURCE_FILE) |
| 204 | return snprintf(buff, len, "file"); |
| 205 | - return snprintf(buff, len, "0x%" PRIx64, get_be64(key)); |
| 206 | + if (flags & MPATH_F_APTPL_MASK) |
| 207 | + flagstr = ":aptpl"; |
| 208 | + return snprintf(buff, len, "0x%" PRIx64 "%s", get_be64(key), |
| 209 | + flagstr); |
| 210 | } |
| 211 | |
| 212 | static int |
| 213 | def_reservation_key_handler(struct config *conf, vector strvec) |
| 214 | { |
| 215 | return set_reservation_key(strvec, &conf->reservation_key, |
| 216 | + &conf->sa_flags, |
| 217 | &conf->prkey_source); |
| 218 | } |
| 219 | |
| 220 | @@ -1060,6 +1072,7 @@ snprint_def_reservation_key (struct config *conf, char * buff, int len, |
| 221 | const void * data) |
| 222 | { |
| 223 | return print_reservation_key(buff, len, conf->reservation_key, |
| 224 | + conf->sa_flags, |
| 225 | conf->prkey_source); |
| 226 | } |
| 227 | |
| 228 | @@ -1070,6 +1083,7 @@ mp_reservation_key_handler(struct config *conf, vector strvec) |
| 229 | if (!mpe) |
| 230 | return 1; |
| 231 | return set_reservation_key(strvec, &mpe->reservation_key, |
| 232 | + &mpe->sa_flags, |
| 233 | &mpe->prkey_source); |
| 234 | } |
| 235 | |
| 236 | @@ -1079,6 +1093,7 @@ snprint_mp_reservation_key (struct config *conf, char * buff, int len, |
| 237 | { |
| 238 | const struct mpentry * mpe = (const struct mpentry *)data; |
| 239 | return print_reservation_key(buff, len, mpe->reservation_key, |
| 240 | + mpe->sa_flags, |
| 241 | mpe->prkey_source); |
| 242 | } |
| 243 | |
| 244 | diff --git a/libmultipath/dict.h b/libmultipath/dict.h |
| 245 | index 7564892..a40ac66 100644 |
| 246 | --- a/libmultipath/dict.h |
| 247 | +++ b/libmultipath/dict.h |
| 248 | @@ -15,6 +15,7 @@ int print_pgpolicy(char *buff, int len, long v); |
| 249 | int print_no_path_retry(char *buff, int len, long v); |
| 250 | int print_fast_io_fail(char *buff, int len, long v); |
| 251 | int print_dev_loss(char *buff, int len, unsigned long v); |
| 252 | -int print_reservation_key(char * buff, int len, struct be64 key, int source); |
| 253 | +int print_reservation_key(char * buff, int len, struct be64 key, uint8_t |
| 254 | + flags, int source); |
| 255 | int print_off_int_undef(char *buff, int len, long v); |
| 256 | #endif /* _DICT_H */ |
| 257 | diff --git a/libmultipath/prkey.c b/libmultipath/prkey.c |
| 258 | index 89b90ed..d645f81 100644 |
| 259 | --- a/libmultipath/prkey.c |
| 260 | +++ b/libmultipath/prkey.c |
| 261 | @@ -11,6 +11,8 @@ |
| 262 | #include <string.h> |
| 263 | #include <inttypes.h> |
| 264 | #include <errno.h> |
| 265 | +#include <libudev.h> |
| 266 | +#include <mpath_persist.h> |
| 267 | |
| 268 | #define PRKEY_READ 0 |
| 269 | #define PRKEY_WRITE 1 |
| 270 | @@ -108,7 +110,8 @@ static int do_prkey(int fd, char *wwid, char *keystr, int cmd) |
| 271 | return 0; |
| 272 | } |
| 273 | |
| 274 | -int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey) |
| 275 | +int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, |
| 276 | + uint8_t *sa_flags) |
| 277 | { |
| 278 | int fd; |
| 279 | int unused; |
| 280 | @@ -124,6 +127,9 @@ int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey) |
| 281 | ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_READ); |
| 282 | if (ret) |
| 283 | goto out_file; |
| 284 | + *sa_flags = 0; |
| 285 | + if (strchr(keystr, 'X')) |
| 286 | + *sa_flags = MPATH_F_APTPL_MASK; |
| 287 | ret = !!parse_prkey(keystr, prkey); |
| 288 | out_file: |
| 289 | close(fd); |
| 290 | @@ -131,7 +137,8 @@ out: |
| 291 | return ret; |
| 292 | } |
| 293 | |
| 294 | -int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) |
| 295 | +int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, |
| 296 | + uint8_t sa_flags) |
| 297 | { |
| 298 | int fd; |
| 299 | int can_write = 1; |
| 300 | @@ -141,6 +148,12 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) |
| 301 | if (!strlen(mpp->wwid)) |
| 302 | goto out; |
| 303 | |
| 304 | + if (sa_flags & ~MPATH_F_APTPL_MASK) { |
| 305 | + condlog(0, "unsupported pr flags, 0x%x", |
| 306 | + sa_flags & ~MPATH_F_APTPL_MASK); |
| 307 | + sa_flags &= MPATH_F_APTPL_MASK; |
| 308 | + } |
| 309 | + |
| 310 | fd = open_file(conf->prkeys_file, &can_write, PRKEYS_FILE_HEADER); |
| 311 | if (fd < 0) |
| 312 | goto out; |
| 313 | @@ -149,7 +162,15 @@ int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey) |
| 314 | goto out_file; |
| 315 | } |
| 316 | if (prkey) { |
| 317 | - snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey); |
| 318 | + /* using the capitalization of the 'x' is a hack, but |
| 319 | + * it's unlikely that mpath_persist will support more options |
| 320 | + * since sg_persist doesn't, and this lets us keep the |
| 321 | + * same file format as before instead of needing to change |
| 322 | + * the format of the prkeys file */ |
| 323 | + if (sa_flags) |
| 324 | + snprintf(keystr, PRKEY_SIZE, "0X%016" PRIx64, prkey); |
| 325 | + else |
| 326 | + snprintf(keystr, PRKEY_SIZE, "0x%016" PRIx64, prkey); |
| 327 | keystr[PRKEY_SIZE - 1] = '\0'; |
| 328 | ret = do_prkey(fd, mpp->wwid, keystr, PRKEY_WRITE); |
| 329 | } |
| 330 | diff --git a/libmultipath/prkey.h b/libmultipath/prkey.h |
| 331 | index 4028e70..6739191 100644 |
| 332 | --- a/libmultipath/prkey.h |
| 333 | +++ b/libmultipath/prkey.h |
| 334 | @@ -13,7 +13,9 @@ |
| 335 | "# prkey wwid\n" \ |
| 336 | "#\n" |
| 337 | |
| 338 | -int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey); |
| 339 | -int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey); |
| 340 | +int set_prkey(struct config *conf, struct multipath *mpp, uint64_t prkey, |
| 341 | + uint8_t sa_flags); |
| 342 | +int get_prkey(struct config *conf, struct multipath *mpp, uint64_t *prkey, |
| 343 | + uint8_t *sa_flags); |
| 344 | |
| 345 | #endif /* _PRKEY_H */ |
| 346 | diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c |
| 347 | index 9ca1355..62a6893 100644 |
| 348 | --- a/libmultipath/propsel.c |
| 349 | +++ b/libmultipath/propsel.c |
| 350 | @@ -106,6 +106,7 @@ do { \ |
| 351 | if (src && src->prkey_source != PRKEY_SOURCE_NONE) { \ |
| 352 | mp->prkey_source = src->prkey_source; \ |
| 353 | mp->reservation_key = src->reservation_key; \ |
| 354 | + mp->sa_flags = src->sa_flags; \ |
| 355 | origin = msg; \ |
| 356 | goto out; \ |
| 357 | } \ |
| 358 | @@ -703,18 +704,19 @@ int select_reservation_key(struct config *conf, struct multipath *mp) |
| 359 | do_prkey_set(mp->mpe, multipaths_origin); |
| 360 | do_prkey_set(conf, conf_origin); |
| 361 | put_be64(mp->reservation_key, 0); |
| 362 | + mp->sa_flags = 0; |
| 363 | mp->prkey_source = PRKEY_SOURCE_NONE; |
| 364 | return 0; |
| 365 | out: |
| 366 | if (mp->prkey_source == PRKEY_SOURCE_FILE) { |
| 367 | from_file = " (from prkeys file)"; |
| 368 | - if (get_prkey(conf, mp, &prkey) != 0) |
| 369 | + if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0) |
| 370 | put_be64(mp->reservation_key, 0); |
| 371 | else |
| 372 | put_be64(mp->reservation_key, prkey); |
| 373 | } |
| 374 | print_reservation_key(buff, PRKEY_SIZE, mp->reservation_key, |
| 375 | - mp->prkey_source); |
| 376 | + mp->sa_flags, mp->prkey_source); |
| 377 | condlog(3, "%s: reservation_key = %s %s%s", mp->alias, buff, origin, |
| 378 | from_file); |
| 379 | return 0; |
| 380 | diff --git a/libmultipath/structs.h b/libmultipath/structs.h |
| 381 | index 0194b1e..987479f 100644 |
| 382 | --- a/libmultipath/structs.h |
| 383 | +++ b/libmultipath/structs.h |
| 384 | @@ -367,6 +367,7 @@ struct multipath { |
| 385 | /* persistent management data*/ |
| 386 | int prkey_source; |
| 387 | struct be64 reservation_key; |
| 388 | + uint8_t sa_flags; |
| 389 | unsigned char prflag; |
| 390 | int all_tg_pt; |
| 391 | struct gen_multipath generic_mp; |
| 392 | diff --git a/libmultipath/util.c b/libmultipath/util.c |
| 393 | index 7251ad0..8d8fcc8 100644 |
| 394 | --- a/libmultipath/util.c |
| 395 | +++ b/libmultipath/util.c |
| 396 | @@ -10,6 +10,8 @@ |
| 397 | #include <dirent.h> |
| 398 | #include <unistd.h> |
| 399 | #include <errno.h> |
| 400 | +#include <libudev.h> |
| 401 | +#include <mpath_persist.h> |
| 402 | |
| 403 | #include "util.h" |
| 404 | #include "debug.h" |
| 405 | @@ -435,6 +437,20 @@ int parse_prkey(char *ptr, uint64_t *prkey) |
| 406 | return 0; |
| 407 | } |
| 408 | |
| 409 | +int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags) |
| 410 | +{ |
| 411 | + char *flagstr; |
| 412 | + |
| 413 | + flagstr = strchr(ptr, ':'); |
| 414 | + *flags = 0; |
| 415 | + if (flagstr) { |
| 416 | + *flagstr++ = '\0'; |
| 417 | + if (strlen(flagstr) == 5 && strcmp(flagstr, "aptpl") == 0) |
| 418 | + *flags = MPATH_F_APTPL_MASK; |
| 419 | + } |
| 420 | + return parse_prkey(ptr, prkey); |
| 421 | +} |
| 422 | + |
| 423 | int safe_write(int fd, const void *buf, size_t count) |
| 424 | { |
| 425 | while (count > 0) { |
| 426 | diff --git a/libmultipath/util.h b/libmultipath/util.h |
| 427 | index a3ab894..56cec76 100644 |
| 428 | --- a/libmultipath/util.h |
| 429 | +++ b/libmultipath/util.h |
| 430 | @@ -19,6 +19,7 @@ void setup_thread_attr(pthread_attr_t *attr, size_t stacksize, int detached); |
| 431 | int systemd_service_enabled(const char *dev); |
| 432 | int get_linux_version_code(void); |
| 433 | int parse_prkey(char *ptr, uint64_t *prkey); |
| 434 | +int parse_prkey_flags(char *ptr, uint64_t *prkey, uint8_t *flags); |
| 435 | int safe_write(int fd, const void *buf, size_t count); |
| 436 | |
| 437 | #define KERNEL_VERSION(maj, min, ptc) ((((maj) * 256) + (min)) * 256 + (ptc)) |
| 438 | diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5 |
| 439 | index 31f4585..30d8598 100644 |
| 440 | --- a/multipath/multipath.conf.5 |
| 441 | +++ b/multipath/multipath.conf.5 |
| 442 | @@ -726,14 +726,17 @@ This is the service action reservation key used by mpathpersist. It must be |
| 443 | set for all multipath devices using persistent reservations, and it must be |
| 444 | the same as the RESERVATION KEY field of the PERSISTENT RESERVE OUT parameter |
| 445 | list which contains an 8-byte value provided by the application client to the |
| 446 | -device server to identify the I_T nexus. |
| 447 | +device server to identify the I_T nexus. If the \fI--param-aptpl\fR option is |
| 448 | +used when registering the key with mpathpersist, \fB:aptpl\fR must be appended |
| 449 | +to the end of the reservation key. |
| 450 | .RS |
| 451 | .PP |
| 452 | Alternatively, this can be set to \fBfile\fR, which will store the RESERVATION |
| 453 | KEY registered by mpathpersist in the \fIprkeys_file\fR. multipathd will then |
| 454 | use this key to register additional paths as they appear. When the |
| 455 | registration is removed, the RESERVATION KEY is removed from the |
| 456 | -\fIprkeys_file\fR. |
| 457 | +\fIprkeys_file\fR. The prkeys file will automatically keep track of whether |
| 458 | +the key was registered with \fI--param-aptpl\fR. |
| 459 | .TP |
| 460 | The default is: \fB<unset>\fR |
| 461 | .RE |
| 462 | diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c |
| 463 | index ba50fb8..6452796 100644 |
| 464 | --- a/multipathd/cli_handlers.c |
| 465 | +++ b/multipathd/cli_handlers.c |
| 466 | @@ -21,6 +21,7 @@ |
| 467 | #include "sysfs.h" |
| 468 | #include <errno.h> |
| 469 | #include <libudev.h> |
| 470 | +#include <mpath_persist.h> |
| 471 | #include "util.h" |
| 472 | #include "prkey.h" |
| 473 | #include "propsel.h" |
| 474 | @@ -1463,6 +1464,7 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) |
| 475 | struct multipath * mpp; |
| 476 | struct vectors * vecs = (struct vectors *)data; |
| 477 | char *mapname = get_keyparam(v, MAP); |
| 478 | + char *flagstr = ""; |
| 479 | |
| 480 | mapname = convert_dev(mapname, 0); |
| 481 | condlog(3, "%s: get persistent reservation key (operator)", mapname); |
| 482 | @@ -1478,8 +1480,10 @@ cli_getprkey(void * v, char ** reply, int * len, void * data) |
| 483 | *len = strlen(*reply) + 1; |
| 484 | return 0; |
| 485 | } |
| 486 | - snprintf(*reply, 20, "0x%" PRIx64 "\n", |
| 487 | - get_be64(mpp->reservation_key)); |
| 488 | + if (mpp->sa_flags & MPATH_F_APTPL_MASK) |
| 489 | + flagstr = ":aptpl"; |
| 490 | + snprintf(*reply, 20, "0x%" PRIx64 "%s\n", |
| 491 | + get_be64(mpp->reservation_key), flagstr); |
| 492 | (*reply)[19] = '\0'; |
| 493 | *len = strlen(*reply) + 1; |
| 494 | return 0; |
| 495 | @@ -1503,7 +1507,7 @@ cli_unsetprkey(void * v, char ** reply, int * len, void * data) |
| 496 | |
| 497 | conf = get_multipath_config(); |
| 498 | pthread_cleanup_push(put_multipath_config, conf); |
| 499 | - ret = set_prkey(conf, mpp, 0); |
| 500 | + ret = set_prkey(conf, mpp, 0, 0); |
| 501 | pthread_cleanup_pop(1); |
| 502 | |
| 503 | return ret; |
| 504 | @@ -1517,6 +1521,7 @@ cli_setprkey(void * v, char ** reply, int * len, void * data) |
| 505 | char *mapname = get_keyparam(v, MAP); |
| 506 | char *keyparam = get_keyparam(v, KEY); |
| 507 | uint64_t prkey; |
| 508 | + uint8_t flags; |
| 509 | int ret; |
| 510 | struct config *conf; |
| 511 | |
| 512 | @@ -1527,14 +1532,14 @@ cli_setprkey(void * v, char ** reply, int * len, void * data) |
| 513 | if (!mpp) |
| 514 | return 1; |
| 515 | |
| 516 | - if (parse_prkey(keyparam, &prkey) != 0) { |
| 517 | + if (parse_prkey_flags(keyparam, &prkey, &flags) != 0) { |
| 518 | condlog(0, "%s: invalid prkey : '%s'", mapname, keyparam); |
| 519 | return 1; |
| 520 | } |
| 521 | |
| 522 | conf = get_multipath_config(); |
| 523 | pthread_cleanup_push(put_multipath_config, conf); |
| 524 | - ret = set_prkey(conf, mpp, prkey); |
| 525 | + ret = set_prkey(conf, mpp, prkey, flags); |
| 526 | pthread_cleanup_pop(1); |
| 527 | |
| 528 | return ret; |
| 529 | diff --git a/multipathd/main.c b/multipathd/main.c |
| 530 | index d40c416..6b1e782 100644 |
| 531 | --- a/multipathd/main.c |
| 532 | +++ b/multipathd/main.c |
| 533 | @@ -3089,6 +3089,7 @@ void * mpath_pr_event_handler_fn (void * pathp ) |
| 534 | |
| 535 | param= malloc(sizeof(struct prout_param_descriptor)); |
| 536 | memset(param, 0 , sizeof(struct prout_param_descriptor)); |
| 537 | + param->sa_flags = mpp->sa_flags; |
| 538 | memcpy(param->sa_key, &mpp->reservation_key, 8); |
| 539 | param->num_transportid = 0; |
| 540 | |
| 541 | -- |
| 542 | 2.7.4 |
| 543 | |