4111fa5d62db8907ae33352888683eefbee3b2ef
[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(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
378         if ((tpgs = get_target_port_group_support(pp->fd)) <= 0)
379                 return;
380         pp->tpgs = tpgs;
381         ret = get_target_port_group(pp);
382         if (ret < 0)
383                 return;
384         if (get_asymmetric_access_state(pp->fd, ret) < 0)
385                 return;
386         prio_get(p, PRIO_ALUA, DEFAULT_PRIO_ARGS);
387 }
388
389 #define set_prio(src, msg)                                              \
390 do {                                                                    \
391         if (src && src->prio_name) {                                    \
392                 prio_get(p, src->prio_name, src->prio_args);            \
393                 origin = msg;                                           \
394                 goto out;                                               \
395         }                                                               \
396 } while(0)
397
398 extern int
399 select_prio (struct path * pp)
400 {
401         char *origin;
402         struct mpentry * mpe;
403         struct prio * p = &pp->prio;
404
405         if (pp->detect_prio == DETECT_PRIO_ON) {
406                 detect_prio(pp);
407                 if (prio_selected(p)) {
408                         origin = "(detected setting)";
409                         goto out;
410                 }
411         }
412         mpe = find_mpe(pp->wwid);
413         set_prio(mpe, "(LUN setting)");
414         set_prio(conf->overrides, "(overrides setting)");
415         set_prio(pp->hwe, "controller setting)");
416         set_prio(conf, "(config file default)");
417         prio_get(p, DEFAULT_PRIO, DEFAULT_PRIO_ARGS);
418         origin = "(internal default)";
419 out:
420         /*
421          * fetch tpgs mode for alua, if its not already obtained
422          */
423         if (!strncmp(prio_name(p), PRIO_ALUA, PRIO_NAME_LEN)) {
424                 int tpgs = 0;
425                 if(!pp->tpgs &&
426                    (tpgs = get_target_port_group_support(pp->fd)) >= 0)
427                         pp->tpgs = tpgs;
428         }
429         condlog(3, "%s: prio = %s %s", pp->dev, prio_name(p), origin);
430         condlog(3, "%s: prio args = \"%s\" %s", pp->dev, prio_args(p), origin);
431         return 0;
432 }
433
434 extern int
435 select_no_path_retry(struct multipath *mp)
436 {
437         char *origin = NULL;
438         char buff[12];
439
440         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) {
441                 condlog(0, "flush_on_last_del in progress");
442                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
443                 return 0;
444         }
445         mp_set_mpe(no_path_retry);
446         mp_set_ovr(no_path_retry);
447         mp_set_hwe(no_path_retry);
448         mp_set_conf(no_path_retry);
449 out:
450         print_no_path_retry(buff, 12, &mp->no_path_retry);
451         if (origin)
452                 condlog(3, "%s: no_path_retry = %s %s", mp->alias, buff,
453                         origin);
454         else if (mp->no_path_retry != NO_PATH_RETRY_UNDEF)
455                 condlog(3, "%s: no_path_retry = %s (inheritied setting)",
456                         mp->alias, buff);
457         else
458                 condlog(3, "%s: no_path_retry = undef (internal default)",
459                         mp->alias);
460         return 0;
461 }
462
463 int
464 select_minio_rq (struct multipath * mp)
465 {
466         char *origin;
467
468         do_set(minio_rq, mp->mpe, mp->minio, "(LUN setting)");
469         do_set(minio_rq, conf->overrides, mp->minio, "(overrides setting)");
470         do_set(minio_rq, mp->hwe, mp->minio, "(controller setting)");
471         do_set(minio_rq, conf, mp->minio, "(config file setting)");
472         do_default(mp->minio, DEFAULT_MINIO_RQ);
473 out:
474         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
475         return 0;
476 }
477
478 int
479 select_minio_bio (struct multipath * mp)
480 {
481         char *origin;
482
483         mp_set_mpe(minio);
484         mp_set_ovr(minio);
485         mp_set_hwe(minio);
486         mp_set_conf(minio);
487         mp_set_default(minio, DEFAULT_MINIO);
488 out:
489         condlog(3, "%s: minio = %i %s", mp->alias, mp->minio, origin);
490         return 0;
491 }
492
493 extern int
494 select_minio (struct multipath * mp)
495 {
496         unsigned int minv_dmrq[3] = {1, 1, 0};
497
498         if (VERSION_GE(conf->version, minv_dmrq))
499                 return select_minio_rq(mp);
500         else
501                 return select_minio_bio(mp);
502 }
503
504 extern int
505 select_fast_io_fail(struct multipath *mp)
506 {
507         char *origin, buff[12];
508
509         mp_set_ovr(fast_io_fail);
510         mp_set_hwe(fast_io_fail);
511         mp_set_conf(fast_io_fail);
512         mp_set_default(fast_io_fail, DEFAULT_FAST_IO_FAIL);
513 out:
514         print_fast_io_fail(buff, 12, &mp->fast_io_fail);
515         condlog(3, "%s: fast_io_fail_tmo = %s %s", mp->alias, buff, origin);
516         return 0;
517 }
518
519 extern int
520 select_dev_loss(struct multipath *mp)
521 {
522         char *origin, buff[12];
523
524         mp_set_ovr(dev_loss);
525         mp_set_hwe(dev_loss);
526         mp_set_conf(dev_loss);
527         mp->dev_loss = 0;
528         return 0;
529 out:
530         print_dev_loss(buff, 12, &mp->dev_loss);
531         condlog(3, "%s: dev_loss_tmo = %s %s", mp->alias, buff, origin);
532         return 0;
533 }
534
535 extern int
536 select_flush_on_last_del(struct multipath *mp)
537 {
538         char *origin;
539
540         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
541                 return 0;
542         mp_set_mpe(flush_on_last_del);
543         mp_set_ovr(flush_on_last_del);
544         mp_set_hwe(flush_on_last_del);
545         mp_set_conf(flush_on_last_del);
546         mp_set_default(flush_on_last_del, FLUSH_DISABLED);
547 out:
548         condlog(3, "%s: flush_on_last_del = %s %s", mp->alias,
549                 (mp->flush_on_last_del == FLUSH_ENABLED)? "yes" : "no", origin);
550         return 0;
551 }
552
553 extern int
554 select_reservation_key (struct multipath * mp)
555 {
556         char *origin, buff[12];
557
558         mp_set_mpe(reservation_key);
559         mp_set_conf(reservation_key);
560         mp->reservation_key = NULL;
561         return 0;
562 out:
563         print_reservation_key(buff, 12, &mp->reservation_key);
564         condlog(3, "%s: reservation_key = %s %s", mp->alias, buff, origin);
565         return 0;
566 }
567
568 extern int
569 select_retain_hwhandler (struct multipath * mp)
570 {
571         char *origin;
572         unsigned int minv_dm_retain[3] = {1, 5, 0};
573
574         if (!VERSION_GE(conf->version, minv_dm_retain)) {
575                 mp->retain_hwhandler = RETAIN_HWHANDLER_OFF;
576                 origin = "(requires kernel version >= 1.5.0)";
577                 goto out;
578         }
579         mp_set_ovr(retain_hwhandler);
580         mp_set_hwe(retain_hwhandler);
581         mp_set_conf(retain_hwhandler);
582         mp_set_default(retain_hwhandler, DEFAULT_RETAIN_HWHANDLER);
583 out:
584         condlog(3, "%s: retain_attached_hw_handler = %s %s", mp->alias,
585                 (mp->retain_hwhandler == RETAIN_HWHANDLER_ON)? "yes" : "no",
586                 origin);
587         return 0;
588 }
589
590 extern int
591 select_detect_prio (struct path * pp)
592 {
593         char *origin;
594
595         pp_set_ovr(detect_prio);
596         pp_set_hwe(detect_prio);
597         pp_set_conf(detect_prio);
598         pp_set_default(detect_prio, DEFAULT_DETECT_PRIO);
599 out:
600         condlog(3, "%s: detect_prio = %s %s", pp->dev,
601                 (pp->detect_prio == DETECT_PRIO_ON)? "yes" : "no", origin);
602         return 0;
603 }
604
605 extern int
606 select_deferred_remove (struct multipath *mp)
607 {
608         char *origin;
609
610 #ifndef LIBDM_API_DEFERRED
611         mp->deferred_remove = DEFERRED_REMOVE_OFF;
612         origin = "(not compiled with support)";
613         goto out;
614 #endif
615         if (mp->deferred_remove == DEFERRED_REMOVE_IN_PROGRESS) {
616                 condlog(3, "%s: deferred remove in progress", mp->alias);
617                 return 0;
618         }
619         mp_set_mpe(deferred_remove);
620         mp_set_ovr(deferred_remove);
621         mp_set_hwe(deferred_remove);
622         mp_set_conf(deferred_remove);
623         mp_set_default(deferred_remove, DEFAULT_DEFERRED_REMOVE);
624 out:
625         condlog(3, "%s: deferred_remove = %s %s", mp->alias,
626                 (mp->deferred_remove == DEFERRED_REMOVE_ON)? "yes" : "no",
627                 origin);
628         return 0;
629 }
630
631 extern int
632 select_delay_watch_checks(struct multipath *mp)
633 {
634         char *origin, buff[12];
635
636         mp_set_mpe(delay_watch_checks);
637         mp_set_ovr(delay_watch_checks);
638         mp_set_hwe(delay_watch_checks);
639         mp_set_conf(delay_watch_checks);
640         mp_set_default(delay_watch_checks, DEFAULT_DELAY_CHECKS);
641 out:
642         print_delay_checks(buff, 12, &mp->delay_watch_checks);
643         condlog(3, "%s: delay_watch_checks = %s %s", mp->alias, buff, origin);
644         return 0;
645 }
646
647 extern int
648 select_delay_wait_checks(struct multipath *mp)
649 {
650         char *origin, buff[12];
651
652         mp_set_mpe(delay_wait_checks);
653         mp_set_ovr(delay_wait_checks);
654         mp_set_hwe(delay_wait_checks);
655         mp_set_conf(delay_wait_checks);
656         mp_set_default(delay_wait_checks, DEFAULT_DELAY_CHECKS);
657 out:
658         print_delay_checks(buff, 12, &mp->delay_wait_checks);
659         condlog(3, "%s: delay_wait_checks = %s %s", mp->alias, buff, origin);
660         return 0;
661 }