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