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