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