a842fc39b2df6f9a700e63b5037f812016241de6
[platform/upstream/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 "nvme-lib.h"
9 #include "checkers.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 "strbuf.h"
27 #include <inttypes.h>
28 #include <libudev.h>
29
30 pgpolicyfn *pgpolicies[] = {
31         NULL,
32         one_path_per_group,
33         one_group,
34         group_by_serial,
35         group_by_prio,
36         group_by_node_name
37 };
38
39 #define do_set(var, src, dest, msg)                                     \
40 do {                                                                    \
41         if (src && src->var) {                                          \
42                 dest = src->var;                                        \
43                 origin = msg;                                           \
44                 goto out;                                               \
45         }                                                               \
46 } while(0)
47
48 #define __do_set_from_vec(type, var, src, dest)                         \
49 ({                                                                      \
50         type *_p;                                                       \
51         bool _found = false;                                            \
52         int i;                                                          \
53                                                                         \
54         vector_foreach_slot(src, _p, i) {                               \
55                 if (_p->var) {                                          \
56                         dest = _p->var;                                 \
57                         _found = true;                                  \
58                         break;                                          \
59                 }                                                       \
60         }                                                               \
61         _found;                                                         \
62 })
63
64 #define __do_set_from_hwe(var, src, dest) \
65         __do_set_from_vec(struct hwentry, var, (src)->hwe, dest)
66
67 #define do_set_from_hwe(var, src, dest, msg)                            \
68         if (src->hwe && __do_set_from_hwe(var, src, dest)) {            \
69                 origin = msg;                                           \
70                 goto out;                                               \
71         }
72
73 static const char default_origin[] = "(setting: multipath internal)";
74 static const char hwe_origin[] =
75         "(setting: storage device configuration)";
76 static const char multipaths_origin[] =
77         "(setting: multipath.conf multipaths section)";
78 static const char conf_origin[] =
79         "(setting: multipath.conf defaults/devices section)";
80 static const char overrides_origin[] =
81         "(setting: multipath.conf overrides section)";
82 static const char cmdline_origin[] =
83         "(setting: multipath command line [-p] flag)";
84 static const char autodetect_origin[] =
85         "(setting: storage device autodetected)";
86 static const char marginal_path_origin[] =
87         "(setting: implied by marginal_path check)";
88 static const char delay_watch_origin[] =
89         "(setting: implied by delay_watch_checks)";
90 static const char delay_wait_origin[] =
91         "(setting: implied by delay_wait_checks)";
92
93 #define do_default(dest, value)                                         \
94 do {                                                                    \
95         dest = value;                                                   \
96         origin = default_origin;                                        \
97 } while(0)
98
99 #define mp_set_mpe(var)                                                 \
100 do_set(var, mp->mpe, mp->var, multipaths_origin)
101 #define mp_set_hwe(var)                                                 \
102 do_set_from_hwe(var, mp, mp->var, hwe_origin)
103 #define mp_set_ovr(var)                                                 \
104 do_set(var, conf->overrides, mp->var, overrides_origin)
105 #define mp_set_conf(var)                                                \
106 do_set(var, conf, mp->var, conf_origin)
107 #define mp_set_default(var, value)                                      \
108 do_default(mp->var, value)
109
110 #define pp_set_mpe(var)                                                 \
111 do_set(var, mpe, pp->var, multipaths_origin)
112 #define pp_set_hwe(var)                                                 \
113 do_set_from_hwe(var, pp, pp->var, hwe_origin)
114 #define pp_set_conf(var)                                                \
115 do_set(var, conf, pp->var, conf_origin)
116 #define pp_set_ovr(var)                                                 \
117 do_set(var, conf->overrides, pp->var, overrides_origin)
118 #define pp_set_default(var, value)                                      \
119 do_default(pp->var, value)
120
121 #define do_attr_set(var, src, shift, msg)                               \
122 do {                                                                    \
123         if (src && (src->attribute_flags & (1 << shift))) {             \
124                 mp->attribute_flags |= (1 << shift);                    \
125                 mp->var = src->var;                                     \
126                 origin = msg;                                           \
127                 goto out;                                               \
128         }                                                               \
129 } while(0)
130
131 #define set_attr_mpe(var, shift)                                        \
132 do_attr_set(var, mp->mpe, shift, "(setting: multipath.conf multipaths section)")
133 #define set_attr_conf(var, shift)                                       \
134 do_attr_set(var, conf, shift, "(setting: multipath.conf defaults/devices section)")
135
136 #define do_prkey_set(src, msg)                                          \
137 do {                                                                    \
138         if (src && src->prkey_source != PRKEY_SOURCE_NONE) {            \
139                 mp->prkey_source = src->prkey_source;                   \
140                 mp->reservation_key = src->reservation_key;             \
141                 mp->sa_flags = src->sa_flags;                           \
142                 origin = msg;                                           \
143                 goto out;                                               \
144         }                                                               \
145 } while (0)
146
147 int select_mode(struct config *conf, struct multipath *mp)
148 {
149         const char *origin;
150
151         set_attr_mpe(mode, ATTR_MODE);
152         set_attr_conf(mode, ATTR_MODE);
153         mp->attribute_flags &= ~(1 << ATTR_MODE);
154         return 0;
155 out:
156         condlog(3, "%s: mode = 0%o %s", mp->alias, mp->mode, origin);
157         return 0;
158 }
159
160 int select_uid(struct config *conf, struct multipath *mp)
161 {
162         const char *origin;
163
164         set_attr_mpe(uid, ATTR_UID);
165         set_attr_conf(uid, ATTR_UID);
166         mp->attribute_flags &= ~(1 << ATTR_UID);
167         return 0;
168 out:
169         condlog(3, "%s: uid = 0%o %s", mp->alias, mp->uid, origin);
170         return 0;
171 }
172
173 int select_gid(struct config *conf, struct multipath *mp)
174 {
175         const char *origin;
176
177         set_attr_mpe(gid, ATTR_GID);
178         set_attr_conf(gid, ATTR_GID);
179         mp->attribute_flags &= ~(1 << ATTR_GID);
180         return 0;
181 out:
182         condlog(3, "%s: gid = 0%o %s", mp->alias, mp->gid, origin);
183         return 0;
184 }
185
186 /*
187  * selectors :
188  * traverse the configuration layers from most specific to most generic
189  * stop at first explicit setting found
190  */
191 int select_rr_weight(struct config *conf, struct multipath * mp)
192 {
193         const char *origin;
194         STRBUF_ON_STACK(buff);
195
196         mp_set_mpe(rr_weight);
197         mp_set_ovr(rr_weight);
198         mp_set_hwe(rr_weight);
199         mp_set_conf(rr_weight);
200         mp_set_default(rr_weight, DEFAULT_RR_WEIGHT);
201 out:
202         print_rr_weight(&buff, mp->rr_weight);
203         condlog(3, "%s: rr_weight = %s %s", mp->alias,
204                 get_strbuf_str(&buff), origin);
205         return 0;
206 }
207
208 int select_pgfailback(struct config *conf, struct multipath * mp)
209 {
210         const char *origin;
211         STRBUF_ON_STACK(buff);
212
213         mp_set_mpe(pgfailback);
214         mp_set_ovr(pgfailback);
215         mp_set_hwe(pgfailback);
216         mp_set_conf(pgfailback);
217         mp_set_default(pgfailback, DEFAULT_FAILBACK);
218 out:
219         print_pgfailback(&buff, mp->pgfailback);
220         condlog(3, "%s: failback = %s %s", mp->alias,
221                 get_strbuf_str(&buff), origin);
222         return 0;
223 }
224
225 int select_pgpolicy(struct config *conf, struct multipath * mp)
226 {
227         const char *origin;
228         char buff[POLICY_NAME_SIZE];
229
230         if (conf->pgpolicy_flag > 0) {
231                 mp->pgpolicy = conf->pgpolicy_flag;
232                 origin = cmdline_origin;
233                 goto out;
234         }
235         mp_set_mpe(pgpolicy);
236         mp_set_ovr(pgpolicy);
237         mp_set_hwe(pgpolicy);
238         mp_set_conf(pgpolicy);
239         mp_set_default(pgpolicy, DEFAULT_PGPOLICY);
240 out:
241         mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
242         get_pgpolicy_name(buff, POLICY_NAME_SIZE, mp->pgpolicy);
243         condlog(3, "%s: path_grouping_policy = %s %s", mp->alias, buff, origin);
244         return 0;
245 }
246
247 int select_selector(struct config *conf, struct multipath * mp)
248 {
249         const char *origin;
250
251         mp_set_mpe(selector);
252         mp_set_ovr(selector);
253         mp_set_hwe(selector);
254         mp_set_conf(selector);
255         mp_set_default(selector, DEFAULT_SELECTOR);
256 out:
257         mp->selector = strdup(mp->selector);
258         condlog(3, "%s: path_selector = \"%s\" %s", mp->alias, mp->selector,
259                 origin);
260         return 0;
261 }
262
263 static void
264 select_alias_prefix (struct config *conf, struct multipath * mp)
265 {
266         const char *origin;
267
268         mp_set_ovr(alias_prefix);
269         mp_set_hwe(alias_prefix);
270         mp_set_conf(alias_prefix);
271         mp_set_default(alias_prefix, DEFAULT_ALIAS_PREFIX);
272 out:
273         condlog(3, "%s: alias_prefix = %s %s", mp->wwid, mp->alias_prefix,
274                 origin);
275 }
276
277 static int
278 want_user_friendly_names(struct config *conf, struct multipath * mp)
279 {
280
281         const char *origin;
282         int user_friendly_names;
283
284         do_set(user_friendly_names, mp->mpe, user_friendly_names,
285                multipaths_origin);
286         do_set(user_friendly_names, conf->overrides, user_friendly_names,
287                overrides_origin);
288         do_set_from_hwe(user_friendly_names, mp, user_friendly_names,
289                         hwe_origin);
290         do_set(user_friendly_names, conf, user_friendly_names,
291                conf_origin);
292         do_default(user_friendly_names, DEFAULT_USER_FRIENDLY_NAMES);
293 out:
294         condlog(3, "%s: user_friendly_names = %s %s", mp->wwid,
295                 (user_friendly_names == USER_FRIENDLY_NAMES_ON)? "yes" : "no",
296                 origin);
297         return (user_friendly_names == USER_FRIENDLY_NAMES_ON);
298 }
299
300 int select_alias(struct config *conf, struct multipath * mp)
301 {
302         const char *origin = NULL;
303
304         if (mp->mpe && mp->mpe->alias) {
305                 mp->alias = strdup(mp->mpe->alias);
306                 origin = multipaths_origin;
307                 goto out;
308         }
309
310         mp->alias = NULL;
311         if (!want_user_friendly_names(conf, mp))
312                 goto out;
313
314         select_alias_prefix(conf, mp);
315
316         if (strlen(mp->alias_old) > 0) {
317                 mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
318                                 mp->alias_old, mp->alias_prefix,
319                                 conf->bindings_read_only);
320                 memset (mp->alias_old, 0, WWID_SIZE);
321                 origin = "(setting: using existing alias)";
322         }
323
324         if (mp->alias == NULL) {
325                 mp->alias = get_user_friendly_alias(mp->wwid,
326                                 conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
327                 origin = "(setting: user_friendly_name)";
328         }
329 out:
330         if (mp->alias == NULL) {
331                 mp->alias = strdup(mp->wwid);
332                 origin = "(setting: default to WWID)";
333         }
334         if (mp->alias)
335                 condlog(3, "%s: alias = %s %s", mp->wwid, mp->alias, origin);
336         return mp->alias ? 0 : 1;
337 }
338
339 void reconcile_features_with_options(const char *id, char **features, int* no_path_retry,
340                   int *retain_hwhandler)
341 {
342         static const char q_i_n_p[] = "queue_if_no_path";
343         static const char r_a_h_h[] = "retain_attached_hw_handler";
344         STRBUF_ON_STACK(buff);
345
346         if (*features == NULL)
347                 return;
348         if (id == NULL)
349                 id = "UNKNOWN";
350
351         /*
352          * We only use no_path_retry internally. The "queue_if_no_path"
353          * device-mapper feature is derived from it when the map is loaded.
354          * For consistency, "queue_if_no_path" is removed from the
355          * internal libmultipath features string.
356          * For backward compatibility we allow 'features "1 queue_if_no_path"';
357          * it's translated into "no_path_retry queue" here.
358          */
359         if (strstr(*features, q_i_n_p)) {
360                 condlog(0, "%s: option 'features \"1 %s\"' is deprecated, "
361                         "please use 'no_path_retry queue' instead",
362                         id, q_i_n_p);
363                 if (*no_path_retry == NO_PATH_RETRY_UNDEF) {
364                         *no_path_retry = NO_PATH_RETRY_QUEUE;
365                         print_no_path_retry(&buff, *no_path_retry);
366                         condlog(3, "%s: no_path_retry = %s (inherited setting from feature '%s')",
367                                 id, get_strbuf_str(&buff), q_i_n_p);
368                 };
369                 /* Warn only if features string is overridden */
370                 if (*no_path_retry != NO_PATH_RETRY_QUEUE) {
371                         print_no_path_retry(&buff, *no_path_retry);
372                         condlog(2, "%s: ignoring feature '%s' because no_path_retry is set to '%s'",
373                                 id, q_i_n_p, get_strbuf_str(&buff));
374                 }
375                 remove_feature(features, q_i_n_p);
376         }
377         if (strstr(*features, r_a_h_h)) {
378                 condlog(0, "%s: option 'features \"1 %s\"' is deprecated",
379                         id, r_a_h_h);
380                 if (*retain_hwhandler == RETAIN_HWHANDLER_UNDEF) {
381                         condlog(3, "%s: %s = on (inherited setting from feature '%s')",
382                                 id, r_a_h_h, r_a_h_h);
383                         *retain_hwhandler = RETAIN_HWHANDLER_ON;
384                 } else if (*retain_hwhandler == RETAIN_HWHANDLER_OFF)
385                         condlog(2, "%s: ignoring feature '%s' because %s is set to 'off'",
386                                 id, r_a_h_h, r_a_h_h);
387                 remove_feature(features, r_a_h_h);
388         }
389 }
390
391 int select_features(struct config *conf, struct multipath *mp)
392 {
393         const char *origin;
394
395         mp_set_mpe(features);
396         mp_set_ovr(features);
397         mp_set_hwe(features);
398         mp_set_conf(features);
399         mp_set_default(features, DEFAULT_FEATURES);
400 out:
401         mp->features = strdup(mp->features);
402
403         reconcile_features_with_options(mp->alias, &mp->features,
404                                         &mp->no_path_retry,
405                                         &mp->retain_hwhandler);
406         condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin);
407         return 0;
408 }
409
410 static int get_dh_state(struct path *pp, char *value, size_t value_len)
411 {
412         struct udev_device *ud;
413
414         if (pp->udev == NULL)
415                 return -1;
416
417         ud = udev_device_get_parent_with_subsystem_devtype(
418                 pp->udev, "scsi", "scsi_device");
419         if (ud == NULL)
420                 return -1;
421
422         return sysfs_attr_get_value(ud, "dh_state", value, value_len);
423 }
424
425 int select_hwhandler(struct config *conf, struct multipath *mp)
426 {
427         const char *origin;
428         struct path *pp;
429         /* dh_state is no longer than "detached" */
430         char handler[12];
431         static char alua_name[] = "1 alua";
432         static const char tpgs_origin[]= "(setting: autodetected from TPGS)";
433         char *dh_state;
434         int i;
435         bool all_tpgs = true, one_tpgs = false;
436
437         dh_state = &handler[2];
438
439         /*
440          * TPGS_UNDEF means that ALUA support couldn't determined either way
441          * yet, probably because the path was always down.
442          * If at least one path does have TPGS support, and no path has
443          * TPGS_NONE, assume that TPGS would be supported by all paths if
444          * all were up.
445          */
446         vector_foreach_slot(mp->paths, pp, i) {
447                 int tpgs = path_get_tpgs(pp);
448
449                 all_tpgs = all_tpgs && tpgs != TPGS_NONE;
450                 one_tpgs = one_tpgs ||
451                         (tpgs != TPGS_NONE && tpgs != TPGS_UNDEF);
452         }
453         all_tpgs = all_tpgs && one_tpgs;
454
455         if (mp->retain_hwhandler != RETAIN_HWHANDLER_OFF) {
456                 vector_foreach_slot(mp->paths, pp, i) {
457                         if (get_dh_state(pp, dh_state, sizeof(handler) - 2) > 0
458                             && strcmp(dh_state, "detached")) {
459                                 memcpy(handler, "1 ", 2);
460                                 mp->hwhandler = handler;
461                                 origin = "(setting: retained by kernel driver)";
462                                 goto out;
463                         }
464                 }
465         }
466
467         mp_set_hwe(hwhandler);
468         mp_set_conf(hwhandler);
469         mp_set_default(hwhandler, DEFAULT_HWHANDLER);
470 out:
471         if (all_tpgs && !strcmp(mp->hwhandler, DEFAULT_HWHANDLER) &&
472                 origin == default_origin) {
473                 mp->hwhandler = alua_name;
474                 origin = tpgs_origin;
475         } else if (!all_tpgs && !strcmp(mp->hwhandler, alua_name)) {
476                 mp->hwhandler = DEFAULT_HWHANDLER;
477                 origin = tpgs_origin;
478         }
479         mp->hwhandler = strdup(mp->hwhandler);
480         condlog(3, "%s: hardware_handler = \"%s\" %s", mp->alias, mp->hwhandler,
481                 origin);
482         return 0;
483 }
484
485 /*
486  * Current RDAC (NetApp E-Series) firmware relies
487  * on periodic REPORT TARGET PORT GROUPS for
488  * internal load balancing.
489  * Using the sysfs priority checker defeats this purpose.
490  *
491  * Moreover, NetApp would also prefer the RDAC checker over ALUA.
492  * (https://www.redhat.com/archives/dm-devel/2017-September/msg00326.html)
493  */
494 static int
495 check_rdac(struct path * pp)
496 {
497         int len;
498         char buff[44];
499         const char *checker_name = NULL;
500
501         if (pp->bus != SYSFS_BUS_SCSI)
502                 return 0;
503         /* Avoid checking 0xc9 if this is likely not an RDAC array */
504         if (!__do_set_from_hwe(checker_name, pp, checker_name) &&
505             !is_vpd_page_supported(pp->fd, 0xC9))
506                 return 0;
507         if (checker_name && strcmp(checker_name, RDAC))
508                 return 0;
509         len = get_vpd_sgio(pp->fd, 0xC9, 0, buff, 44);
510         if (len <= 0)
511                 return 0;
512         return !(memcmp(buff + 4, "vac1", 4));
513 }
514
515 int select_checker(struct config *conf, struct path *pp)
516 {
517         const char *origin;
518         char *ckr_name;
519         struct checker * c = &pp->checker;
520
521         if (pp->detect_checker == DETECT_CHECKER_ON) {
522                 origin = autodetect_origin;
523                 if (check_rdac(pp)) {
524                         ckr_name = RDAC;
525                         goto out;
526                 }
527                 (void)path_get_tpgs(pp);
528                 if (pp->tpgs != TPGS_NONE && pp->tpgs != TPGS_UNDEF) {
529                         ckr_name = TUR;
530                         goto out;
531                 }
532         }
533         do_set(checker_name, conf->overrides, ckr_name, overrides_origin);
534         do_set_from_hwe(checker_name, pp, ckr_name, hwe_origin);
535         do_set(checker_name, conf, ckr_name, conf_origin);
536         do_default(ckr_name, DEFAULT_CHECKER);
537 out:
538         checker_get(conf->multipath_dir, c, ckr_name);
539         condlog(3, "%s: path_checker = %s %s", pp->dev,
540                 checker_name(c), origin);
541         if (conf->checker_timeout) {
542                 c->timeout = conf->checker_timeout;
543                 condlog(3, "%s: checker timeout = %u s %s",
544                         pp->dev, c->timeout, conf_origin);
545         }
546         else if (sysfs_get_timeout(pp, &c->timeout) > 0)
547                 condlog(3, "%s: checker timeout = %u s (setting: kernel sysfs)",
548                         pp->dev, c->timeout);
549         else {
550                 c->timeout = DEF_TIMEOUT;
551                 condlog(3, "%s: checker timeout = %u s %s",
552                         pp->dev, c->timeout, default_origin);
553         }
554         return 0;
555 }
556
557 int select_getuid(struct config *conf, struct path *pp)
558 {
559         const char *origin;
560
561         pp->uid_attribute = get_uid_attribute_by_attrs(conf, pp->dev);
562         if (pp->uid_attribute) {
563                 origin = "(setting: multipath.conf defaults section / uid_attrs)";
564                 goto out;
565         }
566
567         pp_set_ovr(getuid);
568         pp_set_ovr(uid_attribute);
569         pp_set_hwe(getuid);
570         pp_set_hwe(uid_attribute);
571         pp_set_conf(getuid);
572         pp_set_conf(uid_attribute);
573         pp_set_default(uid_attribute, DEFAULT_UID_ATTRIBUTE);
574 out:
575         if (pp->uid_attribute)
576                 condlog(3, "%s: uid_attribute = %s %s", pp->dev,
577                         pp->uid_attribute, origin);
578         else if (pp->getuid)
579                 condlog(3, "%s: getuid = \"%s\" %s", pp->dev, pp->getuid,
580                         origin);
581         return 0;
582 }
583
584 /* must be called after select_getuid */
585 int select_recheck_wwid(struct config *conf, struct path * pp)
586 {
587         const char *origin;
588
589         pp_set_ovr(recheck_wwid);
590         pp_set_hwe(recheck_wwid);
591         pp_set_conf(recheck_wwid);
592         pp_set_default(recheck_wwid, DEFAULT_RECHECK_WWID);
593 out:
594         if (pp->recheck_wwid == RECHECK_WWID_ON &&
595             (pp->bus != SYSFS_BUS_SCSI || pp->getuid != NULL ||
596              !has_uid_fallback(pp))) {
597                 pp->recheck_wwid = RECHECK_WWID_OFF;
598                 origin = "(setting: unsupported by device type/config)";
599         }
600         condlog(3, "%s: recheck_wwid = %i %s", pp->dev, pp->recheck_wwid,
601                 origin);
602         return 0;
603 }
604
605 void
606 detect_prio(struct config *conf, struct path * pp)
607 {
608         struct prio *p = &pp->prio;
609         char buff[512];
610         char *default_prio;
611         int tpgs;
612
613         switch(pp->bus) {
614         case SYSFS_BUS_NVME:
615                 if (nvme_id_ctrl_ana(pp->fd, NULL) == 0)
616                         return;
617                 default_prio = PRIO_ANA;
618                 break;
619         case SYSFS_BUS_SCSI:
620                 tpgs = path_get_tpgs(pp);
621                 if (tpgs == TPGS_NONE)
622                         return;
623                 if ((tpgs == TPGS_EXPLICIT || !check_rdac(pp)) &&
624                     sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
625                         default_prio = PRIO_SYSFS;
626                 else
627                         default_prio = PRIO_ALUA;
628                 break;
629         default:
630                 return;
631         }
632         prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS);
633 }
634
635 #define set_prio(dir, src, msg)                                 \
636 do {                                                                    \
637         if (src && src->prio_name) {                                    \
638                 prio_get(dir, p, src->prio_name, src->prio_args);       \
639                 origin = msg;                                           \
640                 goto out;                                               \
641         }                                                               \
642 } while(0)
643
644 #define set_prio_from_vec(type, dir, src, msg, p)                       \
645 do {                                                                    \
646         type *_p;                                                       \
647         int i;                                                          \
648         char *prio_name = NULL, *prio_args = NULL;                      \
649                                                                         \
650         vector_foreach_slot(src, _p, i) {                               \
651                 if (prio_name == NULL && _p->prio_name)         \
652                         prio_name = _p->prio_name;                      \
653                 if (prio_args == NULL && _p->prio_args)         \
654                         prio_args = _p->prio_args;                      \
655         }                                                               \
656         if (prio_name != NULL) {                                        \
657                 prio_get(dir, p, prio_name, prio_args);                 \
658                 origin = msg;                                           \
659                 goto out;                                               \
660         }                                                               \
661 } while (0)
662
663 int select_prio(struct config *conf, struct path *pp)
664 {
665         const char *origin;
666         struct mpentry * mpe;
667         struct prio * p = &pp->prio;
668         int log_prio = 3;
669
670         if (pp->detect_prio == DETECT_PRIO_ON) {
671                 detect_prio(conf, pp);
672                 if (prio_selected(p)) {
673                         origin = autodetect_origin;
674                         goto out;
675                 }
676         }
677         mpe = find_mpe(conf->mptable, pp->wwid);
678         set_prio(conf->multipath_dir, mpe, multipaths_origin);
679         set_prio(conf->multipath_dir, conf->overrides, overrides_origin);
680         set_prio_from_vec(struct hwentry, conf->multipath_dir,
681                           pp->hwe, hwe_origin, p);
682         set_prio(conf->multipath_dir, conf, conf_origin);
683         prio_get(conf->multipath_dir, p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
684         origin = default_origin;
685 out:
686         /*
687          * fetch tpgs mode for alua, if its not already obtained
688          */
689         if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
690                 int tpgs = path_get_tpgs(pp);
691
692                 if (tpgs == TPGS_NONE) {
693                         prio_get(conf->multipath_dir,
694                                  p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
695                         origin = "(setting: emergency fallback - alua failed)";
696                         log_prio = 1;
697                 }
698         }
699         condlog(log_prio, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
700         condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin);
701         return 0;
702 }
703
704 int select_no_path_retry(struct config *conf, struct multipath *mp)
705 {
706         const char *origin = NULL;
707         STRBUF_ON_STACK(buff);
708
709         if (mp->disable_queueing) {
710                 condlog(0, "%s: queueing disabled", mp->alias);
711                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
712                 return 0;
713         }
714         mp_set_mpe(no_path_retry);
715         mp_set_ovr(no_path_retry);
716         mp_set_hwe(no_path_retry);
717         mp_set_conf(no_path_retry);
718 out:
719         print_no_path_retry(&buff, mp->no_path_retry);
720         if (origin)
721                 condlog(3, "%s: no_path_retry = %s %s", mp->alias,
722                         get_strbuf_str(&buff), origin);
723         else
724                 condlog(3, "%s: no_path_retry = undef %s",
725                         mp->alias, default_origin);
726         return 0;
727 }
728
729 int
730 select_minio_rq (struct config *conf, struct multipath * mp)
731 {
732         const char *origin;
733
734         do_set(minio_rq, mp->mpe, mp->minio, multipaths_origin);
735         do_set(minio_rq, conf->overrides, mp->minio, overrides_origin);
736         do_set_from_hwe(minio_rq, mp, mp->minio, hwe_origin);
737         do_set(minio_rq, conf, mp->minio, conf_origin);
738         do_default(mp->minio, DEFAULT_MINIO_RQ);
739 out:
740         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
741         return 0;
742 }
743
744 int
745 select_minio_bio (struct config *conf, struct multipath * mp)
746 {
747         const char *origin;
748
749         mp_set_mpe(minio);
750         mp_set_ovr(minio);
751         mp_set_hwe(minio);
752         mp_set_conf(minio);
753         mp_set_default(minio, DEFAULT_MINIO);
754 out:
755         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
756         return 0;
757 }
758
759 int select_minio(struct config *conf, struct multipath *mp)
760 {
761         unsigned int minv_dmrq[3] = {1, 1, 0}, version[3];
762
763         if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version)
764             && VERSION_GE(version, minv_dmrq))
765                 return select_minio_rq(conf, mp);
766         else
767                 return select_minio_bio(conf, mp);
768 }
769
770 int select_fast_io_fail(struct config *conf, struct multipath *mp)
771 {
772         const char *origin;
773         STRBUF_ON_STACK(buff);
774
775         mp_set_ovr(fast_io_fail);
776         mp_set_hwe(fast_io_fail);
777         mp_set_conf(fast_io_fail);
778         mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL);
779 out:
780         print_undef_off_zero(&buff, mp->fast_io_fail);
781         condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias,
782                 get_strbuf_str(&buff), origin);
783         return 0;
784 }
785
786 int select_dev_loss(struct config *conf, struct multipath *mp)
787 {
788         const char *origin;
789         STRBUF_ON_STACK(buff);
790
791         mp_set_ovr(dev_loss);
792         mp_set_hwe(dev_loss);
793         mp_set_conf(dev_loss);
794         mp->dev_loss = DEV_LOSS_TMO_UNSET;
795         return 0;
796 out:
797         print_dev_loss(&buff, mp->dev_loss);
798         condlog(3, "%s: dev_loss_tmo = %s %s", mp->alias,
799                 get_strbuf_str(&buff), origin);
800         return 0;
801 }
802
803 int select_eh_deadline(struct config *conf, struct multipath *mp)
804 {
805         const char *origin;
806         STRBUF_ON_STACK(buff);
807
808         mp_set_ovr(eh_deadline);
809         mp_set_hwe(eh_deadline);
810         mp_set_conf(eh_deadline);
811         mp->eh_deadline = EH_DEADLINE_UNSET;
812         /* not changing sysfs in default cause, so don't print anything */
813         return 0;
814 out:
815         print_undef_off_zero(&buff, mp->eh_deadline);
816         condlog(3, "%s: eh_deadline = %s %s", mp->alias,
817                 get_strbuf_str(&buff), origin);
818         return 0;
819 }
820
821 int select_flush_on_last_del(struct config *conf, struct multipath *mp)
822 {
823         const char *origin;
824
825         mp_set_mpe(flush_on_last_del);
826         mp_set_ovr(flush_on_last_del);
827         mp_set_hwe(flush_on_last_del);
828         mp_set_conf(flush_on_last_del);
829         mp_set_default(flush_on_last_del, DEFAULT_FLUSH);
830 out:
831         condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
832                 (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
833         return 0;
834 }
835
836 int select_reservation_key(struct config *conf, struct multipath *mp)
837 {
838         const char *origin;
839         STRBUF_ON_STACK(buff);
840         char *from_file = "";
841         uint64_t prkey = 0;
842
843         do_prkey_set(mp->mpe, multipaths_origin);
844         do_prkey_set(conf, conf_origin);
845         put_be64(mp->reservation_key, 0);
846         mp->sa_flags = 0;
847         mp->prkey_source = PRKEY_SOURCE_NONE;
848         return 0;
849 out:
850         if (mp->prkey_source == PRKEY_SOURCE_FILE) {
851                 from_file = " (from prkeys file)";
852                 if (get_prkey(conf, mp, &prkey, &mp->sa_flags) != 0)
853                         put_be64(mp->reservation_key, 0);
854                 else
855                         put_be64(mp->reservation_key, prkey);
856         }
857         print_reservation_key(&buff, mp->reservation_key,
858                               mp->sa_flags, mp->prkey_source);
859         condlog(3, "%s: reservation_key = %s %s%s", mp->alias,
860                 get_strbuf_str(&buff), origin, from_file);
861         return 0;
862 }
863
864 int select_retain_hwhandler(struct config *conf, struct multipath *mp)
865 {
866         const char *origin;
867         unsigned int minv_dm_retain[3] = {1, 5, 0}, version[3];
868
869         if (!libmp_get_version(DM_MPATH_TARGET_VERSION, version) &&
870             !VERSION_GE(version, minv_dm_retain)) {
871                 mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
872                 origin = "(setting: WARNING, requires kernel dm-mpath version >= 1.5.0)";
873                 goto out;
874         }
875         if (get_linux_version_code() >= KERNEL_VERSION(4, 3, 0)) {
876                 mp->retain_hwhandler = RETAIN_HWHANDLER_ON;
877                 origin = "(setting: implied in kernel >= 4.3.0)";
878                 goto out;
879         }
880         mp_set_ovr(retain_hwhandler);
881         mp_set_hwe(retain_hwhandler);
882         mp_set_conf(retain_hwhandler);
883         mp_set_default(retain_hwhandler, DEFAULT_RETAIN_HWHANDLER);
884 out:
885         condlog(3, "%s: retain_attached_hw_handler = %s %s", mp->alias,
886                 (mp->retain_hwhandler == RETAIN_HWHANDLER_ON)? "yes" : "no",
887                 origin);
888         return 0;
889 }
890
891 int select_detect_prio(struct config *conf, struct path *pp)
892 {
893         const char *origin;
894
895         pp_set_ovr(detect_prio);
896         pp_set_hwe(detect_prio);
897         pp_set_conf(detect_prio);
898         pp_set_default(detect_prio, DEFAULT_DETECT_PRIO);
899 out:
900         condlog(3, "%s: detect_prio = %s %s", pp->dev,
901                 (pp->detect_prio == DETECT_PRIO_ON)? "yes" : "no", origin);
902         return 0;
903 }
904
905 int select_detect_checker(struct config *conf, struct path *pp)
906 {
907         const char *origin;
908
909         pp_set_ovr(detect_checker);
910         pp_set_hwe(detect_checker);
911         pp_set_conf(detect_checker);
912         pp_set_default(detect_checker, DEFAULT_DETECT_CHECKER);
913 out:
914         condlog(3, "%s: detect_checker = %s %s", pp->dev,
915                 (pp->detect_checker == DETECT_CHECKER_ON)? "yes" : "no",
916                 origin);
917         return 0;
918 }
919
920 int select_deferred_remove(struct config *conf, struct multipath *mp)
921 {
922         const char *origin;
923
924 #ifndef LIBDM_API_DEFERRED
925         mp->deferred_remove = DEFERRED_REMOVE_OFF;
926         origin = "(setting: WARNING, not compiled with support)";
927         goto out;
928 #endif
929         if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
930                 condlog(3, "%s: deferred remove in progress", mp->alias);
931                 return 0;
932         }
933         mp_set_mpe(deferred_remove);
934         mp_set_ovr(deferred_remove);
935         mp_set_hwe(deferred_remove);
936         mp_set_conf(deferred_remove);
937         mp_set_default(deferred_remove, DEFAULT_DEFERRED_REMOVE);
938 out:
939         condlog(3, "%s: deferred_remove = %s %s", mp->alias,
940                 (mp->deferred_remove == DEFERRED_REMOVE_ON)? "yes" : "no",
941                 origin);
942         return 0;
943 }
944
945 static inline int san_path_check_options_set(const struct multipath *mp)
946 {
947         return mp->san_path_err_threshold > 0 ||
948                mp->san_path_err_forget_rate > 0 ||
949                mp->san_path_err_recovery_time > 0;
950 }
951
952 static int
953 use_delay_watch_checks(struct config *conf, struct multipath *mp)
954 {
955         int value = NU_UNDEF;
956         const char *origin = default_origin;
957         STRBUF_ON_STACK(buff);
958
959         do_set(delay_watch_checks, mp->mpe, value, multipaths_origin);
960         do_set(delay_watch_checks, conf->overrides, value, overrides_origin);
961         do_set_from_hwe(delay_watch_checks, mp, value, hwe_origin);
962         do_set(delay_watch_checks, conf, value, conf_origin);
963 out:
964         if (print_off_int_undef(&buff, value) > 0)
965                 condlog(3, "%s: delay_watch_checks = %s %s", mp->alias,
966                         get_strbuf_str(&buff), origin);
967         return value;
968 }
969
970 static int
971 use_delay_wait_checks(struct config *conf, struct multipath *mp)
972 {
973         int value = NU_UNDEF;
974         const char *origin = default_origin;
975         STRBUF_ON_STACK(buff);
976
977         do_set(delay_wait_checks, mp->mpe, value, multipaths_origin);
978         do_set(delay_wait_checks, conf->overrides, value, overrides_origin);
979         do_set_from_hwe(delay_wait_checks, mp, value, hwe_origin);
980         do_set(delay_wait_checks, conf, value, conf_origin);
981 out:
982         if (print_off_int_undef(&buff, value) > 0)
983                 condlog(3, "%s: delay_wait_checks = %s %s", mp->alias,
984                         get_strbuf_str(&buff), origin);
985         return value;
986 }
987
988 int select_delay_checks(struct config *conf, struct multipath *mp)
989 {
990         int watch_checks, wait_checks;
991         STRBUF_ON_STACK(buff);
992
993         watch_checks = use_delay_watch_checks(conf, mp);
994         wait_checks = use_delay_wait_checks(conf, mp);
995         if (watch_checks <= 0 && wait_checks <= 0)
996                 return 0;
997         if (san_path_check_options_set(mp)) {
998                 condlog(3, "%s: both marginal_path and delay_checks error detection options selected", mp->alias);
999                 condlog(3, "%s: ignoring delay_checks options", mp->alias);
1000                 return 0;
1001         }
1002         mp->san_path_err_threshold = 1;
1003         condlog(3, "%s: san_path_err_threshold = 1 %s", mp->alias,
1004                 (watch_checks > 0)? delay_watch_origin : delay_wait_origin);
1005         if (watch_checks > 0) {
1006                 mp->san_path_err_forget_rate = watch_checks;
1007                 print_off_int_undef(&buff, mp->san_path_err_forget_rate);
1008                 condlog(3, "%s: san_path_err_forget_rate = %s %s", mp->alias,
1009                         get_strbuf_str(&buff), delay_watch_origin);
1010                 reset_strbuf(&buff);
1011         }
1012         if (wait_checks > 0) {
1013                 mp->san_path_err_recovery_time = wait_checks *
1014                                                  conf->max_checkint;
1015                 print_off_int_undef(&buff, mp->san_path_err_recovery_time);
1016                 condlog(3, "%s: san_path_err_recovery_time = %s %s", mp->alias,
1017                         get_strbuf_str(&buff), delay_wait_origin);
1018         }
1019         return 0;
1020 }
1021
1022 static int san_path_deprecated_warned;
1023 #define warn_san_path_deprecated(v, x)                                  \
1024         do {                                                            \
1025                 if (v->x > 0 && !san_path_deprecated_warned) {          \
1026                 san_path_deprecated_warned = 1;                         \
1027                 condlog(1, "WARNING: option %s is deprecated, "         \
1028                         "please use marginal_path options instead",     \
1029                         #x);                                            \
1030                 }                                                       \
1031         } while(0)
1032
1033 int select_san_path_err_threshold(struct config *conf, struct multipath *mp)
1034 {
1035         const char *origin;
1036         STRBUF_ON_STACK(buff);
1037
1038         if (marginal_path_check_enabled(mp)) {
1039                 mp->san_path_err_threshold = NU_NO;
1040                 origin = marginal_path_origin;
1041                 goto out;
1042         }
1043         mp_set_mpe(san_path_err_threshold);
1044         mp_set_ovr(san_path_err_threshold);
1045         mp_set_hwe(san_path_err_threshold);
1046         mp_set_conf(san_path_err_threshold);
1047         mp_set_default(san_path_err_threshold, DEFAULT_ERR_CHECKS);
1048 out:
1049         if (print_off_int_undef(&buff, mp->san_path_err_threshold) > 0)
1050                 condlog(3, "%s: san_path_err_threshold = %s %s",
1051                         mp->alias, get_strbuf_str(&buff), origin);
1052         warn_san_path_deprecated(mp, san_path_err_threshold);
1053         return 0;
1054 }
1055
1056 int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp)
1057 {
1058         const char *origin;
1059         STRBUF_ON_STACK(buff);
1060
1061         if (marginal_path_check_enabled(mp)) {
1062                 mp->san_path_err_forget_rate = NU_NO;
1063                 origin = marginal_path_origin;
1064                 goto out;
1065         }
1066         mp_set_mpe(san_path_err_forget_rate);
1067         mp_set_ovr(san_path_err_forget_rate);
1068         mp_set_hwe(san_path_err_forget_rate);
1069         mp_set_conf(san_path_err_forget_rate);
1070         mp_set_default(san_path_err_forget_rate, DEFAULT_ERR_CHECKS);
1071 out:
1072         if (print_off_int_undef(&buff, mp->san_path_err_forget_rate) > 0)
1073                 condlog(3, "%s: san_path_err_forget_rate = %s %s",
1074                         mp->alias, get_strbuf_str(&buff), origin);
1075         warn_san_path_deprecated(mp, san_path_err_forget_rate);
1076         return 0;
1077
1078 }
1079
1080 int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp)
1081 {
1082         const char *origin;
1083         STRBUF_ON_STACK(buff);
1084
1085         if (marginal_path_check_enabled(mp)) {
1086                 mp->san_path_err_recovery_time = NU_NO;
1087                 origin = marginal_path_origin;
1088                 goto out;
1089         }
1090         mp_set_mpe(san_path_err_recovery_time);
1091         mp_set_ovr(san_path_err_recovery_time);
1092         mp_set_hwe(san_path_err_recovery_time);
1093         mp_set_conf(san_path_err_recovery_time);
1094         mp_set_default(san_path_err_recovery_time, DEFAULT_ERR_CHECKS);
1095 out:
1096         if (print_off_int_undef(&buff, mp->san_path_err_recovery_time) != 0)
1097                 condlog(3, "%s: san_path_err_recovery_time = %s %s", mp->alias,
1098                         get_strbuf_str(&buff), origin);
1099         warn_san_path_deprecated(mp, san_path_err_recovery_time);
1100         return 0;
1101
1102 }
1103
1104 int select_marginal_path_err_sample_time(struct config *conf, struct multipath *mp)
1105 {
1106         const char *origin;
1107         STRBUF_ON_STACK(buff);
1108
1109         mp_set_mpe(marginal_path_err_sample_time);
1110         mp_set_ovr(marginal_path_err_sample_time);
1111         mp_set_hwe(marginal_path_err_sample_time);
1112         mp_set_conf(marginal_path_err_sample_time);
1113         mp_set_default(marginal_path_err_sample_time, DEFAULT_ERR_CHECKS);
1114 out:
1115         if (mp->marginal_path_err_sample_time > 0 &&
1116             mp->marginal_path_err_sample_time < 2 * IOTIMEOUT_SEC) {
1117                 condlog(2, "%s: configuration error: marginal_path_err_sample_time must be >= %d",
1118                         mp->alias, 2 * IOTIMEOUT_SEC);
1119                         mp->marginal_path_err_sample_time = 2 * IOTIMEOUT_SEC;
1120         }
1121         if (print_off_int_undef(&buff, mp->marginal_path_err_sample_time) > 0)
1122                 condlog(3, "%s: marginal_path_err_sample_time = %s %s",
1123                         mp->alias, get_strbuf_str(&buff), origin);
1124         return 0;
1125 }
1126
1127 int select_marginal_path_err_rate_threshold(struct config *conf, struct multipath *mp)
1128 {
1129         const char *origin;
1130         STRBUF_ON_STACK(buff);
1131
1132         mp_set_mpe(marginal_path_err_rate_threshold);
1133         mp_set_ovr(marginal_path_err_rate_threshold);
1134         mp_set_hwe(marginal_path_err_rate_threshold);
1135         mp_set_conf(marginal_path_err_rate_threshold);
1136         mp_set_default(marginal_path_err_rate_threshold, DEFAULT_ERR_CHECKS);
1137 out:
1138         if (print_off_int_undef(&buff, mp->marginal_path_err_rate_threshold) > 0)
1139                 condlog(3, "%s: marginal_path_err_rate_threshold = %s %s",
1140                         mp->alias, get_strbuf_str(&buff), origin);
1141         return 0;
1142 }
1143
1144 int select_marginal_path_err_recheck_gap_time(struct config *conf, struct multipath *mp)
1145 {
1146         const char *origin;
1147         STRBUF_ON_STACK(buff);
1148
1149         mp_set_mpe(marginal_path_err_recheck_gap_time);
1150         mp_set_ovr(marginal_path_err_recheck_gap_time);
1151         mp_set_hwe(marginal_path_err_recheck_gap_time);
1152         mp_set_conf(marginal_path_err_recheck_gap_time);
1153         mp_set_default(marginal_path_err_recheck_gap_time, DEFAULT_ERR_CHECKS);
1154 out:
1155         if (print_off_int_undef(&buff,
1156                                 mp->marginal_path_err_recheck_gap_time) > 0)
1157                 condlog(3, "%s: marginal_path_err_recheck_gap_time = %s %s",
1158                         mp->alias, get_strbuf_str(&buff), origin);
1159         return 0;
1160 }
1161
1162 int select_marginal_path_double_failed_time(struct config *conf, struct multipath *mp)
1163 {
1164         const char *origin;
1165         STRBUF_ON_STACK(buff);
1166
1167         mp_set_mpe(marginal_path_double_failed_time);
1168         mp_set_ovr(marginal_path_double_failed_time);
1169         mp_set_hwe(marginal_path_double_failed_time);
1170         mp_set_conf(marginal_path_double_failed_time);
1171         mp_set_default(marginal_path_double_failed_time, DEFAULT_ERR_CHECKS);
1172 out:
1173         if (print_off_int_undef(&buff, mp->marginal_path_double_failed_time) > 0)
1174                 condlog(3, "%s: marginal_path_double_failed_time = %s %s",
1175                         mp->alias, get_strbuf_str(&buff), origin);
1176         return 0;
1177 }
1178
1179 int select_skip_kpartx (struct config *conf, struct multipath * mp)
1180 {
1181         const char *origin;
1182
1183         mp_set_mpe(skip_kpartx);
1184         mp_set_ovr(skip_kpartx);
1185         mp_set_hwe(skip_kpartx);
1186         mp_set_conf(skip_kpartx);
1187         mp_set_default(skip_kpartx, DEFAULT_SKIP_KPARTX);
1188 out:
1189         condlog(3, "%s: skip_kpartx = %s %s", mp->alias,
1190                 (mp->skip_kpartx == SKIP_KPARTX_ON)? "yes" : "no",
1191                 origin);
1192         return 0;
1193 }
1194
1195 int select_max_sectors_kb(struct config *conf, struct multipath * mp)
1196 {
1197         const char *origin;
1198
1199         mp_set_mpe(max_sectors_kb);
1200         mp_set_ovr(max_sectors_kb);
1201         mp_set_hwe(max_sectors_kb);
1202         mp_set_conf(max_sectors_kb);
1203         mp_set_default(max_sectors_kb, DEFAULT_MAX_SECTORS_KB);
1204         /*
1205          * In the default case, we will not modify max_sectors_kb in sysfs
1206          * (see sysfs_set_max_sectors_kb()).
1207          * Don't print a log message here to avoid user confusion.
1208          */
1209         return 0;
1210 out:
1211         condlog(3, "%s: max_sectors_kb = %i %s", mp->alias, mp->max_sectors_kb,
1212                 origin);
1213         return 0;
1214 }
1215
1216 int select_ghost_delay (struct config *conf, struct multipath * mp)
1217 {
1218         const char *origin;
1219         STRBUF_ON_STACK(buff);
1220
1221         mp_set_mpe(ghost_delay);
1222         mp_set_ovr(ghost_delay);
1223         mp_set_hwe(ghost_delay);
1224         mp_set_conf(ghost_delay);
1225         mp_set_default(ghost_delay, DEFAULT_GHOST_DELAY);
1226 out:
1227         if (print_off_int_undef(&buff, mp->ghost_delay) != 0)
1228                 condlog(3, "%s: ghost_delay = %s %s", mp->alias,
1229                         get_strbuf_str(&buff), origin);
1230         return 0;
1231 }
1232
1233 int select_find_multipaths_timeout(struct config *conf, struct path *pp)
1234 {
1235         const char *origin;
1236
1237         pp_set_conf(find_multipaths_timeout);
1238         pp_set_default(find_multipaths_timeout,
1239                        DEFAULT_FIND_MULTIPATHS_TIMEOUT);
1240 out:
1241         /*
1242          * If configured value is negative, and this "unknown" hardware
1243          * (no hwentry), use very small timeout to avoid delays.
1244          */
1245         if (pp->find_multipaths_timeout < 0) {
1246                 pp->find_multipaths_timeout = -pp->find_multipaths_timeout;
1247                 if (!pp->hwe) {
1248                         pp->find_multipaths_timeout =
1249                                 DEFAULT_UNKNOWN_FIND_MULTIPATHS_TIMEOUT;
1250                         origin = "(default for unknown hardware)";
1251                 }
1252         }
1253         condlog(3, "%s: timeout for find_multipaths \"smart\" = %ds %s",
1254                 pp->dev, pp->find_multipaths_timeout, origin);
1255         return 0;
1256 }
1257
1258 int select_all_tg_pt (struct config *conf, struct multipath * mp)
1259 {
1260         const char *origin;
1261
1262         mp_set_ovr(all_tg_pt);
1263         mp_set_hwe(all_tg_pt);
1264         mp_set_conf(all_tg_pt);
1265         mp_set_default(all_tg_pt, DEFAULT_ALL_TG_PT);
1266 out:
1267         condlog(3, "%s: all_tg_pt = %s %s", mp->alias,
1268                 (mp->all_tg_pt == ALL_TG_PT_ON)? "yes" : "no",
1269                 origin);
1270         return 0;
1271 }
1272
1273 int select_vpd_vendor_id (struct path *pp)
1274 {
1275         const char *origin;
1276
1277         pp_set_hwe(vpd_vendor_id);
1278         pp_set_default(vpd_vendor_id, 0);
1279 out:
1280         if (pp->vpd_vendor_id < 0 || pp->vpd_vendor_id >= VPD_VP_ARRAY_SIZE) {
1281                 condlog(3, "%s: vpd_vendor_id = %d (invalid, setting to 0)",
1282                         pp->dev, pp->vpd_vendor_id);
1283                 pp->vpd_vendor_id = 0;
1284         }
1285         condlog(3, "%s: vpd_vendor_id = %d \"%s\" %s", pp->dev,
1286                 pp->vpd_vendor_id, vpd_vendor_pages[pp->vpd_vendor_id].name,
1287                 origin);
1288         return 0;
1289 }