Make params variable local
[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
21 pgpolicyfn *pgpolicies[] = {
22         NULL,
23         one_path_per_group,
24         one_group,
25         group_by_serial,
26         group_by_prio,
27         group_by_node_name
28 };
29
30 extern int
31 select_mode (struct multipath *mp)
32 {
33         if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_MODE))) {
34                 mp->attribute_flags |= (1 << ATTR_MODE);
35                 mp->mode = mp->mpe->mode;
36                 condlog(3, "mode = 0%o (LUN setting)", mp->mode);
37         }
38         else if (conf->attribute_flags & (1 << ATTR_MODE)) {
39                 mp->attribute_flags |= (1 << ATTR_MODE);
40                 mp->mode = conf->mode;
41                 condlog(3, "mode = 0%o (config file default)", mp->mode);
42         }
43         else
44                 mp->attribute_flags &= ~(1 << ATTR_MODE);
45         return 0;
46 }
47
48 extern int
49 select_uid (struct multipath *mp)
50 {
51         if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_UID))) {
52                 mp->attribute_flags |= (1 << ATTR_UID);
53                 mp->uid = mp->mpe->uid;
54                 condlog(3, "uid = %u (LUN setting)", mp->uid);
55         }
56         else if (conf->attribute_flags & (1 << ATTR_UID)) {
57                 mp->attribute_flags |= (1 << ATTR_UID);
58                 mp->uid = conf->uid;
59                 condlog(3, "uid = %u (config file default)", mp->uid);
60         }
61         else
62                 mp->attribute_flags &= ~(1 << ATTR_UID);
63         return 0;
64 }
65
66 extern int
67 select_gid (struct multipath *mp)
68 {
69         if (mp->mpe && (mp->mpe->attribute_flags & (1 << ATTR_GID))) {
70                 mp->attribute_flags |= (1 << ATTR_GID);
71                 mp->gid = mp->mpe->gid;
72                 condlog(3, "gid = %u (LUN setting)", mp->gid);
73         }
74         else if (conf->attribute_flags & (1 << ATTR_GID)) {
75                 mp->attribute_flags |= (1 << ATTR_GID);
76                 mp->gid = conf->gid;
77                 condlog(3, "gid = %u (config file default)", mp->gid);
78         }
79         else
80                 mp->attribute_flags &= ~(1 << ATTR_GID);
81         return 0;
82 }
83
84 /*
85  * selectors :
86  * traverse the configuration layers from most specific to most generic
87  * stop at first explicit setting found
88  */
89 extern int
90 select_rr_weight (struct multipath * mp)
91 {
92         if (mp->mpe && mp->mpe->rr_weight) {
93                 mp->rr_weight = mp->mpe->rr_weight;
94                 condlog(3, "%s: rr_weight = %i (LUN setting)",
95                         mp->alias, mp->rr_weight);
96                 return 0;
97         }
98         if (mp->hwe && mp->hwe->rr_weight) {
99                 mp->rr_weight = mp->hwe->rr_weight;
100                 condlog(3, "%s: rr_weight = %i (controller setting)",
101                         mp->alias, mp->rr_weight);
102                 return 0;
103         }
104         if (conf->rr_weight) {
105                 mp->rr_weight = conf->rr_weight;
106                 condlog(3, "%s: rr_weight = %i (config file default)",
107                         mp->alias, mp->rr_weight);
108                 return 0;
109         }
110         mp->rr_weight = RR_WEIGHT_NONE;
111         condlog(3, "%s: rr_weight = %i (internal default)",
112                 mp->alias, mp->rr_weight);
113         return 0;
114 }
115
116 extern int
117 select_pgfailback (struct multipath * mp)
118 {
119         if (mp->mpe && mp->mpe->pgfailback != FAILBACK_UNDEF) {
120                 mp->pgfailback = mp->mpe->pgfailback;
121                 condlog(3, "%s: pgfailback = %i (LUN setting)",
122                         mp->alias, mp->pgfailback);
123                 return 0;
124         }
125         if (mp->hwe && mp->hwe->pgfailback != FAILBACK_UNDEF) {
126                 mp->pgfailback = mp->hwe->pgfailback;
127                 condlog(3, "%s: pgfailback = %i (controller setting)",
128                         mp->alias, mp->pgfailback);
129                 return 0;
130         }
131         if (conf->pgfailback != FAILBACK_UNDEF) {
132                 mp->pgfailback = conf->pgfailback;
133                 condlog(3, "%s: pgfailback = %i (config file default)",
134                         mp->alias, mp->pgfailback);
135                 return 0;
136         }
137         mp->pgfailback = DEFAULT_FAILBACK;
138         condlog(3, "%s: pgfailover = %i (internal default)",
139                 mp->alias, mp->pgfailback);
140         return 0;
141 }
142
143 extern int
144 select_pgpolicy (struct multipath * mp)
145 {
146         char pgpolicy_name[POLICY_NAME_SIZE];
147
148         if (conf->pgpolicy_flag > 0) {
149                 mp->pgpolicy = conf->pgpolicy_flag;
150                 mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
151                 get_pgpolicy_name(pgpolicy_name, POLICY_NAME_SIZE,
152                                   mp->pgpolicy);
153                 condlog(3, "%s: pgpolicy = %s (cmd line flag)",
154                         mp->alias, pgpolicy_name);
155                 return 0;
156         }
157         if (mp->mpe && mp->mpe->pgpolicy > 0) {
158                 mp->pgpolicy = mp->mpe->pgpolicy;
159                 mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
160                 get_pgpolicy_name(pgpolicy_name, POLICY_NAME_SIZE,
161                                   mp->pgpolicy);
162                 condlog(3, "%s: pgpolicy = %s (LUN setting)",
163                         mp->alias, pgpolicy_name);
164                 return 0;
165         }
166         if (mp->hwe && mp->hwe->pgpolicy > 0) {
167                 mp->pgpolicy = mp->hwe->pgpolicy;
168                 mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
169                 get_pgpolicy_name(pgpolicy_name, POLICY_NAME_SIZE,
170                                   mp->pgpolicy);
171                 condlog(3, "%s: pgpolicy = %s (controller setting)",
172                         mp->alias, pgpolicy_name);
173                 return 0;
174         }
175         if (conf->pgpolicy > 0) {
176                 mp->pgpolicy = conf->pgpolicy;
177                 mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
178                 get_pgpolicy_name(pgpolicy_name, POLICY_NAME_SIZE,
179                                   mp->pgpolicy);
180                 condlog(3, "%s: pgpolicy = %s (config file default)",
181                         mp->alias, pgpolicy_name);
182                 return 0;
183         }
184         mp->pgpolicy = DEFAULT_PGPOLICY;
185         mp->pgpolicyfn = pgpolicies[mp->pgpolicy];
186         get_pgpolicy_name(pgpolicy_name, POLICY_NAME_SIZE, mp->pgpolicy);
187         condlog(3, "%s: pgpolicy = %s (internal default)",
188                 mp->alias, pgpolicy_name);
189         return 0;
190 }
191
192 extern int
193 select_selector (struct multipath * mp)
194 {
195         if (mp->mpe && mp->mpe->selector) {
196                 mp->selector = mp->mpe->selector;
197                 condlog(3, "%s: selector = %s (LUN setting)",
198                         mp->alias, mp->selector);
199                 return 0;
200         }
201         if (mp->hwe && mp->hwe->selector) {
202                 mp->selector = mp->hwe->selector;
203                 condlog(3, "%s: selector = %s (controller setting)",
204                         mp->alias, mp->selector);
205                 return 0;
206         }
207         if (conf->selector) {
208                 mp->selector = conf->selector;
209                 condlog(3, "%s: selector = %s (config file default)",
210                         mp->alias, mp->selector);
211                 return 0;
212         }
213         mp->selector = set_default(DEFAULT_SELECTOR);
214         condlog(3, "%s: selector = %s (internal default)",
215                 mp->alias, mp->selector);
216         return 0;
217 }
218
219 static void
220 select_alias_prefix (struct multipath * mp)
221 {
222         if (mp->hwe && mp->hwe->alias_prefix) {
223                 mp->alias_prefix = mp->hwe->alias_prefix;
224                 condlog(3, "%s: alias_prefix = %s (controller setting)",
225                         mp->wwid, mp->alias_prefix);
226                 return;
227         }
228         if (conf->alias_prefix) {
229                 mp->alias_prefix = conf->alias_prefix;
230                 condlog(3, "%s: alias_prefix = %s (config file default)",
231                         mp->wwid, mp->alias_prefix);
232                 return;
233         }
234         mp->alias_prefix = set_default(DEFAULT_ALIAS_PREFIX);
235         condlog(3, "%s: alias_prefix = %s (internal default)",
236                 mp->wwid, mp->alias_prefix);
237 }
238
239 extern int
240 select_alias (struct multipath * mp)
241 {
242         if (mp->mpe && mp->mpe->alias)
243                 mp->alias = STRDUP(mp->mpe->alias);
244         else {
245                 mp->alias = NULL;
246                 if (conf->user_friendly_names) {
247                         select_alias_prefix(mp);
248                         mp->alias = get_user_friendly_alias(mp->wwid,
249                                         conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
250                 }
251                 if (mp->alias == NULL)
252                         mp->alias = dm_get_name(mp->wwid);
253                 if (mp->alias == NULL)
254                         mp->alias = STRDUP(mp->wwid);
255         }
256
257         return 0;
258 }
259
260 extern int
261 select_features (struct multipath * mp)
262 {
263         if (mp->hwe && mp->hwe->features) {
264                 mp->features = mp->hwe->features;
265                 condlog(3, "%s: features = %s (controller setting)",
266                         mp->alias, mp->features);
267                 return 0;
268         }
269         if (conf->features) {
270                 mp->features = conf->features;
271                 condlog(3, "%s: features = %s (config file default)",
272                         mp->alias, mp->features);
273                 return 0;
274         }
275         mp->features = set_default(DEFAULT_FEATURES);
276         condlog(3, "%s: features = %s (internal default)",
277                 mp->alias, mp->features);
278         return 0;
279 }
280
281 extern int
282 select_hwhandler (struct multipath * mp)
283 {
284         if (mp->hwe && mp->hwe->hwhandler) {
285                 mp->hwhandler = mp->hwe->hwhandler;
286                 condlog(3, "%s: hwhandler = %s (controller setting)",
287                         mp->alias, mp->hwhandler);
288                 return 0;
289         }
290         if (conf->hwhandler) {
291                 mp->hwhandler = conf->hwhandler;
292                 condlog(3, "%s: hwhandler = %s (config file default)",
293                         mp->alias, mp->hwhandler);
294                 return 0;
295         }
296         mp->hwhandler = set_default(DEFAULT_HWHANDLER);
297         condlog(3, "%s: hwhandler = %s (internal default)",
298                 mp->alias, mp->hwhandler);
299         return 0;
300 }
301
302 extern int
303 select_checker(struct path *pp)
304 {
305         struct checker * c = &pp->checker;
306
307         if (pp->hwe && pp->hwe->checker_name) {
308                 checker_get(c, pp->hwe->checker_name);
309                 condlog(3, "%s: path checker = %s (controller setting)",
310                         pp->dev, checker_name(c));
311                 goto out;
312         }
313         if (conf->checker_name) {
314                 checker_get(c, conf->checker_name);
315                 condlog(3, "%s: path checker = %s (config file default)",
316                         pp->dev, checker_name(c));
317                 goto out;
318         }
319         checker_get(c, DEFAULT_CHECKER);
320         condlog(3, "%s: path checker = %s (internal default)",
321                 pp->dev, checker_name(c));
322 out:
323         if (conf->checker_timeout) {
324                 c->timeout = conf->checker_timeout * 1000;
325                 condlog(3, "%s: checker timeout = %u ms (config file default)",
326                                 pp->dev, c->timeout);
327         }
328         else if (sysfs_get_timeout(pp->sysdev, &c->timeout) == 0)
329                 condlog(3, "%s: checker timeout = %u ms (sysfs setting)",
330                                 pp->dev, c->timeout);
331         else {
332                 c->timeout = DEF_TIMEOUT;
333                 condlog(3, "%s: checker timeout = %u ms (internal default)",
334                                 pp->dev, c->timeout);
335         }
336         return 0;
337 }
338
339 extern int
340 select_getuid (struct path * pp)
341 {
342         if (pp->hwe && pp->hwe->getuid) {
343                 pp->getuid = pp->hwe->getuid;
344                 condlog(3, "%s: getuid = %s (controller setting)",
345                         pp->dev, pp->getuid);
346                 return 0;
347         }
348         if (conf->getuid) {
349                 pp->getuid = conf->getuid;
350                 condlog(3, "%s: getuid = %s (config file default)",
351                         pp->dev, pp->getuid);
352                 return 0;
353         }
354         pp->getuid = STRDUP(DEFAULT_GETUID);
355         condlog(3, "%s: getuid = %s (internal default)",
356                 pp->dev, pp->getuid);
357         return 0;
358 }
359
360 extern int
361 select_prio (struct path * pp)
362 {
363         if (pp->hwe && pp->hwe->prio_name) {
364                 pp->prio = prio_lookup(pp->hwe->prio_name);
365                 prio_set_args(pp->prio, pp->hwe->prio_args);
366                 condlog(3, "%s: prio = %s (controller setting)",
367                         pp->dev, pp->hwe->prio_name);
368                 condlog(3, "%s: prio args = %s (controller setting)",
369                         pp->dev, pp->hwe->prio_args);
370                 return 0;
371         }
372         if (conf->prio_name) {
373                 pp->prio = prio_lookup(conf->prio_name);
374                 prio_set_args(pp->prio, conf->prio_args);
375                 condlog(3, "%s: prio = %s (config file default)",
376                         pp->dev, conf->prio_name);
377                 condlog(3, "%s: prio args = %s (config file default)",
378                         pp->dev, conf->prio_args);
379                 return 0;
380         }
381         pp->prio = prio_lookup(DEFAULT_PRIO);
382         prio_set_args(pp->prio, DEFAULT_PRIO_ARGS);
383         condlog(3, "%s: prio = %s (internal default)",
384                 pp->dev, DEFAULT_PRIO);
385         condlog(3, "%s: prio = %s (internal default)",
386                 pp->dev, DEFAULT_PRIO_ARGS);
387         return 0;
388 }
389
390 extern int
391 select_no_path_retry(struct multipath *mp)
392 {
393         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) {
394                 condlog(0, "flush_on_last_del in progress");
395                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
396         }
397         if (mp->mpe && mp->mpe->no_path_retry != NO_PATH_RETRY_UNDEF) {
398                 mp->no_path_retry = mp->mpe->no_path_retry;
399                 condlog(3, "%s: no_path_retry = %i (multipath setting)",
400                         mp->alias, mp->no_path_retry);
401                 return 0;
402         }
403         if (mp->hwe && mp->hwe->no_path_retry != NO_PATH_RETRY_UNDEF) {
404                 mp->no_path_retry = mp->hwe->no_path_retry;
405                 condlog(3, "%s: no_path_retry = %i (controller setting)",
406                         mp->alias, mp->no_path_retry);
407                 return 0;
408         }
409         if (conf->no_path_retry != NO_PATH_RETRY_UNDEF) {
410                 mp->no_path_retry = conf->no_path_retry;
411                 condlog(3, "%s: no_path_retry = %i (config file default)",
412                         mp->alias, mp->no_path_retry);
413                 return 0;
414         }
415         mp->no_path_retry = NO_PATH_RETRY_UNDEF;
416         condlog(3, "%s: no_path_retry = NONE (internal default)",
417                 mp->alias);
418         return 0;
419 }
420
421 int
422 select_minio_rq (struct multipath * mp)
423 {
424         if (mp->mpe && mp->mpe->minio_rq) {
425                 mp->minio = mp->mpe->minio_rq;
426                 condlog(3, "%s: minio = %i rq (LUN setting)",
427                         mp->alias, mp->minio);
428                 return 0;
429         }
430         if (mp->hwe && mp->hwe->minio_rq) {
431                 mp->minio = mp->hwe->minio_rq;
432                 condlog(3, "%s: minio = %i rq (controller setting)",
433                         mp->alias, mp->minio);
434                 return 0;
435         }
436         if (conf->minio) {
437                 mp->minio = conf->minio_rq;
438                 condlog(3, "%s: minio = %i rq (config file default)",
439                         mp->alias, mp->minio);
440                 return 0;
441         }
442         mp->minio = DEFAULT_MINIO_RQ;
443         condlog(3, "%s: minio = %i rq (internal default)",
444                 mp->alias, mp->minio);
445         return 0;
446 }
447
448 int
449 select_minio_bio (struct multipath * mp)
450 {
451         if (mp->mpe && mp->mpe->minio) {
452                 mp->minio = mp->mpe->minio;
453                 condlog(3, "%s: minio = %i (LUN setting)",
454                         mp->alias, mp->minio);
455                 return 0;
456         }
457         if (mp->hwe && mp->hwe->minio) {
458                 mp->minio = mp->hwe->minio;
459                 condlog(3, "%s: minio = %i (controller setting)",
460                         mp->alias, mp->minio);
461                 return 0;
462         }
463         if (conf->minio) {
464                 mp->minio = conf->minio;
465                 condlog(3, "%s: minio = %i (config file default)",
466                         mp->alias, mp->minio);
467                 return 0;
468         }
469         mp->minio = DEFAULT_MINIO;
470         condlog(3, "%s: minio = %i (internal default)",
471                 mp->alias, mp->minio);
472         return 0;
473 }
474
475 extern int
476 select_minio (struct multipath * mp)
477 {
478         if (conf->dmrq)
479                 return select_minio_rq(mp);
480         else
481                 return select_minio_bio(mp);
482 }
483
484 extern int
485 select_pg_timeout(struct multipath *mp)
486 {
487         if (mp->mpe && mp->mpe->pg_timeout != PGTIMEOUT_UNDEF) {
488                 mp->pg_timeout = mp->mpe->pg_timeout;
489                 if (mp->pg_timeout > 0)
490                         condlog(3, "%s: pg_timeout = %d (multipath setting)",
491                                 mp->alias, mp->pg_timeout);
492                 else
493                         condlog(3, "%s: pg_timeout = NONE (multipath setting)",
494                                 mp->alias);
495                 return 0;
496         }
497         if (mp->hwe && mp->hwe->pg_timeout != PGTIMEOUT_UNDEF) {
498                 mp->pg_timeout = mp->hwe->pg_timeout;
499                 if (mp->pg_timeout > 0)
500                         condlog(3, "%s: pg_timeout = %d (controller setting)",
501                                 mp->alias, mp->pg_timeout);
502                 else
503                         condlog(3, "%s: pg_timeout = NONE (controller setting)",
504                                 mp->alias);
505                 return 0;
506         }
507         if (conf->pg_timeout != PGTIMEOUT_UNDEF) {
508                 mp->pg_timeout = conf->pg_timeout;
509                 if (mp->pg_timeout > 0)
510                         condlog(3, "%s: pg_timeout = %d (config file default)",
511                                 mp->alias, mp->pg_timeout);
512                 else
513                         condlog(3,
514                                 "%s: pg_timeout = NONE (config file default)",
515                                 mp->alias);
516                 return 0;
517         }
518         mp->pg_timeout = PGTIMEOUT_UNDEF;
519         condlog(3, "%s: pg_timeout = NONE (internal default)", mp->alias);
520         return 0;
521 }
522
523 extern int
524 select_fast_io_fail(struct multipath *mp)
525 {
526         if (mp->hwe && mp->hwe->fast_io_fail) {
527                 mp->fast_io_fail = mp->hwe->fast_io_fail;
528                 if (mp->fast_io_fail == -1)
529                         condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias);
530                 else
531                         condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias, mp->fast_io_fail);
532                 return 0;
533         }
534         if (conf->fast_io_fail) {
535                 mp->fast_io_fail = conf->fast_io_fail;
536                 if (mp->fast_io_fail == -1)
537                         condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias);
538                 else
539                         condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias, mp->fast_io_fail);
540                 return 0;
541         }
542         mp->fast_io_fail = 0;
543         return 0;
544 }
545
546 extern int
547 select_dev_loss(struct multipath *mp)
548 {
549         if (mp->hwe && mp->hwe->dev_loss) {
550                 mp->dev_loss = mp->hwe->dev_loss;
551                 condlog(3, "%s: dev_loss_tmo = %u (controller default)",
552                         mp->alias, mp->dev_loss);
553                 return 0;
554         }
555         if (conf->dev_loss) {
556                 mp->dev_loss = conf->dev_loss;
557                 condlog(3, "%s: dev_loss_tmo = %u (config file default)",
558                         mp->alias, mp->dev_loss);
559                 return 0;
560         }
561         mp->dev_loss = 0;
562         return 0;
563 }
564
565 extern int
566 select_flush_on_last_del(struct multipath *mp)
567 {
568         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
569                 return 0;
570         if (mp->mpe && mp->mpe->flush_on_last_del != FLUSH_UNDEF) {
571                 mp->flush_on_last_del = mp->mpe->flush_on_last_del;
572                 condlog(3, "flush_on_last_del = %i (multipath setting)",
573                                 mp->flush_on_last_del);
574                 return 0;
575         }
576         if (mp->hwe && mp->hwe->flush_on_last_del != FLUSH_UNDEF) {
577                 mp->flush_on_last_del = mp->hwe->flush_on_last_del;
578                 condlog(3, "flush_on_last_del = %i (controler setting)",
579                                 mp->flush_on_last_del);
580                 return 0;
581         }
582         if (conf->flush_on_last_del != FLUSH_UNDEF) {
583                 mp->flush_on_last_del = conf->flush_on_last_del;
584                 condlog(3, "flush_on_last_del = %i (config file default)",
585                                 mp->flush_on_last_del);
586                 return 0;
587         }
588         mp->flush_on_last_del = FLUSH_UNDEF;
589         condlog(3, "flush_on_last_del = DISABLED (internal default)");
590         return 0;
591 }