multipath: add "ghost_delay" parameter
[multipath-tools/.git] / libmultipath / propsel.c
1 /*
2  * Copyright (c) 2004, 2005 Christophe Varoqui
3  * Copyright (c) 2005 Benjamin Marzinski, Redhat
4  * Copyright (c) 2005 Kiyoshi Ueda, NEC
5  */
6 #include <stdio.h>
7
8 #include "checkers.h"
9 #include "memory.h"
10 #include "vector.h"
11 #include "structs.h"
12 #include "config.h"
13 #include "debug.h"
14 #include "pgpolicies.h"
15 #include "alias.h"
16 #include "defaults.h"
17 #include "devmapper.h"
18 #include "prio.h"
19 #include "discovery.h"
20 #include "dict.h"
21 #include "util.h"
22 #include "prioritizers/alua_rtpg.h"
23 #include "prkey.h"
24 #include <inttypes.h>
25
26 pgpolicyfn *pgpolicies[] = {
27         NULL,
28         one_path_per_group,
29         one_group,
30         group_by_serial,
31         group_by_prio,
32         group_by_node_name
33 };
34
35 #define do_set(var, src, dest, msg)                                     \
36 do {                                                                    \
37         if (src && src->var) {                                          \
38                 dest = src->var;                                        \
39                 origin = msg;                                           \
40                 goto out;                                               \
41         }                                                               \
42 } while(0)
43 #define do_default(dest, value)                                         \
44 do {                                                                    \
45         dest = value;                                                   \
46         origin = "(setting: multipath internal)";                       \
47 } while(0)
48
49 #define mp_set_mpe(var)                                                 \
50 do_set(var, mp->mpe, mp->var, "(setting: multipath.conf multipaths section)")
51 #define mp_set_hwe(var)                                                 \
52 do_set(var, mp->hwe, mp->var, "(setting: storage device configuration)")
53 #define mp_set_ovr(var)                                                 \
54 do_set(var, conf->overrides, mp->var, "(setting: multipath.conf overrides section)")
55 #define mp_set_conf(var)                                                \
56 do_set(var, conf, mp->var, "(setting: multipath.conf defaults/devices section)")
57 #define mp_set_default(var, value)                                      \
58 do_default(mp->var, value)
59
60 #define pp_set_mpe(var)                                                 \
61 do_set(var, mpe, pp->var, "(setting: multipath.conf multipaths section)")
62 #define pp_set_hwe(var)                                                 \
63 do_set(var, pp->hwe, pp->var, "(setting: storage device configuration)")
64 #define pp_set_conf(var)                                                \
65 do_set(var, conf, pp->var, "(setting: multipath.conf defaults/devices section)")
66 #define pp_set_ovr(var)                                                 \
67 do_set(var, conf->overrides, pp->var, "(setting: multipath.conf overrides section)")
68 #define pp_set_default(var, value)                                      \
69 do_default(pp->var, value)
70
71 #define do_attr_set(var, src, shift, msg)                               \
72 do {                                                                    \
73         if (src && (src->attribute_flags & (1 << shift))) {             \
74                 mp->attribute_flags |= (1 << shift);                    \
75                 mp->var = src->var;                                     \
76                 origin = msg;                                           \
77                 goto out;                                               \
78         }                                                               \
79 } while(0)
80
81 #define set_attr_mpe(var, shift)                                        \
82 do_attr_set(var, mp->mpe, shift, "(setting: multipath.conf multipaths section)")
83 #define set_attr_conf(var, shift)                                       \
84 do_attr_set(var, conf, shift, "(setting: multipath.conf defaults/devices section)")
85
86 #define do_prkey_set(src, msg)                                          \
87 do {                                                                    \
88         if (src && src->prkey_source != PRKEY_SOURCE_NONE) {            \
89                 mp->prkey_source = src->prkey_source;                   \
90                 mp->reservation_key = src->reservation_key;             \
91                 origin = msg;                                           \
92                 goto out;                                               \
93         }                                                               \
94 } while (0)
95
96 int select_mode(struct config *conf, struct multipath *mp)
97 {
98         char *origin;
99
100         set_attr_mpe(mode, ATTR_MODE);
101         set_attr_conf(mode, ATTR_MODE);
102         mp->attribute_flags &= ~(1 << ATTR_MODE);
103         return 0;
104 out:
105         condlog(3, "%s: mode = 0%o %s", mp->alias, mp->mode, origin);
106         return 0;
107 }
108
109 int select_uid(struct config *conf, struct multipath *mp)
110 {
111         char *origin;
112
113         set_attr_mpe(uid, ATTR_UID);
114         set_attr_conf(uid, ATTR_UID);
115         mp->attribute_flags &= ~(1 << ATTR_UID);
116         return 0;
117 out:
118         condlog(3, "%s: uid = 0%o %s", mp->alias, mp->uid, origin);
119         return 0;
120 }
121
122 int select_gid(struct config *conf, struct multipath *mp)
123 {
124         char *origin;
125
126         set_attr_mpe(gid, ATTR_GID);
127         set_attr_conf(gid, ATTR_GID);
128         mp->attribute_flags &= ~(1 << ATTR_GID);
129         return 0;
130 out:
131         condlog(3, "%s: gid = 0%o %s", mp->alias, mp->gid, origin);
132         return 0;
133 }
134
135 /*
136  * selectors :
137  * traverse the configuration layers from most specific to most generic
138  * stop at first explicit setting found
139  */
140 int select_rr_weight(struct config *conf, struct multipath * mp)
141 {
142         char *origin, buff[13];
143
144         mp_set_mpe(rr_weight);
145         mp_set_ovr(rr_weight);
146         mp_set_hwe(rr_weight);
147         mp_set_conf(rr_weight);
148         mp_set_default(rr_weight, DEFAULT_RR_WEIGHT);
149 out:
150         print_rr_weight(buff, 13, &mp->rr_weight);
151         condlog(3, "%s: rr_weight = %s %s", mp->alias, buff, origin);
152         return 0;
153 }
154
155 int select_pgfailback(struct config *conf, struct multipath * mp)
156 {
157         char *origin, buff[13];
158
159         mp_set_mpe(pgfailback);
160         mp_set_ovr(pgfailback);
161         mp_set_hwe(pgfailback);
162         mp_set_conf(pgfailback);
163         mp_set_default(pgfailback, DEFAULT_FAILBACK);
164 out:
165         print_pgfailback(buff, 13, &mp->pgfailback);
166         condlog(3, "%s: failback = %s %s", mp->alias, buff, origin);
167         return 0;
168 }
169
170 int select_pgpolicy(struct config *conf, struct multipath * mp)
171 {
172         char *origin, buff[POLICY_NAME_SIZE];
173
174         if (conf->pgpolicy_flag > 0) {
175                 mp->pgpolicy = conf->pgpolicy_flag;
176                 origin = "(setting: multipath command line [-p] flag)";
177                 goto out;
178         }
179         mp_set_mpe(pgpolicy);
180         mp_set_ovr(pgpolicy);
181         mp_set_hwe(pgpolicy);
182         mp_set_conf(pgpolicy);
183         mp_set_default(pgpolicy, DEFAULT_PGPOLICY);
184 out:
185         mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
186         get_pgpolicy_name(buff, POLICY_NAME_SIZE, mp->pgpolicy);
187         condlog(3, "%s: path_grouping_policy = %s %s", mp->alias, buff, origin);
188         return 0;
189 }
190
191 int select_selector(struct config *conf, struct multipath * mp)
192 {
193         char *origin;
194
195         mp_set_mpe(selector);
196         mp_set_ovr(selector);
197         mp_set_hwe(selector);
198         mp_set_conf(selector);
199         mp_set_default(selector, DEFAULT_SELECTOR);
200 out:
201         mp->selector = STRDUP(mp->selector);
202         condlog(3, "%s: path_selector = \"%s\" %s", mp->alias, mp->selector,
203                 origin);
204         return 0;
205 }
206
207 static void
208 select_alias_prefix (struct config *conf, struct multipath * mp)
209 {
210         char *origin;
211
212         mp_set_ovr(alias_prefix);
213         mp_set_hwe(alias_prefix);
214         mp_set_conf(alias_prefix);
215         mp_set_default(alias_prefix, DEFAULT_ALIAS_PREFIX);
216 out:
217         condlog(3, "%s: alias_prefix = %s %s", mp->wwid, mp->alias_prefix,
218                 origin);
219 }
220
221 static int
222 want_user_friendly_names(struct config *conf, struct multipath * mp)
223 {
224
225         char *origin;
226         int user_friendly_names;
227
228         do_set(user_friendly_names, mp->mpe, user_friendly_names,
229                "(setting: multipath.conf multipaths section)");
230         do_set(user_friendly_names, conf->overrides, user_friendly_names,
231                "(setting: multipath.conf overrides section)");
232         do_set(user_friendly_names, mp->hwe, user_friendly_names,
233                "(setting: storage device configuration)");
234         do_set(user_friendly_names, conf, user_friendly_names,
235                "(setting: multipath.conf defaults/devices section)");
236         do_default(user_friendly_names, DEFAULT_USER_FRIENDLY_NAMES);
237 out:
238         condlog(3, "%s: user_friendly_names = %s %s", mp->wwid,
239                 (user_friendly_names == USER_FRIENDLY_NAMES_ON)? "yes" : "no",
240                 origin);
241         return (user_friendly_names == USER_FRIENDLY_NAMES_ON);
242 }
243
244 int select_alias(struct config *conf, struct multipath * mp)
245 {
246         char *origin = NULL;
247
248         if (mp->mpe && mp->mpe->alias) {
249                 mp->alias = STRDUP(mp->mpe->alias);
250                 origin = "(setting: multipath.conf multipaths section)";
251                 goto out;
252         }
253
254         mp->alias = NULL;
255         if (!want_user_friendly_names(conf, mp))
256                 goto out;
257
258         select_alias_prefix(conf, mp);
259
260         if (strlen(mp->alias_old) > 0) {
261                 mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
262                                 mp->alias_old, mp->alias_prefix,
263                                 conf->bindings_read_only);
264                 memset (mp->alias_old, 0, WWID_SIZE);
265                 origin = "(setting: using existing alias)";
266         }
267
268         if (mp->alias == NULL) {
269                 mp->alias = get_user_friendly_alias(mp->wwid,
270                                 conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
271                 origin = "(setting: user_friendly_name)";
272         }
273 out:
274         if (mp->alias == NULL) {
275                 mp->alias = STRDUP(mp->wwid);
276                 origin = "(setting: default to WWID)";
277         }
278         if (mp->alias)
279                 condlog(3, "%s: alias = %s %s", mp->wwid, mp->alias, origin);
280         return mp->alias ? 0 : 1;
281 }
282
283 void reconcile_features_with_options(const char *id, char **features, int* no_path_retry,
284                   int *retain_hwhandler)
285 {
286         static const char q_i_n_p[] = "queue_if_no_path";
287         static const char r_a_h_h[] = "retain_attached_hw_handler";
288         char buff[12];
289
290         if (*features == NULL)
291                 return;
292         if (id == NULL)
293                 id = "UNKNOWN";
294
295         /*
296          * We only use no_path_retry internally. The "queue_if_no_path"
297          * device-mapper feature is derived from it when the map is loaded.
298          * For consistency, "queue_if_no_path" is removed from the
299          * internal libmultipath features string.
300          * For backward compatibility we allow 'features "1 queue_if_no_path"';
301          * it's translated into "no_path_retry queue" here.
302          */
303         if (strstr(*features, q_i_n_p)) {
304                 condlog(0, "%s: option 'features \"1 %s\"' is deprecated, "
305                         "please use 'no_path_retry queue' instead",
306                         id, q_i_n_p);
307                 if (*no_path_retry == NO_PATH_RETRY_UNDEF) {
308                         *no_path_retry = NO_PATH_RETRY_QUEUE;
309                         print_no_path_retry(buff, sizeof(buff),
310                                             no_path_retry);
311                         condlog(3, "%s: no_path_retry = %s (inherited setting from feature '%s')",
312                                 id, buff, q_i_n_p);
313                 };
314                 /* Warn only if features string is overridden */
315                 if (*no_path_retry != NO_PATH_RETRY_QUEUE) {
316                         print_no_path_retry(buff, sizeof(buff),
317                                             no_path_retry);
318                         condlog(2, "%s: ignoring feature '%s' because no_path_retry is set to '%s'",
319                                 id, q_i_n_p, buff);
320                 }
321                 remove_feature(features, q_i_n_p);
322         }
323         if (strstr(*features, r_a_h_h)) {
324                 condlog(0, "%s: option 'features \"1 %s\"' is deprecated",
325                         id, r_a_h_h);
326                 if (*retain_hwhandler == RETAIN_HWHANDLER_UNDEF) {
327                         condlog(3, "%s: %s = on (inherited setting from feature '%s')",
328                                 id, r_a_h_h, r_a_h_h);
329                         *retain_hwhandler = RETAIN_HWHANDLER_ON;
330                 } else if (*retain_hwhandler == RETAIN_HWHANDLER_OFF)
331                         condlog(2, "%s: ignoring feature '%s' because %s is set to 'off'",
332                                 id, r_a_h_h, r_a_h_h);
333                 remove_feature(features, r_a_h_h);
334         }
335 }
336
337 int select_features(struct config *conf, struct multipath *mp)
338 {
339         char *origin;
340
341         mp_set_mpe(features);
342         mp_set_ovr(features);
343         mp_set_hwe(features);
344         mp_set_conf(features);
345         mp_set_default(features, DEFAULT_FEATURES);
346 out:
347         mp->features = STRDUP(mp->features);
348
349         reconcile_features_with_options(mp->alias, &mp->features,
350                                         &mp->no_path_retry,
351                                         &mp->retain_hwhandler);
352         condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin);
353         return 0;
354 }
355
356 int select_hwhandler(struct config *conf, struct multipath *mp)
357 {
358         char *origin;
359
360         mp_set_hwe(hwhandler);
361         mp_set_conf(hwhandler);
362         mp_set_default(hwhandler, DEFAULT_HWHANDLER);
363 out:
364         mp->hwhandler = STRDUP(mp->hwhandler);
365         condlog(3, "%s: hardware_handler = \"%s\" %s", mp->alias, mp->hwhandler,
366                 origin);
367         return 0;
368 }
369
370 /*
371  * Current RDAC (NetApp E-Series) firmware relies
372  * on periodic REPORT TARGET PORT GROUPS for
373  * internal load balancing.
374  * Using the sysfs priority checker defeats this purpose.
375  *
376  * Moreover, NetApp would also prefer the RDAC checker over ALUA.
377  * (https://www.redhat.com/archives/dm-devel/2017-September/msg00326.html)
378  */
379 static int
380 check_rdac(struct path * pp)
381 {
382         int len;
383         char buff[44];
384
385         len = get_vpd_sgio(pp->fd, 0xC9, buff, 44);
386         if (len <= 0)
387                 return 0;
388         return !(memcmp(buff + 4, "vac1", 4));
389 }
390
391 int select_checker(struct config *conf, struct path *pp)
392 {
393         char *origin, *checker_name;
394         struct checker * c = &pp->checker;
395
396         if (pp->detect_checker == DETECT_CHECKER_ON) {
397                 origin = "(setting: storage device autodetected)";
398                 if (check_rdac(pp)) {
399                         checker_name = RDAC;
400                         goto out;
401                 } else if (pp->tpgs > 0) {
402                         checker_name = TUR;
403                         goto out;
404                 }
405         }
406         do_set(checker_name, conf->overrides, checker_name, "(setting: multipath.conf overrides section)");
407         do_set(checker_name, pp->hwe, checker_name, "(setting: storage device configuration)");
408         do_set(checker_name, conf, checker_name, "(setting: multipath.conf defaults/devices section)");
409         do_default(checker_name, DEFAULT_CHECKER);
410 out:
411         checker_get(conf->multipath_dir, c, checker_name);
412         condlog(3, "%s: path_checker = %s %s", pp->dev, c->name, origin);
413         if (conf->checker_timeout) {
414                 c->timeout = conf->checker_timeout;
415                 condlog(3, "%s: checker timeout = %u s (setting: multipath.conf defaults/devices section)",
416                                 pp->dev, c->timeout);
417         }
418         else if (sysfs_get_timeout(pp, &c->timeout) > 0)
419                 condlog(3, "%s: checker timeout = %u s (setting: kernel sysfs)",
420                                 pp->dev, c->timeout);
421         else {
422                 c->timeout = DEF_TIMEOUT;
423                 condlog(3, "%s: checker timeout = %u s (setting: multipath internal)",
424                                 pp->dev, c->timeout);
425         }
426         return 0;
427 }
428
429 int select_getuid(struct config *conf, struct path *pp)
430 {
431         char *origin;
432
433         pp->uid_attribute = parse_uid_attribute_by_attrs(conf->uid_attrs, pp->dev);
434         if (pp->uid_attribute) {
435                 origin = "(setting: multipath.conf defaults section)";
436                 goto out;
437         }
438
439         pp_set_ovr(getuid);
440         pp_set_ovr(uid_attribute);
441         pp_set_hwe(getuid);
442         pp_set_hwe(uid_attribute);
443         pp_set_conf(getuid);
444         pp_set_conf(uid_attribute);
445         pp_set_default(uid_attribute, DEFAULT_UID_ATTRIBUTE);
446 out:
447         if (pp->uid_attribute)
448                 condlog(3, "%s: uid_attribute = %s %s", pp->dev,
449                         pp->uid_attribute, origin);
450         else if (pp->getuid)
451                 condlog(3, "%s: getuid = \"%s\" %s", pp->dev, pp->getuid,
452                         origin);
453         return 0;
454 }
455
456 void
457 detect_prio(struct config *conf, struct path * pp)
458 {
459         struct prio *p = &pp->prio;
460         char buff[512];
461         char *default_prio = PRIO_ALUA;
462
463         if (pp->tpgs <= 0)
464                 return;
465         if (pp->tpgs == 2 && !check_rdac(pp)) {
466                 if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
467                         default_prio = PRIO_SYSFS;
468         }
469         prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS);
470 }
471
472 #define set_prio(dir, src, msg)                                 \
473 do {                                                                    \
474         if (src && src->prio_name) {                                    \
475                 prio_get(dir, p, src->prio_name, src->prio_args);       \
476                 origin = msg;                                           \
477                 goto out;                                               \
478         }                                                               \
479 } while(0)
480
481 int select_prio(struct config *conf, struct path *pp)
482 {
483         char *origin;
484         struct mpentry * mpe;
485         struct prio * p = &pp->prio;
486
487         if (pp->detect_prio == DETECT_PRIO_ON) {
488                 detect_prio(conf, pp);
489                 if (prio_selected(p)) {
490                         origin = "(setting: storage device autodetected)";
491                         goto out;
492                 }
493         }
494         mpe = find_mpe(conf->mptable, pp->wwid);
495         set_prio(conf->multipath_dir, mpe, "(setting: multipath.conf multipaths section)");
496         set_prio(conf->multipath_dir, conf->overrides, "(setting: multipath.conf overrides section)");
497         set_prio(conf->multipath_dir, pp->hwe, "(setting: storage device configuration)");
498         set_prio(conf->multipath_dir, conf, "(setting: multipath.conf defaults/devices section)");
499         prio_get(conf->multipath_dir, p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
500         origin = "(setting: multipath internal)";
501 out:
502         /*
503          * fetch tpgs mode for alua, if its not already obtained
504          */
505         if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
506                 int tpgs = 0;
507                 unsigned int timeout = conf->checker_timeout;
508
509                 if(!pp->tpgs &&
510                    (tpgs = get_target_port_group_support(pp->fd, timeout)) >= 0)
511                         pp->tpgs = tpgs;
512         }
513         condlog(3, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
514         condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin);
515         return 0;
516 }
517
518 int select_no_path_retry(struct config *conf, struct multipath *mp)
519 {
520         char *origin = NULL;
521         char buff[12];
522
523         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) {
524                 condlog(0, "%s: flush_on_last_del in progress", mp->alias);
525                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
526                 return 0;
527         }
528         mp_set_mpe(no_path_retry);
529         mp_set_ovr(no_path_retry);
530         mp_set_hwe(no_path_retry);
531         mp_set_conf(no_path_retry);
532 out:
533         print_no_path_retry(buff, 12, &mp->no_path_retry);
534         if (origin)
535                 condlog(3, "%s: no_path_retry = %s %s", mp->alias, buff,
536                         origin);
537         else
538                 condlog(3, "%s: no_path_retry = undef (setting: multipath internal)",
539                         mp->alias);
540         return 0;
541 }
542
543 int
544 select_minio_rq (struct config *conf, struct multipath * mp)
545 {
546         char *origin;
547
548         do_set(minio_rq, mp->mpe, mp->minio, "(setting: multipath.conf multipaths section)");
549         do_set(minio_rq, conf->overrides, mp->minio, "(setting: multipath.conf overrides section)");
550         do_set(minio_rq, mp->hwe, mp->minio, "(setting: storage device configuration)");
551         do_set(minio_rq, conf, mp->minio, "(setting: multipath.conf defaults/devices section)");
552         do_default(mp->minio, DEFAULT_MINIO_RQ);
553 out:
554         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
555         return 0;
556 }
557
558 int
559 select_minio_bio (struct config *conf, struct multipath * mp)
560 {
561         char *origin;
562
563         mp_set_mpe(minio);
564         mp_set_ovr(minio);
565         mp_set_hwe(minio);
566         mp_set_conf(minio);
567         mp_set_default(minio, DEFAULT_MINIO);
568 out:
569         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
570         return 0;
571 }
572
573 int select_minio(struct config *conf, struct multipath *mp)
574 {
575         unsigned int minv_dmrq[3] = {1, 1, 0};
576
577         if (VERSION_GE(conf->version, minv_dmrq))
578                 return select_minio_rq(conf, mp);
579         else
580                 return select_minio_bio(conf, mp);
581 }
582
583 int select_fast_io_fail(struct config *conf, struct multipath *mp)
584 {
585         char *origin, buff[12];
586
587         mp_set_ovr(fast_io_fail);
588         mp_set_hwe(fast_io_fail);
589         mp_set_conf(fast_io_fail);
590         mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL);
591 out:
592         print_fast_io_fail(buff, 12, &mp->fast_io_fail);
593         condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin);
594         return 0;
595 }
596
597 int select_dev_loss(struct config *conf, struct multipath *mp)
598 {
599         char *origin, buff[12];
600
601         mp_set_ovr(dev_loss);
602         mp_set_hwe(dev_loss);
603         mp_set_conf(dev_loss);
604         mp->dev_loss = 0;
605         return 0;
606 out:
607         print_dev_loss(buff, 12, &mp->dev_loss);
608         condlog(3, "%s: dev_loss_tmo = %s %s", mp->alias, buff, origin);
609         return 0;
610 }
611
612 int select_flush_on_last_del(struct config *conf, struct multipath *mp)
613 {
614         char *origin;
615
616         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
617                 return 0;
618         mp_set_mpe(flush_on_last_del);
619         mp_set_ovr(flush_on_last_del);
620         mp_set_hwe(flush_on_last_del);
621         mp_set_conf(flush_on_last_del);
622         mp_set_default(flush_on_last_del, DEFAULT_FLUSH);
623 out:
624         condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
625                 (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
626         return 0;
627 }
628
629 int select_reservation_key(struct config *conf, struct multipath *mp)
630 {
631         char *origin, buff[PRKEY_SIZE];
632         char *from_file = "";
633         uint64_t prkey = 0;
634
635         do_prkey_set(mp->mpe, "(setting: multipath.conf multipaths section)");
636         do_prkey_set(conf, "(setting: multipath.conf defaults/devices section)");
637         put_be64(mp->reservation_key, 0);
638         mp->prkey_source = PRKEY_SOURCE_NONE;
639         return 0;
640 out:
641         if (mp->prkey_source == PRKEY_SOURCE_FILE) {
642                 from_file = " (from prkeys file)";
643                 if (get_prkey(conf, mp, &prkey) != 0)
644                         put_be64(mp->reservation_key, 0);
645                 else
646                         put_be64(mp->reservation_key, prkey);
647         }
648         print_reservation_key(buff, PRKEY_SIZE, mp->reservation_key,
649                               mp->prkey_source);
650         condlog(3, "%s: reservation_key = %s %s%s", mp->alias, buff, origin,
651                 from_file);
652         return 0;
653 }
654
655 int select_retain_hwhandler(struct config *conf, struct multipath *mp)
656 {
657         char *origin;
658         unsigned int minv_dm_retain[3] = {1, 5, 0};
659
660         if (!VERSION_GE(conf->version, minv_dm_retain)) {
661                 mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
662                 origin = "(setting: WARNING, requires kernel dm-mpath version >= 1.5.0)";
663                 goto out;
664         }
665         if (get_linux_version_code() >= KERNEL_VERSION(4, 3, 0)) {
666                 mp->retain_hwhandler = RETAIN_HWHANDLER_ON;
667                 origin = "(setting: implied in kernel >= 4.3.0)";
668                 goto out;
669         }
670         mp_set_ovr(retain_hwhandler);
671         mp_set_hwe(retain_hwhandler);
672         mp_set_conf(retain_hwhandler);
673         mp_set_default(retain_hwhandler, DEFAULT_RETAIN_HWHANDLER);
674 out:
675         condlog(3, "%s: retain_attached_hw_handler = %s %s", mp->alias,
676                 (mp->retain_hwhandler == RETAIN_HWHANDLER_ON)? "yes" : "no",
677                 origin);
678         return 0;
679 }
680
681 int select_detect_prio(struct config *conf, struct path *pp)
682 {
683         char *origin;
684
685         pp_set_ovr(detect_prio);
686         pp_set_hwe(detect_prio);
687         pp_set_conf(detect_prio);
688         pp_set_default(detect_prio, DEFAULT_DETECT_PRIO);
689 out:
690         condlog(3, "%s: detect_prio = %s %s", pp->dev,
691                 (pp->detect_prio == DETECT_PRIO_ON)? "yes" : "no", origin);
692         return 0;
693 }
694
695 int select_detect_checker(struct config *conf, struct path *pp)
696 {
697         char *origin;
698
699         pp_set_ovr(detect_checker);
700         pp_set_hwe(detect_checker);
701         pp_set_conf(detect_checker);
702         pp_set_default(detect_checker, DEFAULT_DETECT_CHECKER);
703 out:
704         condlog(3, "%s: detect_checker = %s %s", pp->dev,
705                 (pp->detect_checker == DETECT_CHECKER_ON)? "yes" : "no",
706                 origin);
707         return 0;
708 }
709
710 int select_deferred_remove(struct config *conf, struct multipath *mp)
711 {
712         char *origin;
713
714 #ifndef LIBDM_API_DEFERRED
715         mp->deferred_remove = DEFERRED_REMOVE_OFF;
716         origin = "(setting: WARNING, not compiled with support)";
717         goto out;
718 #endif
719         if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
720                 condlog(3, "%s: deferred remove in progress", mp->alias);
721                 return 0;
722         }
723         mp_set_mpe(deferred_remove);
724         mp_set_ovr(deferred_remove);
725         mp_set_hwe(deferred_remove);
726         mp_set_conf(deferred_remove);
727         mp_set_default(deferred_remove, DEFAULT_DEFERRED_REMOVE);
728 out:
729         condlog(3, "%s: deferred_remove = %s %s", mp->alias,
730                 (mp->deferred_remove == DEFERRED_REMOVE_ON)? "yes" : "no",
731                 origin);
732         return 0;
733 }
734
735 int select_delay_watch_checks(struct config *conf, struct multipath *mp)
736 {
737         char *origin, buff[12];
738
739         mp_set_mpe(delay_watch_checks);
740         mp_set_ovr(delay_watch_checks);
741         mp_set_hwe(delay_watch_checks);
742         mp_set_conf(delay_watch_checks);
743         mp_set_default(delay_watch_checks, DEFAULT_DELAY_CHECKS);
744 out:
745         print_off_int_undef(buff, 12, &mp->delay_watch_checks);
746         condlog(3, "%s: delay_watch_checks = %s %s", mp->alias, buff, origin);
747         return 0;
748 }
749
750 int select_delay_wait_checks(struct config *conf, struct multipath *mp)
751 {
752         char *origin, buff[12];
753
754         mp_set_mpe(delay_wait_checks);
755         mp_set_ovr(delay_wait_checks);
756         mp_set_hwe(delay_wait_checks);
757         mp_set_conf(delay_wait_checks);
758         mp_set_default(delay_wait_checks, DEFAULT_DELAY_CHECKS);
759 out:
760         print_off_int_undef(buff, 12, &mp->delay_wait_checks);
761         condlog(3, "%s: delay_wait_checks = %s %s", mp->alias, buff, origin);
762         return 0;
763
764 }
765
766 int select_marginal_path_err_sample_time(struct config *conf, struct multipath *mp)
767 {
768         char *origin, buff[12];
769
770         mp_set_mpe(marginal_path_err_sample_time);
771         mp_set_ovr(marginal_path_err_sample_time);
772         mp_set_hwe(marginal_path_err_sample_time);
773         mp_set_conf(marginal_path_err_sample_time);
774         mp_set_default(marginal_path_err_sample_time, DEFAULT_ERR_CHECKS);
775 out:
776         print_off_int_undef(buff, 12, &mp->marginal_path_err_sample_time);
777         condlog(3, "%s: marginal_path_err_sample_time = %s %s", mp->alias, buff,
778                         origin);
779         return 0;
780 }
781
782 int select_marginal_path_err_rate_threshold(struct config *conf, struct multipath *mp)
783 {
784         char *origin, buff[12];
785
786         mp_set_mpe(marginal_path_err_rate_threshold);
787         mp_set_ovr(marginal_path_err_rate_threshold);
788         mp_set_hwe(marginal_path_err_rate_threshold);
789         mp_set_conf(marginal_path_err_rate_threshold);
790         mp_set_default(marginal_path_err_rate_threshold, DEFAULT_ERR_CHECKS);
791 out:
792         print_off_int_undef(buff, 12, &mp->marginal_path_err_rate_threshold);
793         condlog(3, "%s: marginal_path_err_rate_threshold = %s %s", mp->alias, buff,
794                         origin);
795         return 0;
796 }
797
798 int select_marginal_path_err_recheck_gap_time(struct config *conf, struct multipath *mp)
799 {
800         char *origin, buff[12];
801
802         mp_set_mpe(marginal_path_err_recheck_gap_time);
803         mp_set_ovr(marginal_path_err_recheck_gap_time);
804         mp_set_hwe(marginal_path_err_recheck_gap_time);
805         mp_set_conf(marginal_path_err_recheck_gap_time);
806         mp_set_default(marginal_path_err_recheck_gap_time, DEFAULT_ERR_CHECKS);
807 out:
808         print_off_int_undef(buff, 12, &mp->marginal_path_err_recheck_gap_time);
809         condlog(3, "%s: marginal_path_err_recheck_gap_time = %s %s", mp->alias, buff,
810                         origin);
811         return 0;
812 }
813
814 int select_marginal_path_double_failed_time(struct config *conf, struct multipath *mp)
815 {
816         char *origin, buff[12];
817
818         mp_set_mpe(marginal_path_double_failed_time);
819         mp_set_ovr(marginal_path_double_failed_time);
820         mp_set_hwe(marginal_path_double_failed_time);
821         mp_set_conf(marginal_path_double_failed_time);
822         mp_set_default(marginal_path_double_failed_time, DEFAULT_ERR_CHECKS);
823 out:
824         print_off_int_undef(buff, 12, &mp->marginal_path_double_failed_time);
825         condlog(3, "%s: marginal_path_double_failed_time = %s %s", mp->alias, buff,
826                         origin);
827         return 0;
828 }
829
830 int select_skip_kpartx (struct config *conf, struct multipath * mp)
831 {
832         char *origin;
833
834         mp_set_mpe(skip_kpartx);
835         mp_set_ovr(skip_kpartx);
836         mp_set_hwe(skip_kpartx);
837         mp_set_conf(skip_kpartx);
838         mp_set_default(skip_kpartx, DEFAULT_SKIP_KPARTX);
839 out:
840         condlog(3, "%s: skip_kpartx = %s %s", mp->alias,
841                 (mp->skip_kpartx == SKIP_KPARTX_ON)? "yes" : "no",
842                 origin);
843         return 0;
844 }
845
846 int select_max_sectors_kb(struct config *conf, struct multipath * mp)
847 {
848         char *origin;
849
850         mp_set_mpe(max_sectors_kb);
851         mp_set_ovr(max_sectors_kb);
852         mp_set_hwe(max_sectors_kb);
853         mp_set_conf(max_sectors_kb);
854         mp_set_default(max_sectors_kb, DEFAULT_MAX_SECTORS_KB);
855         /*
856          * In the default case, we will not modify max_sectors_kb in sysfs
857          * (see sysfs_set_max_sectors_kb()).
858          * Don't print a log message here to avoid user confusion.
859          */
860         return 0;
861 out:
862         condlog(3, "%s: max_sectors_kb = %i %s", mp->alias, mp->max_sectors_kb,
863                 origin);
864         return 0;
865 }
866
867 int select_ghost_delay (struct config *conf, struct multipath * mp)
868 {
869         char *origin, buff[12];
870
871         mp_set_mpe(ghost_delay);
872         mp_set_ovr(ghost_delay);
873         mp_set_hwe(ghost_delay);
874         mp_set_conf(ghost_delay);
875         mp_set_default(ghost_delay, DEFAULT_GHOST_DELAY);
876 out:
877         print_off_int_undef(buff, 12, &mp->ghost_delay);
878         condlog(3, "%s: ghost_delay = %s %s", mp->alias, buff, origin);
879         return 0;
880 }