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