e4afef737207151d34d17d93f475366b7fcd5d83
[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 "prioritizers/alua_rtpg.h"
22 #include <inttypes.h>
23
24 pgpolicyfn *pgpolicies[] = {
25         NULL,
26         one_path_per_group,
27         one_group,
28         group_by_serial,
29         group_by_prio,
30         group_by_node_name
31 };
32
33 #define do_set(var, src, dest, msg)                                     \
34 do {                                                                    \
35         if (src && src->var) {                                          \
36                 dest = src->var;                                        \
37                 origin = msg;                                           \
38                 goto out;                                               \
39         }                                                               \
40 } while(0)
41 #define do_default(dest, value)                                         \
42 do {                                                                    \
43         dest = value;                                                   \
44         origin = "(setting: multipath internal)";                       \
45 } while(0)
46
47 #define mp_set_mpe(var)                                                 \
48 do_set(var, mp->mpe, mp->var, "(setting: multipath.conf multipaths section)")
49 #define mp_set_hwe(var)                                                 \
50 do_set(var, mp->hwe, mp->var, "(setting: array configuration)")
51 #define mp_set_ovr(var)                                                 \
52 do_set(var, conf->overrides, mp->var, "(setting: multipath.conf overrides section)")
53 #define mp_set_conf(var)                                                \
54 do_set(var, conf, mp->var, "(setting: multipath.conf defaults/devices section)")
55 #define mp_set_default(var, value)                                      \
56 do_default(mp->var, value)
57
58 #define pp_set_mpe(var)                                                 \
59 do_set(var, mpe, pp->var, "(setting: multipath.conf multipaths section)")
60 #define pp_set_hwe(var)                                                 \
61 do_set(var, pp->hwe, pp->var, "(setting: array configuration)")
62 #define pp_set_conf(var)                                                \
63 do_set(var, conf, pp->var, "(setting: multipath.conf defaults/devices section)")
64 #define pp_set_ovr(var)                                                 \
65 do_set(var, conf->overrides, pp->var, "(setting: multipath.conf overrides section)")
66 #define pp_set_default(var, value)                                      \
67 do_default(pp->var, value)
68
69 #define do_attr_set(var, src, shift, msg)                               \
70 do {                                                                    \
71         if (src && (src->attribute_flags & (1 << shift))) {             \
72                 mp->attribute_flags |= (1 << shift);                    \
73                 mp->var = src->var;                                     \
74                 origin = msg;                                           \
75                 goto out;                                               \
76         }                                                               \
77 } while(0)
78
79 #define set_attr_mpe(var, shift)                                        \
80 do_attr_set(var, mp->mpe, shift, "(setting: multipath.conf multipaths section)")
81 #define set_attr_conf(var, shift)                                       \
82 do_attr_set(var, conf, shift, "(setting: multipath.conf defaults/devices section)")
83
84 int select_mode(struct config *conf, struct multipath *mp)
85 {
86         char *origin;
87
88         set_attr_mpe(mode, ATTR_MODE);
89         set_attr_conf(mode, ATTR_MODE);
90         mp->attribute_flags &= ~(1 << ATTR_MODE);
91         return 0;
92 out:
93         condlog(3, "%s: mode = 0%o %s", mp->alias, mp->mode, origin);
94         return 0;
95 }
96
97 int select_uid(struct config *conf, struct multipath *mp)
98 {
99         char *origin;
100
101         set_attr_mpe(uid, ATTR_UID);
102         set_attr_conf(uid, ATTR_UID);
103         mp->attribute_flags &= ~(1 << ATTR_UID);
104         return 0;
105 out:
106         condlog(3, "%s: uid = 0%o %s", mp->alias, mp->uid, origin);
107         return 0;
108 }
109
110 int select_gid(struct config *conf, struct multipath *mp)
111 {
112         char *origin;
113
114         set_attr_mpe(gid, ATTR_GID);
115         set_attr_conf(gid, ATTR_GID);
116         mp->attribute_flags &= ~(1 << ATTR_GID);
117         return 0;
118 out:
119         condlog(3, "%s: gid = 0%o %s", mp->alias, mp->gid, origin);
120         return 0;
121 }
122
123 /*
124  * selectors :
125  * traverse the configuration layers from most specific to most generic
126  * stop at first explicit setting found
127  */
128 int select_rr_weight(struct config *conf, struct multipath * mp)
129 {
130         char *origin, buff[13];
131
132         mp_set_mpe(rr_weight);
133         mp_set_ovr(rr_weight);
134         mp_set_hwe(rr_weight);
135         mp_set_conf(rr_weight);
136         mp_set_default(rr_weight, DEFAULT_RR_WEIGHT);
137 out:
138         print_rr_weight(buff, 13, &mp->rr_weight);
139         condlog(3, "%s: rr_weight = %s %s", mp->alias, buff, origin);
140         return 0;
141 }
142
143 int select_pgfailback(struct config *conf, struct multipath * mp)
144 {
145         char *origin, buff[13];
146
147         mp_set_mpe(pgfailback);
148         mp_set_ovr(pgfailback);
149         mp_set_hwe(pgfailback);
150         mp_set_conf(pgfailback);
151         mp_set_default(pgfailback, DEFAULT_FAILBACK);
152 out:
153         print_pgfailback(buff, 13, &mp->pgfailback);
154         condlog(3, "%s: failback = %s %s", mp->alias, buff, origin);
155         return 0;
156 }
157
158 int select_pgpolicy(struct config *conf, struct multipath * mp)
159 {
160         char *origin, buff[POLICY_NAME_SIZE];
161
162         if (conf->pgpolicy_flag > 0) {
163                 mp->pgpolicy = conf->pgpolicy_flag;
164                 origin = "(cmd line flag)";
165                 goto out;
166         }
167         mp_set_mpe(pgpolicy);
168         mp_set_ovr(pgpolicy);
169         mp_set_hwe(pgpolicy);
170         mp_set_conf(pgpolicy);
171         mp_set_default(pgpolicy, DEFAULT_PGPOLICY);
172 out:
173         mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
174         get_pgpolicy_name(buff, POLICY_NAME_SIZE, mp->pgpolicy);
175         condlog(3, "%s: path_grouping_policy = %s %s", mp->alias, buff, origin);
176         return 0;
177 }
178
179 int select_selector(struct config *conf, struct multipath * mp)
180 {
181         char *origin;
182
183         mp_set_mpe(selector);
184         mp_set_ovr(selector);
185         mp_set_hwe(selector);
186         mp_set_conf(selector);
187         mp_set_default(selector, DEFAULT_SELECTOR);
188 out:
189         mp->selector = STRDUP(mp->selector);
190         condlog(3, "%s: path_selector = \"%s\" %s", mp->alias, mp->selector,
191                 origin);
192         return 0;
193 }
194
195 static void
196 select_alias_prefix (struct config *conf, struct multipath * mp)
197 {
198         char *origin;
199
200         mp_set_ovr(alias_prefix);
201         mp_set_hwe(alias_prefix);
202         mp_set_conf(alias_prefix);
203         mp_set_default(alias_prefix, DEFAULT_ALIAS_PREFIX);
204 out:
205         condlog(3, "%s: alias_prefix = %s %s", mp->wwid, mp->alias_prefix,
206                 origin);
207 }
208
209 static int
210 want_user_friendly_names(struct config *conf, struct multipath * mp)
211 {
212
213         char *origin;
214         int user_friendly_names;
215
216         do_set(user_friendly_names, mp->mpe, user_friendly_names,
217                "(setting: multipath.conf multipaths section)");
218         do_set(user_friendly_names, conf->overrides, user_friendly_names,
219                "(setting: multipath.conf overrides section)");
220         do_set(user_friendly_names, mp->hwe, user_friendly_names,
221                "(setting: array configuration)");
222         do_set(user_friendly_names, conf, user_friendly_names,
223                "(setting: multipath.conf defaults/devices section)");
224         do_default(user_friendly_names, DEFAULT_USER_FRIENDLY_NAMES);
225 out:
226         condlog(3, "%s: user_friendly_names = %s %s", mp->wwid,
227                 (user_friendly_names == USER_FRIENDLY_NAMES_ON)? "yes" : "no",
228                 origin);
229         return (user_friendly_names == USER_FRIENDLY_NAMES_ON);
230 }
231
232 int select_alias(struct config *conf, struct multipath * mp)
233 {
234         char *origin = NULL;
235
236         if (mp->mpe && mp->mpe->alias) {
237                 mp->alias = STRDUP(mp->mpe->alias);
238                 origin = "(setting: multipath.conf multipaths section)";
239                 goto out;
240         }
241
242         mp->alias = NULL;
243         if (!want_user_friendly_names(conf, mp))
244                 goto out;
245
246         select_alias_prefix(conf, mp);
247
248         if (strlen(mp->alias_old) > 0) {
249                 mp->alias = use_existing_alias(mp->wwid, conf->bindings_file,
250                                 mp->alias_old, mp->alias_prefix,
251                                 conf->bindings_read_only);
252                 memset (mp->alias_old, 0, WWID_SIZE);
253                 origin = "(using existing alias)";
254         }
255
256         if (mp->alias == NULL) {
257                 mp->alias = get_user_friendly_alias(mp->wwid,
258                                 conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
259                 origin = "(user_friendly_name)";
260         }
261 out:
262         if (mp->alias == NULL) {
263                 mp->alias = STRDUP(mp->wwid);
264                 origin = "(default to wwid)";
265         }
266         if (mp->alias)
267                 condlog(3, "%s: alias = %s %s", mp->wwid, mp->alias, origin);
268         return mp->alias ? 0 : 1;
269 }
270
271 int select_features(struct config *conf, struct multipath *mp)
272 {
273         char *origin;
274
275         mp_set_mpe(features);
276         mp_set_ovr(features);
277         mp_set_hwe(features);
278         mp_set_conf(features);
279         mp_set_default(features, DEFAULT_FEATURES);
280 out:
281         mp->features = STRDUP(mp->features);
282         condlog(3, "%s: features = \"%s\" %s", mp->alias, mp->features, origin);
283
284         if (strstr(mp->features, "queue_if_no_path")) {
285                 if (mp->no_path_retry == NO_PATH_RETRY_UNDEF)
286                         mp->no_path_retry = NO_PATH_RETRY_QUEUE;
287                 else if (mp->no_path_retry == NO_PATH_RETRY_FAIL) {
288                         condlog(1, "%s: config error, overriding 'no_path_retry' value",
289                                 mp->alias);
290                         mp->no_path_retry = NO_PATH_RETRY_QUEUE;
291                 }
292         }
293         return 0;
294 }
295
296 int select_hwhandler(struct config *conf, struct multipath *mp)
297 {
298         char *origin;
299
300         mp_set_hwe(hwhandler);
301         mp_set_conf(hwhandler);
302         mp_set_default(hwhandler, DEFAULT_HWHANDLER);
303 out:
304         mp->hwhandler = STRDUP(mp->hwhandler);
305         condlog(3, "%s: hardware_handler = \"%s\" %s", mp->alias, mp->hwhandler,
306                 origin);
307         return 0;
308 }
309
310 int select_checker(struct config *conf, struct path *pp)
311 {
312         char *origin, *checker_name;
313         struct checker * c = &pp->checker;
314
315         do_set(checker_name, conf->overrides, checker_name, "(setting: multipath.conf overrides section)");
316         do_set(checker_name, pp->hwe, checker_name, "(setting: array configuration)");
317         do_set(checker_name, conf, checker_name, "(setting: multipath.conf defaults/devices section)");
318         do_default(checker_name, DEFAULT_CHECKER);
319 out:
320         checker_get(conf->multipath_dir, c, checker_name);
321         condlog(3, "%s: path_checker = %s %s", pp->dev, c->name, origin);
322         if (conf->checker_timeout) {
323                 c->timeout = conf->checker_timeout;
324                 condlog(3, "%s: checker timeout = %u s (setting: multipath.conf defaults/devices section)",
325                                 pp->dev, c->timeout);
326         }
327         else if (sysfs_get_timeout(pp, &c->timeout) > 0)
328                 condlog(3, "%s: checker timeout = %u ms (setting: kernel sysfs)",
329                                 pp->dev, c->timeout);
330         else {
331                 c->timeout = DEF_TIMEOUT;
332                 condlog(3, "%s: checker timeout = %u ms (setting: multipath internal)",
333                                 pp->dev, c->timeout);
334         }
335         return 0;
336 }
337
338 int select_getuid(struct config *conf, struct path *pp)
339 {
340         char *origin;
341
342         pp_set_ovr(getuid);
343         pp_set_ovr(uid_attribute);
344         pp_set_hwe(getuid);
345         pp_set_hwe(uid_attribute);
346         pp_set_conf(getuid);
347         pp_set_conf(uid_attribute);
348         pp_set_default(uid_attribute, DEFAULT_UID_ATTRIBUTE);
349 out:
350         if (pp->uid_attribute)
351                 condlog(3, "%s: uid_attribute = %s %s", pp->dev,
352                         pp->uid_attribute, origin);
353         else if (pp->getuid)
354                 condlog(3, "%s: getuid = \"%s\" %s", pp->dev, pp->getuid,
355                         origin);
356         return 0;
357 }
358
359 void
360 detect_prio(struct config *conf, struct path * pp)
361 {
362         int ret;
363         struct prio *p = &pp->prio;
364         int tpgs = 0;
365         unsigned int timeout = conf->checker_timeout;
366         char buff[512];
367         char *default_prio = PRIO_ALUA;
368
369         if ((tpgs = get_target_port_group_support(pp->fd, timeout)) <= 0)
370                 return;
371         pp->tpgs = tpgs;
372         ret = get_target_port_group(pp, timeout);
373         if (ret < 0)
374                 return;
375         if (get_asymmetric_access_state(pp->fd, ret, timeout) < 0)
376                 return;
377         if (sysfs_get_asymmetric_access_state(pp, buff, 512) >= 0)
378                 default_prio = PRIO_SYSFS;
379         prio_get(conf->multipath_dir, p, default_prio, DEFAULT_PRIO_ARGS);
380 }
381
382 #define set_prio(dir, src, msg)                                 \
383 do {                                                                    \
384         if (src && src->prio_name) {                                    \
385                 prio_get(dir, p, src->prio_name, src->prio_args);       \
386                 origin = msg;                                           \
387                 goto out;                                               \
388         }                                                               \
389 } while(0)
390
391 int select_prio(struct config *conf, struct path *pp)
392 {
393         char *origin;
394         struct mpentry * mpe;
395         struct prio * p = &pp->prio;
396
397         if (pp->detect_prio == DETECT_PRIO_ON) {
398                 detect_prio(conf, pp);
399                 if (prio_selected(p)) {
400                         origin = "(setting: array autodetected)";
401                         goto out;
402                 }
403         }
404         mpe = find_mpe(conf->mptable, pp->wwid);
405         set_prio(conf->multipath_dir, mpe, "(setting: multipath.conf multipaths section)");
406         set_prio(conf->multipath_dir, conf->overrides, "(setting: multipath.conf overrides section)");
407         set_prio(conf->multipath_dir, pp->hwe, "(setting: array configuration)");
408         set_prio(conf->multipath_dir, conf, "(setting: multipath.conf defaults/devices section)");
409         prio_get(conf->multipath_dir, p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
410         origin = "(setting: multipath internal)";
411 out:
412         /*
413          * fetch tpgs mode for alua, if its not already obtained
414          */
415         if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
416                 int tpgs = 0;
417                 unsigned int timeout = conf->checker_timeout;
418
419                 if(!pp->tpgs &&
420                    (tpgs = get_target_port_group_support(pp->fd, timeout)) >= 0)
421                         pp->tpgs = tpgs;
422         }
423         condlog(3, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
424         condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin);
425         return 0;
426 }
427
428 int select_no_path_retry(struct config *conf, struct multipath *mp)
429 {
430         char *origin = NULL;
431         char buff[12];
432
433         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) {
434                 condlog(0, "flush_on_last_del in progress");
435                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
436                 return 0;
437         }
438         mp_set_mpe(no_path_retry);
439         mp_set_ovr(no_path_retry);
440         mp_set_hwe(no_path_retry);
441         mp_set_conf(no_path_retry);
442 out:
443         print_no_path_retry(buff, 12, &mp->no_path_retry);
444         if (origin)
445                 condlog(3, "%s: no_path_retry = %s %s", mp->alias, buff,
446                         origin);
447         else if (mp->no_path_retry != NO_PATH_RETRY_UNDEF)
448                 condlog(3, "%s: no_path_retry = %s (inherited setting)",
449                         mp->alias, buff);
450         else
451                 condlog(3, "%s: no_path_retry = undef (setting: multipath internal)",
452                         mp->alias);
453         return 0;
454 }
455
456 int
457 select_minio_rq (struct config *conf, struct multipath * mp)
458 {
459         char *origin;
460
461         do_set(minio_rq, mp->mpe, mp->minio, "(setting: multipath.conf multipaths section)");
462         do_set(minio_rq, conf->overrides, mp->minio, "(setting: multipath.conf overrides section)");
463         do_set(minio_rq, mp->hwe, mp->minio, "(setting: array configuration)");
464         do_set(minio_rq, conf, mp->minio, "(setting: multipath.conf defaults/devices section)");
465         do_default(mp->minio, DEFAULT_MINIO_RQ);
466 out:
467         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
468         return 0;
469 }
470
471 int
472 select_minio_bio (struct config *conf, struct multipath * mp)
473 {
474         char *origin;
475
476         mp_set_mpe(minio);
477         mp_set_ovr(minio);
478         mp_set_hwe(minio);
479         mp_set_conf(minio);
480         mp_set_default(minio, DEFAULT_MINIO);
481 out:
482         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
483         return 0;
484 }
485
486 int select_minio(struct config *conf, struct multipath *mp)
487 {
488         unsigned int minv_dmrq[3] = {1, 1, 0};
489
490         if (VERSION_GE(conf->version, minv_dmrq))
491                 return select_minio_rq(conf, mp);
492         else
493                 return select_minio_bio(conf, mp);
494 }
495
496 int select_fast_io_fail(struct config *conf, struct multipath *mp)
497 {
498         char *origin, buff[12];
499
500         mp_set_ovr(fast_io_fail);
501         mp_set_hwe(fast_io_fail);
502         mp_set_conf(fast_io_fail);
503         mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL);
504 out:
505         print_fast_io_fail(buff, 12, &mp->fast_io_fail);
506         condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin);
507         return 0;
508 }
509
510 int select_dev_loss(struct config *conf, struct multipath *mp)
511 {
512         char *origin, buff[12];
513
514         mp_set_ovr(dev_loss);
515         mp_set_hwe(dev_loss);
516         mp_set_conf(dev_loss);
517         mp->dev_loss = 0;
518         return 0;
519 out:
520         print_dev_loss(buff, 12, &mp->dev_loss);
521         condlog(3, "%s: dev_loss_tmo = %s %s", mp->alias, buff, origin);
522         return 0;
523 }
524
525 int select_flush_on_last_del(struct config *conf, struct multipath *mp)
526 {
527         char *origin;
528
529         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
530                 return 0;
531         mp_set_mpe(flush_on_last_del);
532         mp_set_ovr(flush_on_last_del);
533         mp_set_hwe(flush_on_last_del);
534         mp_set_conf(flush_on_last_del);
535         mp_set_default(flush_on_last_del, DEFAULT_FLUSH);
536 out:
537         condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
538                 (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
539         return 0;
540 }
541
542 int select_reservation_key(struct config *conf, struct multipath *mp)
543 {
544         char *origin, buff[12];
545
546         mp_set_mpe(reservation_key);
547         mp_set_conf(reservation_key);
548         mp->reservation_key = NULL;
549         return 0;
550 out:
551         print_reservation_key(buff, 12, &mp->reservation_key);
552         condlog(3, "%s: reservation_key = %s %s", mp->alias, buff, origin);
553         return 0;
554 }
555
556 int select_retain_hwhandler(struct config *conf, struct multipath *mp)
557 {
558         char *origin;
559         unsigned int minv_dm_retain[3] = {1, 5, 0};
560
561         if (!VERSION_GE(conf->version, minv_dm_retain)) {
562                 mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
563                 origin = "(requires kernel version >= 1.5.0)";
564                 goto out;
565         }
566         mp_set_ovr(retain_hwhandler);
567         mp_set_hwe(retain_hwhandler);
568         mp_set_conf(retain_hwhandler);
569         mp_set_default(retain_hwhandler, DEFAULT_RETAIN_HWHANDLER);
570 out:
571         condlog(3, "%s: retain_attached_hw_handler = %s %s", mp->alias,
572                 (mp->retain_hwhandler == RETAIN_HWHANDLER_ON)? "yes" : "no",
573                 origin);
574         return 0;
575 }
576
577 int select_detect_prio(struct config *conf, struct path *pp)
578 {
579         char *origin;
580
581         pp_set_ovr(detect_prio);
582         pp_set_hwe(detect_prio);
583         pp_set_conf(detect_prio);
584         pp_set_default(detect_prio, DEFAULT_DETECT_PRIO);
585 out:
586         condlog(3, "%s: detect_prio = %s %s", pp->dev,
587                 (pp->detect_prio == DETECT_PRIO_ON)? "yes" : "no", origin);
588         return 0;
589 }
590
591 int select_deferred_remove(struct config *conf, struct multipath *mp)
592 {
593         char *origin;
594
595 #ifndef LIBDM_API_DEFERRED
596         mp->deferred_remove = DEFERRED_REMOVE_OFF;
597         origin = "(not compiled with support)";
598         goto out;
599 #endif
600         if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
601                 condlog(3, "%s: deferred remove in progress", mp->alias);
602                 return 0;
603         }
604         mp_set_mpe(deferred_remove);
605         mp_set_ovr(deferred_remove);
606         mp_set_hwe(deferred_remove);
607         mp_set_conf(deferred_remove);
608         mp_set_default(deferred_remove, DEFAULT_DEFERRED_REMOVE);
609 out:
610         condlog(3, "%s: deferred_remove = %s %s", mp->alias,
611                 (mp->deferred_remove == DEFERRED_REMOVE_ON)? "yes" : "no",
612                 origin);
613         return 0;
614 }
615
616 int select_delay_watch_checks(struct config *conf, struct multipath *mp)
617 {
618         char *origin, buff[12];
619
620         mp_set_mpe(delay_watch_checks);
621         mp_set_ovr(delay_watch_checks);
622         mp_set_hwe(delay_watch_checks);
623         mp_set_conf(delay_watch_checks);
624         mp_set_default(delay_watch_checks, DEFAULT_DELAY_CHECKS);
625 out:
626         print_off_int_undef(buff, 12, &mp->delay_watch_checks);
627         condlog(3, "%s: delay_watch_checks = %s %s", mp->alias, buff, origin);
628         return 0;
629 }
630
631 int select_delay_wait_checks(struct config *conf, struct multipath *mp)
632 {
633         char *origin, buff[12];
634
635         mp_set_mpe(delay_wait_checks);
636         mp_set_ovr(delay_wait_checks);
637         mp_set_hwe(delay_wait_checks);
638         mp_set_conf(delay_wait_checks);
639         mp_set_default(delay_wait_checks, DEFAULT_DELAY_CHECKS);
640 out:
641         print_off_int_undef(buff, 12, &mp->delay_wait_checks);
642         condlog(3, "%s: delay_wait_checks = %s %s", mp->alias, buff, origin);
643         return 0;
644
645 }
646 int select_san_path_err_threshold(struct config *conf, struct multipath *mp)
647 {
648         char *origin, buff[12];
649
650         mp_set_mpe(san_path_err_threshold);
651         mp_set_ovr(san_path_err_threshold);
652         mp_set_hwe(san_path_err_threshold);
653         mp_set_conf(san_path_err_threshold);
654         mp_set_default(san_path_err_threshold, DEFAULT_ERR_CHECKS);
655 out:
656         print_off_int_undef(buff, 12, &mp->san_path_err_threshold);
657         condlog(3, "%s: san_path_err_threshold = %s %s", mp->alias, buff, origin);
658         return 0;
659 }
660
661 int select_san_path_err_forget_rate(struct config *conf, struct multipath *mp)
662 {
663         char *origin, buff[12];
664
665         mp_set_mpe(san_path_err_forget_rate);
666         mp_set_ovr(san_path_err_forget_rate);
667         mp_set_hwe(san_path_err_forget_rate);
668         mp_set_conf(san_path_err_forget_rate);
669         mp_set_default(san_path_err_forget_rate, DEFAULT_ERR_CHECKS);
670 out:
671         print_off_int_undef(buff, 12, &mp->san_path_err_forget_rate);
672         condlog(3, "%s: san_path_err_forget_rate = %s %s", mp->alias, buff, origin);
673         return 0;
674
675 }
676 int select_san_path_err_recovery_time(struct config *conf, struct multipath *mp)
677 {
678         char *origin, buff[12];
679
680         mp_set_mpe(san_path_err_recovery_time);
681         mp_set_ovr(san_path_err_recovery_time);
682         mp_set_hwe(san_path_err_recovery_time);
683         mp_set_conf(san_path_err_recovery_time);
684         mp_set_default(san_path_err_recovery_time, DEFAULT_ERR_CHECKS);
685 out:
686         print_off_int_undef(buff, 12, &mp->san_path_err_recovery_time);
687         condlog(3, "%s: san_path_err_recovery_time = %s %s", mp->alias, buff, origin);
688         return 0;
689
690 }
691 int select_skip_kpartx (struct config *conf, struct multipath * mp)
692 {
693         char *origin;
694
695         mp_set_mpe(skip_kpartx);
696         mp_set_ovr(skip_kpartx);
697         mp_set_hwe(skip_kpartx);
698         mp_set_conf(skip_kpartx);
699         mp_set_default(skip_kpartx, DEFAULT_SKIP_KPARTX);
700 out:
701         condlog(3, "%s: skip_kpartx = %s %s", mp->alias,
702                 (mp->skip_kpartx == SKIP_KPARTX_ON)? "yes" : "no",
703                 origin);
704         return 0;
705 }
706
707 extern int
708 select_max_sectors_kb (struct config *conf, struct multipath * mp)
709 {
710         char *origin;
711
712         mp_set_mpe(max_sectors_kb);
713         mp_set_ovr(max_sectors_kb);
714         mp_set_hwe(max_sectors_kb);
715         mp_set_conf(max_sectors_kb);
716         return 0;
717 out:
718         condlog(3, "%s: max_sectors_kb = %i %s", mp->alias, mp->max_sectors_kb,
719                 origin);
720         return 0;
721 }