Use struct udev_device instead of sysdev
[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 #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 extern int
241 select_alias (struct multipath * mp)
242 {
243         if (mp->mpe && mp->mpe->alias)
244                 mp->alias = STRDUP(mp->mpe->alias);
245         else {
246                 mp->alias = NULL;
247                 if (conf->user_friendly_names) {
248                         select_alias_prefix(mp);
249                         mp->alias = get_user_friendly_alias(mp->wwid,
250                                         conf->bindings_file, mp->alias_prefix, conf->bindings_read_only);
251                 }
252                 if (mp->alias == NULL)
253                         mp->alias = dm_get_name(mp->wwid);
254                 if (mp->alias == NULL)
255                         mp->alias = STRDUP(mp->wwid);
256         }
257
258         return mp->alias ? 0 : 1;
259 }
260
261 extern int
262 select_features (struct multipath * mp)
263 {
264         struct mpentry * mpe;
265         char *origin;
266
267         if ((mpe = find_mpe(mp->wwid)) && mpe->features) {
268                 mp->features = STRDUP(mpe->features);
269                 origin = "LUN setting";
270         } else if (mp->hwe && mp->hwe->features) {
271                 mp->features = STRDUP(mp->hwe->features);
272                 origin = "controller setting";
273         } else {
274                 mp->features = STRDUP(conf->features);
275                 origin = "internal default";
276         }
277         condlog(3, "%s: features = %s (%s)",
278                 mp->alias, mp->features, origin);
279         if (strstr(mp->features, "queue_if_no_path")) {
280                 if (mp->no_path_retry == NO_PATH_RETRY_UNDEF)
281                         mp->no_path_retry = NO_PATH_RETRY_QUEUE;
282                 else if (mp->no_path_retry == NO_PATH_RETRY_FAIL) {
283                         condlog(1, "%s: config error, overriding 'no_path_retry' value",
284                                 mp->alias);
285                         mp->no_path_retry = NO_PATH_RETRY_QUEUE;
286                 }
287         }
288         return 0;
289 }
290
291 extern int
292 select_hwhandler (struct multipath * mp)
293 {
294         if (mp->hwe && mp->hwe->hwhandler) {
295                 mp->hwhandler = mp->hwe->hwhandler;
296                 condlog(3, "%s: hwhandler = %s (controller setting)",
297                         mp->alias, mp->hwhandler);
298                 return 0;
299         }
300         if (conf->hwhandler) {
301                 mp->hwhandler = conf->hwhandler;
302                 condlog(3, "%s: hwhandler = %s (config file default)",
303                         mp->alias, mp->hwhandler);
304                 return 0;
305         }
306         mp->hwhandler = set_default(DEFAULT_HWHANDLER);
307         condlog(3, "%s: hwhandler = %s (internal default)",
308                 mp->alias, mp->hwhandler);
309         return 0;
310 }
311
312 extern int
313 select_checker(struct path *pp)
314 {
315         struct checker * c = &pp->checker;
316
317         if (pp->hwe && pp->hwe->checker_name) {
318                 checker_get(c, pp->hwe->checker_name);
319                 condlog(3, "%s: path checker = %s (controller setting)",
320                         pp->dev, checker_name(c));
321                 goto out;
322         }
323         if (conf->checker_name) {
324                 checker_get(c, conf->checker_name);
325                 condlog(3, "%s: path checker = %s (config file default)",
326                         pp->dev, checker_name(c));
327                 goto out;
328         }
329         checker_get(c, DEFAULT_CHECKER);
330         condlog(3, "%s: path checker = %s (internal default)",
331                 pp->dev, checker_name(c));
332 out:
333         if (conf->checker_timeout) {
334                 c->timeout = conf->checker_timeout * 1000;
335                 condlog(3, "%s: checker timeout = %u ms (config file default)",
336                                 pp->dev, c->timeout);
337         }
338         else if (pp->udev && 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         if (pp->hwe && pp->hwe->getuid) {
353                 pp->getuid = pp->hwe->getuid;
354                 condlog(3, "%s: getuid = %s (controller setting)",
355                         pp->dev, pp->getuid);
356                 return 0;
357         }
358         if (conf->getuid) {
359                 pp->getuid = conf->getuid;
360                 condlog(3, "%s: getuid = %s (config file default)",
361                         pp->dev, pp->getuid);
362                 return 0;
363         }
364         pp->getuid = STRDUP(DEFAULT_GETUID);
365         condlog(3, "%s: getuid = %s (internal default)",
366                 pp->dev, pp->getuid);
367         return 0;
368 }
369
370 extern int
371 select_prio (struct path * pp)
372 {
373         struct mpentry * mpe;
374
375         if ((mpe = find_mpe(pp->wwid))) {
376                 if (mpe->prio_name) {
377                         pp->prio = prio_lookup(mpe->prio_name);
378                         prio_set_args(pp->prio, mpe->prio_args);
379                         condlog(3, "%s: prio = %s (LUN setting)",
380                                 pp->dev, pp->prio->name);
381                         return 0;
382                 }
383         }
384
385         if (pp->hwe && pp->hwe->prio_name) {
386                 pp->prio = prio_lookup(pp->hwe->prio_name);
387                 prio_set_args(pp->prio, pp->hwe->prio_args);
388                 condlog(3, "%s: prio = %s (controller setting)",
389                         pp->dev, pp->hwe->prio_name);
390                 condlog(3, "%s: prio args = %s (controller setting)",
391                         pp->dev, pp->hwe->prio_args);
392                 return 0;
393         }
394         if (conf->prio_name) {
395                 pp->prio = prio_lookup(conf->prio_name);
396                 prio_set_args(pp->prio, conf->prio_args);
397                 condlog(3, "%s: prio = %s (config file default)",
398                         pp->dev, conf->prio_name);
399                 condlog(3, "%s: prio args = %s (config file default)",
400                         pp->dev, conf->prio_args);
401                 return 0;
402         }
403         pp->prio = prio_lookup(DEFAULT_PRIO);
404         prio_set_args(pp->prio, DEFAULT_PRIO_ARGS);
405         condlog(3, "%s: prio = %s (internal default)",
406                 pp->dev, DEFAULT_PRIO);
407         condlog(3, "%s: prio = %s (internal default)",
408                 pp->dev, DEFAULT_PRIO_ARGS);
409         return 0;
410 }
411
412 extern int
413 select_no_path_retry(struct multipath *mp)
414 {
415         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS) {
416                 condlog(0, "flush_on_last_del in progress");
417                 mp->no_path_retry = NO_PATH_RETRY_FAIL;
418         }
419         if (mp->mpe && mp->mpe->no_path_retry != NO_PATH_RETRY_UNDEF) {
420                 mp->no_path_retry = mp->mpe->no_path_retry;
421                 condlog(3, "%s: no_path_retry = %i (multipath setting)",
422                         mp->alias, mp->no_path_retry);
423                 return 0;
424         }
425         if (mp->hwe && mp->hwe->no_path_retry != NO_PATH_RETRY_UNDEF) {
426                 mp->no_path_retry = mp->hwe->no_path_retry;
427                 condlog(3, "%s: no_path_retry = %i (controller setting)",
428                         mp->alias, mp->no_path_retry);
429                 return 0;
430         }
431         if (conf->no_path_retry != NO_PATH_RETRY_UNDEF) {
432                 mp->no_path_retry = conf->no_path_retry;
433                 condlog(3, "%s: no_path_retry = %i (config file default)",
434                         mp->alias, mp->no_path_retry);
435                 return 0;
436         }
437         if (mp->no_path_retry != NO_PATH_RETRY_UNDEF)
438                 condlog(3, "%s: no_path_retry = %i (inherited setting)",
439                         mp->alias, mp->no_path_retry);
440         else
441                 condlog(3, "%s: no_path_retry = %i (internal default)",
442                         mp->alias, mp->no_path_retry);
443         return 0;
444 }
445
446 int
447 select_minio_rq (struct multipath * mp)
448 {
449         if (mp->mpe && mp->mpe->minio_rq) {
450                 mp->minio = mp->mpe->minio_rq;
451                 condlog(3, "%s: minio = %i rq (LUN setting)",
452                         mp->alias, mp->minio);
453                 return 0;
454         }
455         if (mp->hwe && mp->hwe->minio_rq) {
456                 mp->minio = mp->hwe->minio_rq;
457                 condlog(3, "%s: minio = %i rq (controller setting)",
458                         mp->alias, mp->minio);
459                 return 0;
460         }
461         if (conf->minio) {
462                 mp->minio = conf->minio_rq;
463                 condlog(3, "%s: minio = %i rq (config file default)",
464                         mp->alias, mp->minio);
465                 return 0;
466         }
467         mp->minio = DEFAULT_MINIO_RQ;
468         condlog(3, "%s: minio = %i rq (internal default)",
469                 mp->alias, mp->minio);
470         return 0;
471 }
472
473 int
474 select_minio_bio (struct multipath * mp)
475 {
476         if (mp->mpe && mp->mpe->minio) {
477                 mp->minio = mp->mpe->minio;
478                 condlog(3, "%s: minio = %i (LUN setting)",
479                         mp->alias, mp->minio);
480                 return 0;
481         }
482         if (mp->hwe && mp->hwe->minio) {
483                 mp->minio = mp->hwe->minio;
484                 condlog(3, "%s: minio = %i (controller setting)",
485                         mp->alias, mp->minio);
486                 return 0;
487         }
488         if (conf->minio) {
489                 mp->minio = conf->minio;
490                 condlog(3, "%s: minio = %i (config file default)",
491                         mp->alias, mp->minio);
492                 return 0;
493         }
494         mp->minio = DEFAULT_MINIO;
495         condlog(3, "%s: minio = %i (internal default)",
496                 mp->alias, mp->minio);
497         return 0;
498 }
499
500 extern int
501 select_minio (struct multipath * mp)
502 {
503         if (conf->dmrq)
504                 return select_minio_rq(mp);
505         else
506                 return select_minio_bio(mp);
507 }
508
509 extern int
510 select_pg_timeout(struct multipath *mp)
511 {
512         if (mp->mpe && mp->mpe->pg_timeout != PGTIMEOUT_UNDEF) {
513                 mp->pg_timeout = mp->mpe->pg_timeout;
514                 if (mp->pg_timeout > 0)
515                         condlog(3, "%s: pg_timeout = %d (multipath setting)",
516                                 mp->alias, mp->pg_timeout);
517                 else
518                         condlog(3, "%s: pg_timeout = NONE (multipath setting)",
519                                 mp->alias);
520                 return 0;
521         }
522         if (mp->hwe && mp->hwe->pg_timeout != PGTIMEOUT_UNDEF) {
523                 mp->pg_timeout = mp->hwe->pg_timeout;
524                 if (mp->pg_timeout > 0)
525                         condlog(3, "%s: pg_timeout = %d (controller setting)",
526                                 mp->alias, mp->pg_timeout);
527                 else
528                         condlog(3, "%s: pg_timeout = NONE (controller setting)",
529                                 mp->alias);
530                 return 0;
531         }
532         if (conf->pg_timeout != PGTIMEOUT_UNDEF) {
533                 mp->pg_timeout = conf->pg_timeout;
534                 if (mp->pg_timeout > 0)
535                         condlog(3, "%s: pg_timeout = %d (config file default)",
536                                 mp->alias, mp->pg_timeout);
537                 else
538                         condlog(3,
539                                 "%s: pg_timeout = NONE (config file default)",
540                                 mp->alias);
541                 return 0;
542         }
543         mp->pg_timeout = PGTIMEOUT_UNDEF;
544         condlog(3, "%s: pg_timeout = NONE (internal default)", mp->alias);
545         return 0;
546 }
547
548 extern int
549 select_fast_io_fail(struct multipath *mp)
550 {
551         if (mp->hwe && mp->hwe->fast_io_fail) {
552                 mp->fast_io_fail = mp->hwe->fast_io_fail;
553                 if (mp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
554                         condlog(3, "%s: fast_io_fail_tmo = off (controller default)", mp->alias);
555                 else
556                         condlog(3, "%s: fast_io_fail_tmo = %d (controller default)", mp->alias,
557                                 mp->fast_io_fail == MP_FAST_IO_FAIL_ZERO ? 0 : mp->fast_io_fail);
558                 return 0;
559         }
560         if (conf->fast_io_fail) {
561                 mp->fast_io_fail = conf->fast_io_fail;
562                 if (mp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
563                         condlog(3, "%s: fast_io_fail_tmo = off (config file default)", mp->alias);
564                 else
565                         condlog(3, "%s: fast_io_fail_tmo = %d (config file default)", mp->alias,
566                                 mp->fast_io_fail == MP_FAST_IO_FAIL_ZERO ? 0 : mp->fast_io_fail);
567                 return 0;
568         }
569         mp->fast_io_fail = 0;
570         return 0;
571 }
572
573 extern int
574 select_dev_loss(struct multipath *mp)
575 {
576         if (mp->hwe && mp->hwe->dev_loss) {
577                 mp->dev_loss = mp->hwe->dev_loss;
578                 condlog(3, "%s: dev_loss_tmo = %u (controller default)",
579                         mp->alias, mp->dev_loss);
580                 return 0;
581         }
582         if (conf->dev_loss) {
583                 mp->dev_loss = conf->dev_loss;
584                 condlog(3, "%s: dev_loss_tmo = %u (config file default)",
585                         mp->alias, mp->dev_loss);
586                 return 0;
587         }
588         mp->dev_loss = 0;
589         return 0;
590 }
591
592 extern int
593 select_flush_on_last_del(struct multipath *mp)
594 {
595         if (mp->flush_on_last_del == FLUSH_IN_PROGRESS)
596                 return 0;
597         if (mp->mpe && mp->mpe->flush_on_last_del != FLUSH_UNDEF) {
598                 mp->flush_on_last_del = mp->mpe->flush_on_last_del;
599                 condlog(3, "flush_on_last_del = %i (multipath setting)",
600                                 mp->flush_on_last_del);
601                 return 0;
602         }
603         if (mp->hwe && mp->hwe->flush_on_last_del != FLUSH_UNDEF) {
604                 mp->flush_on_last_del = mp->hwe->flush_on_last_del;
605                 condlog(3, "flush_on_last_del = %i (controler setting)",
606                                 mp->flush_on_last_del);
607                 return 0;
608         }
609         if (conf->flush_on_last_del != FLUSH_UNDEF) {
610                 mp->flush_on_last_del = conf->flush_on_last_del;
611                 condlog(3, "flush_on_last_del = %i (config file default)",
612                                 mp->flush_on_last_del);
613                 return 0;
614         }
615         mp->flush_on_last_del = FLUSH_UNDEF;
616         condlog(3, "flush_on_last_del = DISABLED (internal default)");
617         return 0;
618 }
619
620 extern int
621 select_reservation_key (struct multipath * mp)
622 {
623         int j;
624         unsigned char *keyp;
625         uint64_t prkey = 0;
626
627         mp->reservation_key = NULL;
628
629         if (mp->mpe && mp->mpe->reservation_key) {
630                 keyp =  mp->mpe->reservation_key;
631                 for (j = 0; j < 8; ++j) {
632                         if (j > 0)
633                                 prkey <<= 8;
634                         prkey |= *keyp;
635                         ++keyp;
636                 }
637
638                 condlog(3, "%s: reservation_key = 0x%" PRIx64 " "
639                                 "(multipath setting)",  mp->alias, prkey);
640
641                 mp->reservation_key = mp->mpe->reservation_key;
642                 return 0;
643         }
644
645         if (conf->reservation_key) {
646                 keyp = conf->reservation_key;
647                 for (j = 0; j < 8; ++j) {
648                         if (j > 0)
649                                 prkey <<= 8;
650                         prkey |= *keyp;
651                         ++keyp;
652                 }
653
654                 condlog(3, "%s: reservation_key  = 0x%" PRIx64
655                                 " (config file default)", mp->alias, prkey);
656
657                 mp->reservation_key = conf->reservation_key;
658                 return 0;
659         }
660
661         return 0;
662 }
663