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