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