7ad9f6e261e775259989c8bb1945a1e5c43cc704
[platform/upstream/multipath-tools.git] / libmultipath / dict.c
1 /*
2  * Based on Alexandre Cassen template for keepalived
3  * Copyright (c) 2004, 2005, 2006  Christophe Varoqui
4  * Copyright (c) 2005 Benjamin Marzinski, Redhat
5  * Copyright (c) 2005 Kiyoshi Ueda, NEC
6  */
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <unistd.h>
10 #include <pwd.h>
11 #include <string.h>
12 #include "checkers.h"
13 #include "vector.h"
14 #include "hwtable.h"
15 #include "structs.h"
16 #include "parser.h"
17 #include "config.h"
18 #include "debug.h"
19 #include "pgpolicies.h"
20 #include "blacklist.h"
21 #include "defaults.h"
22 #include "prio.h"
23 #include "util.h"
24 #include <errno.h>
25 #include <inttypes.h>
26 #include <libudev.h>
27 #include <mpath_persist.h>
28 #include "mpath_cmd.h"
29 #include "dict.h"
30 #include "strbuf.h"
31
32 static void
33 do_set_int(vector strvec, void *ptr, int min, int max, const char *file,
34         int line_nr, char *buff)
35 {
36         int *int_ptr = (int *)ptr;
37         char *eptr;
38         long res;
39
40         res = strtol(buff, &eptr, 10);
41         if (eptr > buff)
42                 while (isspace(*eptr))
43                         eptr++;
44         if (*buff == '\0' || *eptr != '\0') {
45                 condlog(1, "%s line %d, invalid value for %s: \"%s\"",
46                         file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff);
47                 return;
48         }
49         if (res > max || res < min) {
50                 res = (res > max) ? max : min;
51                 condlog(1, "%s line %d, value for %s too %s, capping at %ld",
52                         file, line_nr, (char*)VECTOR_SLOT(strvec, 0),
53                 (res == max)? "large" : "small", res);
54         }
55         *int_ptr = res;
56         return;
57 }
58
59 static int
60 set_int(vector strvec, void *ptr, int min, int max, const char *file,
61         int line_nr)
62 {
63         char *buff;
64
65         buff = set_value(strvec);
66         if (!buff)
67                 return 1;
68
69         do_set_int(strvec, ptr, min, max, file, line_nr, buff);
70
71         free(buff);
72         return 0;
73 }
74
75 static int
76 set_uint(vector strvec, void *ptr, const char *file, int line_nr)
77 {
78         unsigned int *uint_ptr = (unsigned int *)ptr;
79         char *buff, *eptr, *p;
80         unsigned long res;
81
82         buff = set_value(strvec);
83         if (!buff)
84                 return 1;
85
86         p = buff;
87         while (isspace(*p))
88                 p++;
89         res = strtoul(p, &eptr, 10);
90         if (eptr > buff)
91                 while (isspace(*eptr))
92                         eptr++;
93         if (*buff == '\0' || *eptr != '\0' || !isdigit(*p) || res > UINT_MAX)
94                 condlog(1, "%s line %d, invalid value for %s: \"%s\"",
95                         file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff);
96         else
97                 *uint_ptr = res;
98
99         free(buff);
100         return 0;
101 }
102
103 static int
104 set_str(vector strvec, void *ptr, const char *file, int line_nr)
105 {
106         char **str_ptr = (char **)ptr;
107
108         if (*str_ptr)
109                 free(*str_ptr);
110         *str_ptr = set_value(strvec);
111
112         if (!*str_ptr)
113                 return 1;
114
115         return 0;
116 }
117
118 static int
119 set_dir(vector strvec, void *ptr, const char *file, int line_nr)
120 {
121         char **str_ptr = (char **)ptr;
122         char *old_str = *str_ptr;
123         struct stat sb;
124
125         *str_ptr = set_value(strvec);
126         if (!*str_ptr) {
127                 free(old_str);
128                 return 1;
129         }
130         if ((*str_ptr)[0] != '/'){
131                 condlog(1, "%s line %d, %s is not an absolute directory path. Ignoring", file, line_nr, *str_ptr);
132                 *str_ptr = old_str;
133         } else {
134                 if (stat(*str_ptr, &sb) == 0 && S_ISDIR(sb.st_mode))
135                         free(old_str);
136                 else {
137                         condlog(1, "%s line %d, %s is not an existing directory. Ignoring", file, line_nr, *str_ptr);
138                         *str_ptr = old_str;
139                 }
140         }
141         return 0;
142 }
143
144 static int
145 set_path(vector strvec, void *ptr, const char *file, int line_nr)
146 {
147         char **str_ptr = (char **)ptr;
148         char *old_str = *str_ptr;
149
150         *str_ptr = set_value(strvec);
151         if (!*str_ptr) {
152                 free(old_str);
153                 return 1;
154         }
155         if ((*str_ptr)[0] != '/'){
156                 condlog(1, "%s line %d, %s is not an absolute path. Ignoring",
157                         file, line_nr, *str_ptr);
158                 *str_ptr = old_str;
159         } else
160                 free(old_str);
161         return 0;
162 }
163
164 static int
165 set_str_noslash(vector strvec, void *ptr, const char *file, int line_nr)
166 {
167         char **str_ptr = (char **)ptr;
168         char *old_str = *str_ptr;
169
170         *str_ptr = set_value(strvec);
171         if (!*str_ptr) {
172                 free(old_str);
173                 return 1;
174         }
175         if (strchr(*str_ptr, '/')) {
176                 condlog(1, "%s line %d, %s cannot contain a slash. Ignoring",
177                         file, line_nr, *str_ptr);
178                 *str_ptr = old_str;
179         } else
180                 free(old_str);
181         return 0;
182 }
183
184 static int
185 set_yes_no(vector strvec, void *ptr, const char *file, int line_nr)
186 {
187         char * buff;
188         int *int_ptr = (int *)ptr;
189
190         buff = set_value(strvec);
191         if (!buff)
192                 return 1;
193
194         if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
195                 *int_ptr = YN_YES;
196         else if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
197                 *int_ptr = YN_NO;
198         else
199                 condlog(1, "%s line %d, invalid value for %s: \"%s\"",
200                         file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff);
201
202         free(buff);
203         return 0;
204 }
205
206 static int
207 set_yes_no_undef(vector strvec, void *ptr, const char *file, int line_nr)
208 {
209         char * buff;
210         int *int_ptr = (int *)ptr;
211
212         buff = set_value(strvec);
213         if (!buff)
214                 return 1;
215
216         if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
217                 *int_ptr = YNU_NO;
218         else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
219                 *int_ptr = YNU_YES;
220         else
221                 condlog(1, "%s line %d, invalid value for %s: \"%s\"",
222                         file, line_nr, (char*)VECTOR_SLOT(strvec, 0), buff);
223
224         free(buff);
225         return 0;
226 }
227
228 static int print_int(struct strbuf *buff, long v)
229 {
230         return print_strbuf(buff, "%li", v);
231 }
232
233 static int print_nonzero(struct strbuf *buff, long v)
234 {
235         if (!v)
236                 return 0;
237         return print_strbuf(buff, "%li", v);
238 }
239
240 static int print_str(struct strbuf *buff, const char *ptr)
241 {
242         int ret = append_strbuf_quoted(buff, ptr);
243
244         /*
245          * -EINVAL aka (ptr == NULL) means "not set".
246          * Returning an error here breaks unit tests
247          * (logic in snprint_keyword()).
248          */
249         return ret == -EINVAL ? 0 : ret;
250 }
251
252 static int print_ignored(struct strbuf *buff)
253 {
254         return append_strbuf_quoted(buff, "ignored");
255 }
256
257 static int print_yes_no(struct strbuf *buff, long v)
258 {
259         return append_strbuf_quoted(buff, v == YN_NO ? "no" : "yes");
260 }
261
262 static int print_yes_no_undef(struct strbuf *buff, long v)
263 {
264         if (!v)
265                 return 0;
266         return append_strbuf_quoted(buff, v == YNU_NO? "no" : "yes");
267 }
268
269 #define declare_def_handler(option, function)                           \
270 static int                                                              \
271 def_ ## option ## _handler (struct config *conf, vector strvec,         \
272                             const char *file, int line_nr)              \
273 {                                                                       \
274         return function (strvec, &conf->option, file, line_nr);         \
275 }
276
277 #define declare_def_warn_handler(option, function)                      \
278 static int                                                              \
279 def_ ## option ## _handler (struct config *conf, vector strvec,         \
280                             const char *file, int line_nr)              \
281 {                                                                       \
282         condlog(2, "%s line %d, \"" #option "\" is deprecated and will be disabled in a future release", file, line_nr);                                \
283         return function (strvec, &conf->option, file, line_nr);         \
284 }
285
286 #define declare_def_range_handler(option, minval, maxval)                       \
287 static int                                                              \
288 def_ ## option ## _handler (struct config *conf, vector strvec,         \
289                             const char *file, int line_nr)              \
290 {                                                                       \
291         return set_int(strvec, &conf->option, minval, maxval, file, line_nr); \
292 }
293
294 #define declare_def_snprint(option, function)                           \
295 static int                                                              \
296 snprint_def_ ## option (struct config *conf, struct strbuf *buff,       \
297                         const void *data)                               \
298 {                                                                       \
299         return function(buff, conf->option);                            \
300 }
301
302 #define declare_def_snprint_defint(option, function, value)             \
303 static int                                                              \
304 snprint_def_ ## option (struct config *conf, struct strbuf *buff,       \
305                         const void *data)                               \
306 {                                                                       \
307         int i = value;                                                  \
308         if (!conf->option)                                              \
309                 return function(buff, i);                               \
310         return function (buff, conf->option);                           \
311 }
312
313 #define declare_def_snprint_defstr(option, function, value)             \
314 static int                                                              \
315 snprint_def_ ## option (struct config *conf, struct strbuf *buff,       \
316                         const void *data)                               \
317 {                                                                       \
318         static const char *s = value;                                   \
319         if (!conf->option)                                              \
320                 return function(buff, s);                               \
321         return function(buff, conf->option);                            \
322 }
323
324 #define declare_hw_handler(option, function)                            \
325 static int                                                              \
326 hw_ ## option ## _handler (struct config *conf, vector strvec,          \
327                            const char *file, int line_nr)               \
328 {                                                                       \
329         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);         \
330         if (!hwe)                                                       \
331                 return 1;                                               \
332         return function (strvec, &hwe->option, file, line_nr);          \
333 }
334
335 #define declare_hw_range_handler(option, minval, maxval)                \
336 static int                                                              \
337 hw_ ## option ## _handler (struct config *conf, vector strvec,          \
338                            const char *file, int line_nr)               \
339 {                                                                       \
340         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);         \
341         if (!hwe)                                                       \
342                 return 1;                                               \
343         return set_int(strvec, &hwe->option, minval, maxval, file, line_nr); \
344 }
345
346
347 #define declare_hw_snprint(option, function)                            \
348 static int                                                              \
349 snprint_hw_ ## option (struct config *conf, struct strbuf *buff,        \
350                        const void *data)                                \
351 {                                                                       \
352         const struct hwentry * hwe = (const struct hwentry *)data;      \
353         return function(buff, hwe->option);                             \
354 }
355
356 #define declare_ovr_handler(option, function)                           \
357 static int                                                              \
358 ovr_ ## option ## _handler (struct config *conf, vector strvec,         \
359                             const char *file, int line_nr)              \
360 {                                                                       \
361         if (!conf->overrides)                                           \
362                 return 1;                                               \
363         return function (strvec, &conf->overrides->option, file, line_nr); \
364 }
365
366 #define declare_ovr_range_handler(option, minval, maxval)               \
367 static int                                                              \
368 ovr_ ## option ## _handler (struct config *conf, vector strvec,         \
369                             const char *file, int line_nr)              \
370 {                                                                       \
371         if (!conf->overrides)                                           \
372                 return 1;                                               \
373         return set_int(strvec, &conf->overrides->option, minval, maxval, \
374                        file, line_nr); \
375 }
376
377 #define declare_ovr_snprint(option, function)                           \
378 static int                                                              \
379 snprint_ovr_ ## option (struct config *conf, struct strbuf *buff,       \
380                         const void *data)                               \
381 {                                                                       \
382         return function (buff, conf->overrides->option);                \
383 }
384
385 #define declare_mp_handler(option, function)                            \
386 static int                                                              \
387 mp_ ## option ## _handler (struct config *conf, vector strvec,          \
388                            const char *file, int line_nr)               \
389 {                                                                       \
390         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);         \
391         if (!mpe)                                                       \
392                 return 1;                                               \
393         return function (strvec, &mpe->option, file, line_nr);          \
394 }
395
396 #define declare_mp_range_handler(option, minval, maxval)                \
397 static int                                                              \
398 mp_ ## option ## _handler (struct config *conf, vector strvec,          \
399                            const char *file, int line_nr)               \
400 {                                                                       \
401         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);         \
402         if (!mpe)                                                       \
403                 return 1;                                               \
404         return set_int(strvec, &mpe->option, minval, maxval, file, line_nr); \
405 }
406
407 #define declare_mp_snprint(option, function)                            \
408 static int                                                              \
409 snprint_mp_ ## option (struct config *conf, struct strbuf *buff,        \
410                        const void *data)                                \
411 {                                                                       \
412         const struct mpentry * mpe = (const struct mpentry *)data;      \
413         return function(buff, mpe->option);                             \
414 }
415
416 static int checkint_handler(struct config *conf, vector strvec,
417                             const char *file, int line_nr)
418 {
419         int rc = set_uint(strvec, &conf->checkint, file, line_nr);
420
421         if (rc)
422                 return rc;
423         if (conf->checkint == CHECKINT_UNDEF)
424                 conf->checkint--;
425         return 0;
426 }
427
428 declare_def_snprint(checkint, print_int)
429
430 declare_def_handler(max_checkint, set_uint)
431 declare_def_snprint(max_checkint, print_int)
432
433 declare_def_range_handler(verbosity, 0, MAX_VERBOSITY)
434 declare_def_snprint(verbosity, print_int)
435
436 declare_def_handler(reassign_maps, set_yes_no)
437 declare_def_snprint(reassign_maps, print_yes_no)
438
439 declare_def_warn_handler(multipath_dir, set_dir)
440 declare_def_snprint(multipath_dir, print_str)
441
442 static int def_partition_delim_handler(struct config *conf, vector strvec,
443                                        const char *file, int line_nr)
444 {
445         int rc = set_str_noslash(strvec, &conf->partition_delim, file, line_nr);
446
447         if (rc != 0)
448                 return rc;
449
450         if (!strcmp(conf->partition_delim, UNSET_PARTITION_DELIM)) {
451                 free(conf->partition_delim);
452                 conf->partition_delim = NULL;
453         }
454         return 0;
455 }
456
457 static int snprint_def_partition_delim(struct config *conf, struct strbuf *buff,
458                                        const void *data)
459 {
460         if (default_partition_delim == NULL || conf->partition_delim != NULL)
461                 return print_str(buff, conf->partition_delim);
462         else
463                 return print_str(buff, UNSET_PARTITION_DELIM);
464 }
465
466 static const char * const find_multipaths_optvals[] = {
467         [FIND_MULTIPATHS_OFF] = "off",
468         [FIND_MULTIPATHS_ON] = "on",
469         [FIND_MULTIPATHS_STRICT] = "strict",
470         [FIND_MULTIPATHS_GREEDY] = "greedy",
471         [FIND_MULTIPATHS_SMART] = "smart",
472 };
473
474 static int
475 def_find_multipaths_handler(struct config *conf, vector strvec,
476                             const char *file, int line_nr)
477 {
478         char *buff;
479         int i;
480
481         buff = set_value(strvec);
482         if (!buff)
483                 return 1;
484
485         for (i = FIND_MULTIPATHS_OFF; i < __FIND_MULTIPATHS_LAST; i++) {
486                 if (find_multipaths_optvals[i] != NULL &&
487                     !strcmp(buff, find_multipaths_optvals[i])) {
488                         conf->find_multipaths = i;
489                         break;
490                 }
491         }
492
493         if (i >= __FIND_MULTIPATHS_LAST) {
494                 if (strcmp(buff, "no") == 0 || strcmp(buff, "0") == 0)
495                         conf->find_multipaths = FIND_MULTIPATHS_OFF;
496                 else if (strcmp(buff, "yes") == 0 || strcmp(buff, "1") == 0)
497                         conf->find_multipaths = FIND_MULTIPATHS_ON;
498                 else
499                         condlog(1, "%s line %d, invalid value for find_multipaths: \"%s\"",
500                                 file, line_nr, buff);
501         }
502
503         free(buff);
504         return 0;
505 }
506
507 static int
508 snprint_def_find_multipaths(struct config *conf, struct strbuf *buff,
509                             const void *data)
510 {
511         return append_strbuf_quoted(buff,
512                          find_multipaths_optvals[conf->find_multipaths]);
513 }
514
515 declare_def_handler(selector, set_str)
516 declare_def_snprint_defstr(selector, print_str, DEFAULT_SELECTOR)
517 declare_hw_handler(selector, set_str)
518 declare_hw_snprint(selector, print_str)
519 declare_ovr_handler(selector, set_str)
520 declare_ovr_snprint(selector, print_str)
521 declare_mp_handler(selector, set_str)
522 declare_mp_snprint(selector, print_str)
523
524 static int snprint_uid_attrs(struct config *conf, struct strbuf *buff,
525                              const void *dummy)
526 {
527         int j, ret, total = 0;
528         const char *att;
529
530         vector_foreach_slot(&conf->uid_attrs, att, j) {
531                 ret = print_strbuf(buff, "%s%s", j == 0 ? "" : " ", att);
532                 if (ret < 0)
533                         return ret;
534                 total += ret;
535         }
536         return total;
537 }
538
539 static int uid_attrs_handler(struct config *conf, vector strvec,
540                              const char *file, int line_nr)
541 {
542         char *val;
543
544         vector_reset(&conf->uid_attrs);
545         val = set_value(strvec);
546         if (!val)
547                 return 1;
548         if (parse_uid_attrs(val, conf))
549                 condlog(1, "%s line %d,error parsing uid_attrs: \"%s\"", file,
550                         line_nr, val);
551         else
552                 condlog(4, "parsed %d uid_attrs", VECTOR_SIZE(&conf->uid_attrs));
553         free(val);
554         return 0;
555 }
556
557 declare_def_handler(uid_attribute, set_str)
558 declare_def_snprint_defstr(uid_attribute, print_str, DEFAULT_UID_ATTRIBUTE)
559 declare_ovr_handler(uid_attribute, set_str)
560 declare_ovr_snprint(uid_attribute, print_str)
561 declare_hw_handler(uid_attribute, set_str)
562 declare_hw_snprint(uid_attribute, print_str)
563
564 declare_def_handler(getuid, set_str)
565 declare_def_snprint(getuid, print_str)
566 declare_ovr_handler(getuid, set_str)
567 declare_ovr_snprint(getuid, print_str)
568 declare_hw_handler(getuid, set_str)
569 declare_hw_snprint(getuid, print_str)
570
571 declare_def_handler(prio_name, set_str)
572 declare_def_snprint_defstr(prio_name, print_str, DEFAULT_PRIO)
573 declare_ovr_handler(prio_name, set_str)
574 declare_ovr_snprint(prio_name, print_str)
575 declare_hw_handler(prio_name, set_str)
576 declare_hw_snprint(prio_name, print_str)
577 declare_mp_handler(prio_name, set_str)
578 declare_mp_snprint(prio_name, print_str)
579
580 declare_def_handler(alias_prefix, set_str_noslash)
581 declare_def_snprint_defstr(alias_prefix, print_str, DEFAULT_ALIAS_PREFIX)
582 declare_ovr_handler(alias_prefix, set_str_noslash)
583 declare_ovr_snprint(alias_prefix, print_str)
584 declare_hw_handler(alias_prefix, set_str_noslash)
585 declare_hw_snprint(alias_prefix, print_str)
586
587 declare_def_handler(prio_args, set_str)
588 declare_def_snprint_defstr(prio_args, print_str, DEFAULT_PRIO_ARGS)
589 declare_ovr_handler(prio_args, set_str)
590 declare_ovr_snprint(prio_args, print_str)
591 declare_hw_handler(prio_args, set_str)
592 declare_hw_snprint(prio_args, print_str)
593 declare_mp_handler(prio_args, set_str)
594 declare_mp_snprint(prio_args, print_str)
595
596 declare_def_handler(features, set_str)
597 declare_def_snprint_defstr(features, print_str, DEFAULT_FEATURES)
598 declare_ovr_handler(features, set_str)
599 declare_ovr_snprint(features, print_str)
600 declare_hw_handler(features, set_str)
601 declare_hw_snprint(features, print_str)
602 declare_mp_handler(features, set_str)
603 declare_mp_snprint(features, print_str)
604
605 declare_def_handler(checker_name, set_str)
606 declare_def_snprint_defstr(checker_name, print_str, DEFAULT_CHECKER)
607 declare_ovr_handler(checker_name, set_str)
608 declare_ovr_snprint(checker_name, print_str)
609 declare_hw_handler(checker_name, set_str)
610 declare_hw_snprint(checker_name, print_str)
611
612 declare_def_range_handler(minio, 0, INT_MAX)
613 declare_def_snprint_defint(minio, print_int, DEFAULT_MINIO)
614 declare_ovr_range_handler(minio, 0, INT_MAX)
615 declare_ovr_snprint(minio, print_nonzero)
616 declare_hw_range_handler(minio, 0, INT_MAX)
617 declare_hw_snprint(minio, print_nonzero)
618 declare_mp_range_handler(minio, 0, INT_MAX)
619 declare_mp_snprint(minio, print_nonzero)
620
621 declare_def_range_handler(minio_rq, 0, INT_MAX)
622 declare_def_snprint_defint(minio_rq, print_int, DEFAULT_MINIO_RQ)
623 declare_ovr_range_handler(minio_rq, 0, INT_MAX)
624 declare_ovr_snprint(minio_rq, print_nonzero)
625 declare_hw_range_handler(minio_rq, 0, INT_MAX)
626 declare_hw_snprint(minio_rq, print_nonzero)
627 declare_mp_range_handler(minio_rq, 0, INT_MAX)
628 declare_mp_snprint(minio_rq, print_nonzero)
629
630 declare_def_handler(queue_without_daemon, set_yes_no)
631 static int
632 snprint_def_queue_without_daemon(struct config *conf, struct strbuf *buff,
633                                  const void * data)
634 {
635         const char *qwd = "unknown";
636
637         switch (conf->queue_without_daemon) {
638         case QUE_NO_DAEMON_OFF:
639                 qwd = "no";
640                 break;
641         case QUE_NO_DAEMON_ON:
642                 qwd = "yes";
643                 break;
644         case QUE_NO_DAEMON_FORCE:
645                 qwd = "forced";
646                 break;
647         }
648         return append_strbuf_quoted(buff, qwd);
649 }
650
651 declare_def_range_handler(checker_timeout, 0, INT_MAX)
652 declare_def_snprint(checker_timeout, print_nonzero)
653
654 declare_def_handler(allow_usb_devices, set_yes_no)
655 declare_def_snprint(allow_usb_devices, print_yes_no)
656
657 declare_def_handler(flush_on_last_del, set_yes_no_undef)
658 declare_def_snprint_defint(flush_on_last_del, print_yes_no_undef, DEFAULT_FLUSH)
659 declare_ovr_handler(flush_on_last_del, set_yes_no_undef)
660 declare_ovr_snprint(flush_on_last_del, print_yes_no_undef)
661 declare_hw_handler(flush_on_last_del, set_yes_no_undef)
662 declare_hw_snprint(flush_on_last_del, print_yes_no_undef)
663 declare_mp_handler(flush_on_last_del, set_yes_no_undef)
664 declare_mp_snprint(flush_on_last_del, print_yes_no_undef)
665
666 declare_def_handler(user_friendly_names, set_yes_no_undef)
667 declare_def_snprint_defint(user_friendly_names, print_yes_no_undef,
668                            DEFAULT_USER_FRIENDLY_NAMES)
669 declare_ovr_handler(user_friendly_names, set_yes_no_undef)
670 declare_ovr_snprint(user_friendly_names, print_yes_no_undef)
671 declare_hw_handler(user_friendly_names, set_yes_no_undef)
672 declare_hw_snprint(user_friendly_names, print_yes_no_undef)
673 declare_mp_handler(user_friendly_names, set_yes_no_undef)
674 declare_mp_snprint(user_friendly_names, print_yes_no_undef)
675
676 declare_def_warn_handler(bindings_file, set_path)
677 declare_def_snprint(bindings_file, print_str)
678
679 declare_def_warn_handler(wwids_file, set_path)
680 declare_def_snprint(wwids_file, print_str)
681
682 declare_def_warn_handler(prkeys_file, set_path)
683 declare_def_snprint(prkeys_file, print_str)
684
685 declare_def_handler(retain_hwhandler, set_yes_no_undef)
686 declare_def_snprint_defint(retain_hwhandler, print_yes_no_undef,
687                            DEFAULT_RETAIN_HWHANDLER)
688 declare_ovr_handler(retain_hwhandler, set_yes_no_undef)
689 declare_ovr_snprint(retain_hwhandler, print_yes_no_undef)
690 declare_hw_handler(retain_hwhandler, set_yes_no_undef)
691 declare_hw_snprint(retain_hwhandler, print_yes_no_undef)
692
693 declare_def_handler(detect_prio, set_yes_no_undef)
694 declare_def_snprint_defint(detect_prio, print_yes_no_undef,
695                            DEFAULT_DETECT_PRIO)
696 declare_ovr_handler(detect_prio, set_yes_no_undef)
697 declare_ovr_snprint(detect_prio, print_yes_no_undef)
698 declare_hw_handler(detect_prio, set_yes_no_undef)
699 declare_hw_snprint(detect_prio, print_yes_no_undef)
700
701 declare_def_handler(detect_checker, set_yes_no_undef)
702 declare_def_snprint_defint(detect_checker, print_yes_no_undef,
703                            DEFAULT_DETECT_CHECKER)
704 declare_ovr_handler(detect_checker, set_yes_no_undef)
705 declare_ovr_snprint(detect_checker, print_yes_no_undef)
706 declare_hw_handler(detect_checker, set_yes_no_undef)
707 declare_hw_snprint(detect_checker, print_yes_no_undef)
708
709 declare_def_handler(force_sync, set_yes_no)
710 declare_def_snprint(force_sync, print_yes_no)
711
712 declare_def_handler(deferred_remove, set_yes_no_undef)
713 declare_def_snprint_defint(deferred_remove, print_yes_no_undef,
714                            DEFAULT_DEFERRED_REMOVE)
715 declare_ovr_handler(deferred_remove, set_yes_no_undef)
716 declare_ovr_snprint(deferred_remove, print_yes_no_undef)
717 declare_hw_handler(deferred_remove, set_yes_no_undef)
718 declare_hw_snprint(deferred_remove, print_yes_no_undef)
719 declare_mp_handler(deferred_remove, set_yes_no_undef)
720 declare_mp_snprint(deferred_remove, print_yes_no_undef)
721
722 declare_def_range_handler(retrigger_tries, 0, INT_MAX)
723 declare_def_snprint(retrigger_tries, print_int)
724
725 declare_def_range_handler(retrigger_delay, 0, INT_MAX)
726 declare_def_snprint(retrigger_delay, print_int)
727
728 declare_def_range_handler(uev_wait_timeout, 0, INT_MAX)
729 declare_def_snprint(uev_wait_timeout, print_int)
730
731 declare_def_handler(strict_timing, set_yes_no)
732 declare_def_snprint(strict_timing, print_yes_no)
733
734 declare_def_handler(skip_kpartx, set_yes_no_undef)
735 declare_def_snprint_defint(skip_kpartx, print_yes_no_undef,
736                            DEFAULT_SKIP_KPARTX)
737 declare_ovr_handler(skip_kpartx, set_yes_no_undef)
738 declare_ovr_snprint(skip_kpartx, print_yes_no_undef)
739 declare_hw_handler(skip_kpartx, set_yes_no_undef)
740 declare_hw_snprint(skip_kpartx, print_yes_no_undef)
741 declare_mp_handler(skip_kpartx, set_yes_no_undef)
742 declare_mp_snprint(skip_kpartx, print_yes_no_undef)
743 static int def_disable_changed_wwids_handler(struct config *conf, vector strvec,
744                                              const char *file, int line_nr)
745 {
746         return 0;
747 }
748 static int snprint_def_disable_changed_wwids(struct config *conf,
749                                              struct strbuf *buff,
750                                              const void *data)
751 {
752         return print_ignored(buff);
753 }
754
755 declare_def_range_handler(remove_retries, 0, INT_MAX)
756 declare_def_snprint(remove_retries, print_int)
757
758 declare_def_range_handler(max_sectors_kb, 0, INT_MAX)
759 declare_def_snprint(max_sectors_kb, print_nonzero)
760 declare_ovr_range_handler(max_sectors_kb, 0, INT_MAX)
761 declare_ovr_snprint(max_sectors_kb, print_nonzero)
762 declare_hw_range_handler(max_sectors_kb, 0, INT_MAX)
763 declare_hw_snprint(max_sectors_kb, print_nonzero)
764 declare_mp_range_handler(max_sectors_kb, 0, INT_MAX)
765 declare_mp_snprint(max_sectors_kb, print_nonzero)
766
767 declare_def_range_handler(find_multipaths_timeout, INT_MIN, INT_MAX)
768 declare_def_snprint_defint(find_multipaths_timeout, print_int,
769                            DEFAULT_FIND_MULTIPATHS_TIMEOUT)
770
771 declare_def_handler(enable_foreign, set_str)
772 declare_def_snprint_defstr(enable_foreign, print_str,
773                            DEFAULT_ENABLE_FOREIGN)
774
775 static int
776 def_config_dir_handler(struct config *conf, vector strvec, const char *file,
777                        int line_nr)
778 {
779         /* this is only valid in the main config file */
780         if (conf->processed_main_config) {
781                 condlog(1, "%s line %d, config_dir option only valid in /etc/multipath.conf",
782                         file, line_nr);
783                 return 0;
784         }
785         condlog(2, "%s line %d, \"config_dir\" is deprecated and will be disabled in a future release",
786                 file, line_nr);
787         return set_path(strvec, &conf->config_dir, file, line_nr);
788 }
789 declare_def_snprint(config_dir, print_str)
790
791 #define declare_def_attr_handler(option, function)                      \
792 static int                                                              \
793 def_ ## option ## _handler (struct config *conf, vector strvec,         \
794                             const char *file, int line_nr)              \
795 {                                                                       \
796         return function (strvec, &conf->option, &conf->attribute_flags, \
797                          file, line_nr);                                \
798 }
799
800 #define declare_def_attr_snprint(option, function)                      \
801 static int                                                              \
802 snprint_def_ ## option (struct config *conf, struct strbuf *buff,       \
803                         const void *data)                               \
804 {                                                                       \
805         return function(buff, conf->option, conf->attribute_flags);     \
806 }
807
808 #define declare_mp_attr_handler(option, function)                       \
809 static int                                                              \
810 mp_ ## option ## _handler (struct config *conf, vector strvec,          \
811                            const char *file, int line_nr)               \
812 {                                                                       \
813         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);         \
814         if (!mpe)                                                       \
815                 return 1;                                               \
816         return function (strvec, &mpe->option, &mpe->attribute_flags,   \
817                          file, line_nr);                                \
818 }
819
820 #define declare_mp_attr_snprint(option, function)                       \
821 static int                                                              \
822 snprint_mp_ ## option (struct config *conf, struct strbuf *buff,        \
823                        const void * data)                               \
824 {                                                                       \
825         const struct mpentry * mpe = (const struct mpentry *)data;      \
826         return function(buff, mpe->option, mpe->attribute_flags);       \
827 }
828
829 static int
830 set_mode(vector strvec, void *ptr, int *flags, const char *file, int line_nr)
831 {
832         mode_t mode;
833         mode_t *mode_ptr = (mode_t *)ptr;
834         char *buff;
835
836         buff = set_value(strvec);
837
838         if (!buff)
839                 return 1;
840
841         if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
842                 *flags |= (1 << ATTR_MODE);
843                 *mode_ptr = mode;
844         } else
845                 condlog(1, "%s line %d, invalid value for mode: \"%s\"",
846                         file, line_nr, buff);
847
848         free(buff);
849         return 0;
850 }
851
852 static int
853 set_uid(vector strvec, void *ptr, int *flags, const char *file, int line_nr)
854 {
855         uid_t uid;
856         uid_t *uid_ptr = (uid_t *)ptr;
857         char *buff;
858         char passwd_buf[1024];
859         struct passwd info, *found;
860
861         buff = set_value(strvec);
862         if (!buff)
863                 return 1;
864         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
865                 *flags |= (1 << ATTR_UID);
866                 *uid_ptr = info.pw_uid;
867         }
868         else if (sscanf(buff, "%u", &uid) == 1){
869                 *flags |= (1 << ATTR_UID);
870                 *uid_ptr = uid;
871         } else
872                 condlog(1, "%s line %d, invalid value for uid: \"%s\"",
873                         file, line_nr, buff);
874
875         free(buff);
876         return 0;
877 }
878
879 static int
880 set_gid(vector strvec, void *ptr, int *flags, const char *file, int line_nr)
881 {
882         gid_t gid;
883         gid_t *gid_ptr = (gid_t *)ptr;
884         char *buff;
885         char passwd_buf[1024];
886         struct passwd info, *found;
887
888         buff = set_value(strvec);
889         if (!buff)
890                 return 1;
891
892         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
893                 *flags |= (1 << ATTR_GID);
894                 *gid_ptr = info.pw_gid;
895         }
896         else if (sscanf(buff, "%u", &gid) == 1){
897                 *flags |= (1 << ATTR_GID);
898                 *gid_ptr = gid;
899         } else
900                 condlog(1, "%s line %d, invalid value for gid: \"%s\"",
901                         file, line_nr, buff);
902         free(buff);
903         return 0;
904 }
905
906 static int
907 print_mode(struct strbuf *buff, long v, int flags)
908 {
909         mode_t mode = (mode_t)v;
910         if ((flags & (1 << ATTR_MODE)) == 0)
911                 return 0;
912         return print_strbuf(buff, "0%o", mode);
913 }
914
915 static int
916 print_uid(struct strbuf *buff, long v, int flags)
917 {
918         uid_t uid = (uid_t)v;
919         if ((flags & (1 << ATTR_UID)) == 0)
920                 return 0;
921         return print_strbuf(buff, "0%o", uid);
922 }
923
924 static int
925 print_gid(struct strbuf *buff, long v, int flags)
926 {
927         gid_t gid = (gid_t)v;
928         if ((flags & (1 << ATTR_GID)) == 0)
929                 return 0;
930         return print_strbuf(buff, "0%o", gid);
931 }
932
933 declare_def_attr_handler(mode, set_mode)
934 declare_def_attr_snprint(mode, print_mode)
935 declare_mp_attr_handler(mode, set_mode)
936 declare_mp_attr_snprint(mode, print_mode)
937
938 declare_def_attr_handler(uid, set_uid)
939 declare_def_attr_snprint(uid, print_uid)
940 declare_mp_attr_handler(uid, set_uid)
941 declare_mp_attr_snprint(uid, print_uid)
942
943 declare_def_attr_handler(gid, set_gid)
944 declare_def_attr_snprint(gid, print_gid)
945 declare_mp_attr_handler(gid, set_gid)
946 declare_mp_attr_snprint(gid, print_gid)
947
948 static int
949 set_undef_off_zero(vector strvec, void *ptr, const char *file, int line_nr)
950 {
951         char * buff;
952         int *int_ptr = (int *)ptr;
953
954         buff = set_value(strvec);
955         if (!buff)
956                 return 1;
957
958         if (strcmp(buff, "off") == 0)
959                 *int_ptr = UOZ_OFF;
960         else if (strcmp(buff, "0") == 0)
961                 *int_ptr = UOZ_ZERO;
962         else
963                 do_set_int(strvec, int_ptr, 1, INT_MAX, file, line_nr, buff);
964
965         free(buff);
966         return 0;
967 }
968
969 int print_undef_off_zero(struct strbuf *buff, long v)
970 {
971         if (v == UOZ_UNDEF)
972                 return 0;
973         if (v == UOZ_OFF)
974                 return append_strbuf_str(buff, "off");
975         if (v == UOZ_ZERO)
976                 return append_strbuf_str(buff, "0");
977         return print_int(buff, v);
978 }
979
980 declare_def_handler(fast_io_fail, set_undef_off_zero)
981 declare_def_snprint_defint(fast_io_fail, print_undef_off_zero,
982                            DEFAULT_FAST_IO_FAIL)
983 declare_ovr_handler(fast_io_fail, set_undef_off_zero)
984 declare_ovr_snprint(fast_io_fail, print_undef_off_zero)
985 declare_hw_handler(fast_io_fail, set_undef_off_zero)
986 declare_hw_snprint(fast_io_fail, print_undef_off_zero)
987
988 static int
989 set_dev_loss(vector strvec, void *ptr, const char *file, int line_nr)
990 {
991         char * buff;
992         unsigned int *uint_ptr = (unsigned int *)ptr;
993
994         buff = set_value(strvec);
995         if (!buff)
996                 return 1;
997
998         if (!strcmp(buff, "infinity"))
999                 *uint_ptr = MAX_DEV_LOSS_TMO;
1000         else if (sscanf(buff, "%u", uint_ptr) != 1)
1001                 condlog(1, "%s line %d, invalid value for dev_loss_tmo: \"%s\"",
1002                         file, line_nr, buff);
1003
1004         free(buff);
1005         return 0;
1006 }
1007
1008 int
1009 print_dev_loss(struct strbuf *buff, unsigned long v)
1010 {
1011         if (v == DEV_LOSS_TMO_UNSET)
1012                 return 0;
1013         if (v >= MAX_DEV_LOSS_TMO)
1014                 return append_strbuf_quoted(buff, "infinity");
1015         return print_strbuf(buff, "%lu", v);
1016 }
1017
1018 declare_def_handler(dev_loss, set_dev_loss)
1019 declare_def_snprint(dev_loss, print_dev_loss)
1020 declare_ovr_handler(dev_loss, set_dev_loss)
1021 declare_ovr_snprint(dev_loss, print_dev_loss)
1022 declare_hw_handler(dev_loss, set_dev_loss)
1023 declare_hw_snprint(dev_loss, print_dev_loss)
1024
1025 declare_def_handler(eh_deadline, set_undef_off_zero)
1026 declare_def_snprint(eh_deadline, print_undef_off_zero)
1027 declare_ovr_handler(eh_deadline, set_undef_off_zero)
1028 declare_ovr_snprint(eh_deadline, print_undef_off_zero)
1029 declare_hw_handler(eh_deadline, set_undef_off_zero)
1030 declare_hw_snprint(eh_deadline, print_undef_off_zero)
1031
1032 static int
1033 set_pgpolicy(vector strvec, void *ptr, const char *file, int line_nr)
1034 {
1035         char * buff;
1036         int policy;
1037         int *int_ptr = (int *)ptr;
1038
1039         buff = set_value(strvec);
1040         if (!buff)
1041                 return 1;
1042
1043         policy = get_pgpolicy_id(buff);
1044         if (policy != IOPOLICY_UNDEF)
1045                 *int_ptr = policy;
1046         else
1047                 condlog(1, "%s line %d, invalid value for path_grouping_policy: \"%s\"",
1048                         file, line_nr, buff);
1049         free(buff);
1050
1051         return 0;
1052 }
1053
1054 int
1055 print_pgpolicy(struct strbuf *buff, long pgpolicy)
1056 {
1057         char str[POLICY_NAME_SIZE];
1058
1059         if (!pgpolicy)
1060                 return 0;
1061
1062         get_pgpolicy_name(str, POLICY_NAME_SIZE, pgpolicy);
1063
1064         return append_strbuf_quoted(buff, str);
1065 }
1066
1067 declare_def_handler(pgpolicy, set_pgpolicy)
1068 declare_def_snprint_defint(pgpolicy, print_pgpolicy, DEFAULT_PGPOLICY)
1069 declare_ovr_handler(pgpolicy, set_pgpolicy)
1070 declare_ovr_snprint(pgpolicy, print_pgpolicy)
1071 declare_hw_handler(pgpolicy, set_pgpolicy)
1072 declare_hw_snprint(pgpolicy, print_pgpolicy)
1073 declare_mp_handler(pgpolicy, set_pgpolicy)
1074 declare_mp_snprint(pgpolicy, print_pgpolicy)
1075
1076 int
1077 get_sys_max_fds(int *max_fds)
1078 {
1079         FILE *file;
1080         int nr_open;
1081         int ret = 1;
1082
1083         file = fopen("/proc/sys/fs/nr_open", "r");
1084         if (!file) {
1085                 fprintf(stderr, "Cannot open /proc/sys/fs/nr_open : %s\n",
1086                         strerror(errno));
1087                 return 1;
1088         }
1089         if (fscanf(file, "%d", &nr_open) != 1) {
1090                 fprintf(stderr, "Cannot read max open fds from /proc/sys/fs/nr_open");
1091                 if (ferror(file))
1092                         fprintf(stderr, " : %s\n", strerror(errno));
1093                 else
1094                         fprintf(stderr, "\n");
1095         } else {
1096                 *max_fds = nr_open;
1097                 ret = 0;
1098         }
1099         fclose(file);
1100         return ret;
1101 }
1102
1103
1104 static int
1105 max_fds_handler(struct config *conf, vector strvec, const char *file,
1106                 int line_nr)
1107 {
1108         char * buff;
1109         int max_fds;
1110
1111         buff = set_value(strvec);
1112
1113         if (!buff)
1114                 return 1;
1115
1116         if (get_sys_max_fds(&max_fds) != 0)
1117                 max_fds = 4096;  /* Assume safe limit */
1118         if (!strcmp(buff, "max"))
1119                 conf->max_fds = max_fds;
1120         else
1121                 do_set_int(strvec, &conf->max_fds, 0, max_fds, file, line_nr,
1122                            buff);
1123
1124         free(buff);
1125
1126         return 0;
1127 }
1128
1129 static int
1130 snprint_max_fds (struct config *conf, struct strbuf *buff, const void *data)
1131 {
1132         int r = 0, max_fds;
1133
1134         if (!conf->max_fds)
1135                 return 0;
1136
1137         r = get_sys_max_fds(&max_fds);
1138         if (!r && conf->max_fds >= max_fds)
1139                 return append_strbuf_quoted(buff, "max");
1140         else
1141                 return print_int(buff, conf->max_fds);
1142 }
1143
1144 static int
1145 set_rr_weight(vector strvec, void *ptr, const char *file, int line_nr)
1146 {
1147         int *int_ptr = (int *)ptr;
1148         char * buff;
1149
1150         buff = set_value(strvec);
1151
1152         if (!buff)
1153                 return 1;
1154
1155         if (!strcmp(buff, "priorities"))
1156                 *int_ptr = RR_WEIGHT_PRIO;
1157         else if (!strcmp(buff, "uniform"))
1158                 *int_ptr = RR_WEIGHT_NONE;
1159         else
1160                 condlog(1, "%s line %d, invalid value for rr_weight: \"%s\"",
1161                         file, line_nr, buff);
1162         free(buff);
1163
1164         return 0;
1165 }
1166
1167 int
1168 print_rr_weight (struct strbuf *buff, long v)
1169 {
1170         if (!v)
1171                 return 0;
1172         if (v == RR_WEIGHT_PRIO)
1173                 return append_strbuf_quoted(buff, "priorities");
1174         if (v == RR_WEIGHT_NONE)
1175                 return append_strbuf_quoted(buff, "uniform");
1176
1177         return 0;
1178 }
1179
1180 declare_def_handler(rr_weight, set_rr_weight)
1181 declare_def_snprint_defint(rr_weight, print_rr_weight, DEFAULT_RR_WEIGHT)
1182 declare_ovr_handler(rr_weight, set_rr_weight)
1183 declare_ovr_snprint(rr_weight, print_rr_weight)
1184 declare_hw_handler(rr_weight, set_rr_weight)
1185 declare_hw_snprint(rr_weight, print_rr_weight)
1186 declare_mp_handler(rr_weight, set_rr_weight)
1187 declare_mp_snprint(rr_weight, print_rr_weight)
1188
1189 static int
1190 set_pgfailback(vector strvec, void *ptr, const char *file, int line_nr)
1191 {
1192         int *int_ptr = (int *)ptr;
1193         char * buff;
1194
1195         buff = set_value(strvec);
1196         if (!buff)
1197                 return 1;
1198
1199         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
1200                 *int_ptr = -FAILBACK_MANUAL;
1201         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
1202                 *int_ptr = -FAILBACK_IMMEDIATE;
1203         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
1204                 *int_ptr = -FAILBACK_FOLLOWOVER;
1205         else
1206                 do_set_int(strvec, ptr, 0, INT_MAX, file, line_nr, buff);
1207
1208         free(buff);
1209
1210         return 0;
1211 }
1212
1213 int
1214 print_pgfailback (struct strbuf *buff, long v)
1215 {
1216         switch(v) {
1217         case  FAILBACK_UNDEF:
1218                 return 0;
1219         case -FAILBACK_MANUAL:
1220                 return append_strbuf_quoted(buff, "manual");
1221         case -FAILBACK_IMMEDIATE:
1222                 return append_strbuf_quoted(buff, "immediate");
1223         case -FAILBACK_FOLLOWOVER:
1224                 return append_strbuf_quoted(buff, "followover");
1225         default:
1226                 return print_int(buff, v);
1227         }
1228 }
1229
1230 declare_def_handler(pgfailback, set_pgfailback)
1231 declare_def_snprint_defint(pgfailback, print_pgfailback, DEFAULT_FAILBACK)
1232 declare_ovr_handler(pgfailback, set_pgfailback)
1233 declare_ovr_snprint(pgfailback, print_pgfailback)
1234 declare_hw_handler(pgfailback, set_pgfailback)
1235 declare_hw_snprint(pgfailback, print_pgfailback)
1236 declare_mp_handler(pgfailback, set_pgfailback)
1237 declare_mp_snprint(pgfailback, print_pgfailback)
1238
1239 static int
1240 no_path_retry_helper(vector strvec, void *ptr, const char *file, int line_nr)
1241 {
1242         int *int_ptr = (int *)ptr;
1243         char * buff;
1244
1245         buff = set_value(strvec);
1246         if (!buff)
1247                 return 1;
1248
1249         if (!strcmp(buff, "fail") || !strcmp(buff, "0"))
1250                 *int_ptr = NO_PATH_RETRY_FAIL;
1251         else if (!strcmp(buff, "queue"))
1252                 *int_ptr = NO_PATH_RETRY_QUEUE;
1253         else
1254                 do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff);
1255
1256         free(buff);
1257         return 0;
1258 }
1259
1260 int
1261 print_no_path_retry(struct strbuf *buff, long v)
1262 {
1263         switch(v) {
1264         case NO_PATH_RETRY_UNDEF:
1265                 return 0;
1266         case NO_PATH_RETRY_FAIL:
1267                 return append_strbuf_quoted(buff, "fail");
1268         case NO_PATH_RETRY_QUEUE:
1269                 return append_strbuf_quoted(buff, "queue");
1270         default:
1271                 return print_int(buff, v);
1272         }
1273 }
1274
1275 declare_def_handler(no_path_retry, no_path_retry_helper)
1276 declare_def_snprint(no_path_retry, print_no_path_retry)
1277 declare_ovr_handler(no_path_retry, no_path_retry_helper)
1278 declare_ovr_snprint(no_path_retry, print_no_path_retry)
1279 declare_hw_handler(no_path_retry, no_path_retry_helper)
1280 declare_hw_snprint(no_path_retry, print_no_path_retry)
1281 declare_mp_handler(no_path_retry, no_path_retry_helper)
1282 declare_mp_snprint(no_path_retry, print_no_path_retry)
1283
1284 static int
1285 def_log_checker_err_handler(struct config *conf, vector strvec,
1286                             const char *file, int line_nr)
1287 {
1288         char * buff;
1289
1290         buff = set_value(strvec);
1291
1292         if (!buff)
1293                 return 1;
1294
1295         if (!strcmp(buff, "once"))
1296                 conf->log_checker_err = LOG_CHKR_ERR_ONCE;
1297         else if (!strcmp(buff, "always"))
1298                 conf->log_checker_err = LOG_CHKR_ERR_ALWAYS;
1299         else
1300                 condlog(1, "%s line %d, invalid value for log_checker_err: \"%s\"",
1301                         file, line_nr, buff);
1302
1303         free(buff);
1304         return 0;
1305 }
1306
1307 static int
1308 snprint_def_log_checker_err(struct config *conf, struct strbuf *buff,
1309                             const void * data)
1310 {
1311         if (conf->log_checker_err == LOG_CHKR_ERR_ONCE)
1312                 return append_strbuf_quoted(buff, "once");
1313         return append_strbuf_quoted(buff, "always");
1314 }
1315
1316 static int
1317 set_reservation_key(vector strvec, struct be64 *be64_ptr, uint8_t *flags_ptr,
1318                     int *source_ptr)
1319 {
1320         char *buff;
1321         uint64_t prkey;
1322         uint8_t sa_flags;
1323
1324         buff = set_value(strvec);
1325         if (!buff)
1326                 return 1;
1327
1328         if (strcmp(buff, "file") == 0) {
1329                 *source_ptr = PRKEY_SOURCE_FILE;
1330                 *flags_ptr = 0;
1331                 put_be64(*be64_ptr, 0);
1332                 free(buff);
1333                 return 0;
1334         }
1335
1336         if (parse_prkey_flags(buff, &prkey, &sa_flags) != 0) {
1337                 free(buff);
1338                 return 1;
1339         }
1340         *source_ptr = PRKEY_SOURCE_CONF;
1341         *flags_ptr = sa_flags;
1342         put_be64(*be64_ptr, prkey);
1343         free(buff);
1344         return 0;
1345 }
1346
1347 int
1348 print_reservation_key(struct strbuf *buff,
1349                       struct be64 key, uint8_t flags, int source)
1350 {
1351         char *flagstr = "";
1352         if (source == PRKEY_SOURCE_NONE)
1353                 return 0;
1354         if (source == PRKEY_SOURCE_FILE)
1355                 return append_strbuf_quoted(buff, "file");
1356         if (flags & MPATH_F_APTPL_MASK)
1357                 flagstr = ":aptpl";
1358         return print_strbuf(buff, "0x%" PRIx64 "%s", get_be64(key), flagstr);
1359 }
1360
1361 static int
1362 def_reservation_key_handler(struct config *conf, vector strvec,
1363                             const char *file, int line_nr)
1364 {
1365         return set_reservation_key(strvec, &conf->reservation_key,
1366                                    &conf->sa_flags,
1367                                    &conf->prkey_source);
1368 }
1369
1370 static int
1371 snprint_def_reservation_key (struct config *conf, struct strbuf *buff,
1372                              const void * data)
1373 {
1374         return print_reservation_key(buff, conf->reservation_key,
1375                                      conf->sa_flags, conf->prkey_source);
1376 }
1377
1378 static int
1379 mp_reservation_key_handler(struct config *conf, vector strvec, const char *file,
1380                            int line_nr)
1381 {
1382         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1383         if (!mpe)
1384                 return 1;
1385         return set_reservation_key(strvec, &mpe->reservation_key,
1386                                    &mpe->sa_flags,
1387                                    &mpe->prkey_source);
1388 }
1389
1390 static int
1391 snprint_mp_reservation_key (struct config *conf, struct strbuf *buff,
1392                             const void *data)
1393 {
1394         const struct mpentry * mpe = (const struct mpentry *)data;
1395         return print_reservation_key(buff, mpe->reservation_key,
1396                                      mpe->sa_flags, mpe->prkey_source);
1397 }
1398
1399 static int
1400 set_off_int_undef(vector strvec, void *ptr, const char *file, int line_nr)
1401 {
1402         int *int_ptr = (int *)ptr;
1403         char * buff;
1404
1405         buff = set_value(strvec);
1406         if (!buff)
1407                 return 1;
1408
1409         if (!strcmp(buff, "no") || !strcmp(buff, "0"))
1410                 *int_ptr = NU_NO;
1411         else
1412                 do_set_int(strvec, ptr, 1, INT_MAX, file, line_nr, buff);
1413
1414         free(buff);
1415         return 0;
1416 }
1417
1418 int
1419 print_off_int_undef(struct strbuf *buff, long v)
1420 {
1421         switch(v) {
1422         case NU_UNDEF:
1423                 return 0;
1424         case NU_NO:
1425                 return append_strbuf_quoted(buff, "no");
1426         default:
1427                 return print_int(buff, v);
1428         }
1429 }
1430
1431 declare_def_handler(delay_watch_checks, set_off_int_undef)
1432 declare_def_snprint_defint(delay_watch_checks, print_off_int_undef,
1433                            DEFAULT_DELAY_CHECKS)
1434 declare_ovr_handler(delay_watch_checks, set_off_int_undef)
1435 declare_ovr_snprint(delay_watch_checks, print_off_int_undef)
1436 declare_hw_handler(delay_watch_checks, set_off_int_undef)
1437 declare_hw_snprint(delay_watch_checks, print_off_int_undef)
1438 declare_mp_handler(delay_watch_checks, set_off_int_undef)
1439 declare_mp_snprint(delay_watch_checks, print_off_int_undef)
1440 declare_def_handler(delay_wait_checks, set_off_int_undef)
1441 declare_def_snprint_defint(delay_wait_checks, print_off_int_undef,
1442                            DEFAULT_DELAY_CHECKS)
1443 declare_ovr_handler(delay_wait_checks, set_off_int_undef)
1444 declare_ovr_snprint(delay_wait_checks, print_off_int_undef)
1445 declare_hw_handler(delay_wait_checks, set_off_int_undef)
1446 declare_hw_snprint(delay_wait_checks, print_off_int_undef)
1447 declare_mp_handler(delay_wait_checks, set_off_int_undef)
1448 declare_mp_snprint(delay_wait_checks, print_off_int_undef)
1449 declare_def_handler(san_path_err_threshold, set_off_int_undef)
1450 declare_def_snprint_defint(san_path_err_threshold, print_off_int_undef,
1451                            DEFAULT_ERR_CHECKS)
1452 declare_ovr_handler(san_path_err_threshold, set_off_int_undef)
1453 declare_ovr_snprint(san_path_err_threshold, print_off_int_undef)
1454 declare_hw_handler(san_path_err_threshold, set_off_int_undef)
1455 declare_hw_snprint(san_path_err_threshold, print_off_int_undef)
1456 declare_mp_handler(san_path_err_threshold, set_off_int_undef)
1457 declare_mp_snprint(san_path_err_threshold, print_off_int_undef)
1458 declare_def_handler(san_path_err_forget_rate, set_off_int_undef)
1459 declare_def_snprint_defint(san_path_err_forget_rate, print_off_int_undef,
1460                            DEFAULT_ERR_CHECKS)
1461 declare_ovr_handler(san_path_err_forget_rate, set_off_int_undef)
1462 declare_ovr_snprint(san_path_err_forget_rate, print_off_int_undef)
1463 declare_hw_handler(san_path_err_forget_rate, set_off_int_undef)
1464 declare_hw_snprint(san_path_err_forget_rate, print_off_int_undef)
1465 declare_mp_handler(san_path_err_forget_rate, set_off_int_undef)
1466 declare_mp_snprint(san_path_err_forget_rate, print_off_int_undef)
1467 declare_def_handler(san_path_err_recovery_time, set_off_int_undef)
1468 declare_def_snprint_defint(san_path_err_recovery_time, print_off_int_undef,
1469                            DEFAULT_ERR_CHECKS)
1470 declare_ovr_handler(san_path_err_recovery_time, set_off_int_undef)
1471 declare_ovr_snprint(san_path_err_recovery_time, print_off_int_undef)
1472 declare_hw_handler(san_path_err_recovery_time, set_off_int_undef)
1473 declare_hw_snprint(san_path_err_recovery_time, print_off_int_undef)
1474 declare_mp_handler(san_path_err_recovery_time, set_off_int_undef)
1475 declare_mp_snprint(san_path_err_recovery_time, print_off_int_undef)
1476 declare_def_handler(marginal_path_err_sample_time, set_off_int_undef)
1477 declare_def_snprint_defint(marginal_path_err_sample_time, print_off_int_undef,
1478                            DEFAULT_ERR_CHECKS)
1479 declare_ovr_handler(marginal_path_err_sample_time, set_off_int_undef)
1480 declare_ovr_snprint(marginal_path_err_sample_time, print_off_int_undef)
1481 declare_hw_handler(marginal_path_err_sample_time, set_off_int_undef)
1482 declare_hw_snprint(marginal_path_err_sample_time, print_off_int_undef)
1483 declare_mp_handler(marginal_path_err_sample_time, set_off_int_undef)
1484 declare_mp_snprint(marginal_path_err_sample_time, print_off_int_undef)
1485 declare_def_handler(marginal_path_err_rate_threshold, set_off_int_undef)
1486 declare_def_snprint_defint(marginal_path_err_rate_threshold, print_off_int_undef,
1487                            DEFAULT_ERR_CHECKS)
1488 declare_ovr_handler(marginal_path_err_rate_threshold, set_off_int_undef)
1489 declare_ovr_snprint(marginal_path_err_rate_threshold, print_off_int_undef)
1490 declare_hw_handler(marginal_path_err_rate_threshold, set_off_int_undef)
1491 declare_hw_snprint(marginal_path_err_rate_threshold, print_off_int_undef)
1492 declare_mp_handler(marginal_path_err_rate_threshold, set_off_int_undef)
1493 declare_mp_snprint(marginal_path_err_rate_threshold, print_off_int_undef)
1494 declare_def_handler(marginal_path_err_recheck_gap_time, set_off_int_undef)
1495 declare_def_snprint_defint(marginal_path_err_recheck_gap_time, print_off_int_undef,
1496                            DEFAULT_ERR_CHECKS)
1497 declare_ovr_handler(marginal_path_err_recheck_gap_time, set_off_int_undef)
1498 declare_ovr_snprint(marginal_path_err_recheck_gap_time, print_off_int_undef)
1499 declare_hw_handler(marginal_path_err_recheck_gap_time, set_off_int_undef)
1500 declare_hw_snprint(marginal_path_err_recheck_gap_time, print_off_int_undef)
1501 declare_mp_handler(marginal_path_err_recheck_gap_time, set_off_int_undef)
1502 declare_mp_snprint(marginal_path_err_recheck_gap_time, print_off_int_undef)
1503 declare_def_handler(marginal_path_double_failed_time, set_off_int_undef)
1504 declare_def_snprint_defint(marginal_path_double_failed_time, print_off_int_undef,
1505                            DEFAULT_ERR_CHECKS)
1506 declare_ovr_handler(marginal_path_double_failed_time, set_off_int_undef)
1507 declare_ovr_snprint(marginal_path_double_failed_time, print_off_int_undef)
1508 declare_hw_handler(marginal_path_double_failed_time, set_off_int_undef)
1509 declare_hw_snprint(marginal_path_double_failed_time, print_off_int_undef)
1510 declare_mp_handler(marginal_path_double_failed_time, set_off_int_undef)
1511 declare_mp_snprint(marginal_path_double_failed_time, print_off_int_undef)
1512
1513 declare_def_handler(ghost_delay, set_off_int_undef)
1514 declare_def_snprint(ghost_delay, print_off_int_undef)
1515 declare_ovr_handler(ghost_delay, set_off_int_undef)
1516 declare_ovr_snprint(ghost_delay, print_off_int_undef)
1517 declare_hw_handler(ghost_delay, set_off_int_undef)
1518 declare_hw_snprint(ghost_delay, print_off_int_undef)
1519 declare_mp_handler(ghost_delay, set_off_int_undef)
1520 declare_mp_snprint(ghost_delay, print_off_int_undef)
1521
1522 declare_def_handler(all_tg_pt, set_yes_no_undef)
1523 declare_def_snprint_defint(all_tg_pt, print_yes_no_undef, DEFAULT_ALL_TG_PT)
1524 declare_ovr_handler(all_tg_pt, set_yes_no_undef)
1525 declare_ovr_snprint(all_tg_pt, print_yes_no_undef)
1526 declare_hw_handler(all_tg_pt, set_yes_no_undef)
1527 declare_hw_snprint(all_tg_pt, print_yes_no_undef)
1528
1529 declare_def_handler(marginal_pathgroups, set_yes_no)
1530 declare_def_snprint(marginal_pathgroups, print_yes_no)
1531
1532 declare_def_handler(recheck_wwid, set_yes_no_undef)
1533 declare_def_snprint_defint(recheck_wwid, print_yes_no_undef, DEFAULT_RECHECK_WWID)
1534 declare_ovr_handler(recheck_wwid, set_yes_no_undef)
1535 declare_ovr_snprint(recheck_wwid, print_yes_no_undef)
1536 declare_hw_handler(recheck_wwid, set_yes_no_undef)
1537 declare_hw_snprint(recheck_wwid, print_yes_no_undef)
1538
1539 declare_def_range_handler(uxsock_timeout, DEFAULT_REPLY_TIMEOUT, INT_MAX)
1540
1541 static int
1542 hw_vpd_vendor_handler(struct config *conf, vector strvec, const char *file,
1543                       int line_nr)
1544 {
1545         int i;
1546         char *buff;
1547
1548         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1549         if (!hwe)
1550                 return 1;
1551
1552         buff = set_value(strvec);
1553         if (!buff)
1554                 return 1;
1555         for (i = 0; i < VPD_VP_ARRAY_SIZE; i++) {
1556                 if (strcmp(buff, vpd_vendor_pages[i].name) == 0) {
1557                         hwe->vpd_vendor_id = i;
1558                         goto out;
1559                 }
1560         }
1561         condlog(1, "%s line %d, invalid value for vpd_vendor: \"%s\"",
1562                 file, line_nr, buff);
1563 out:
1564         free(buff);
1565         return 0;
1566 }
1567
1568 static int
1569 snprint_hw_vpd_vendor(struct config *conf, struct strbuf *buff,
1570                       const void * data)
1571 {
1572         const struct hwentry * hwe = (const struct hwentry *)data;
1573
1574         if (hwe->vpd_vendor_id > 0 && hwe->vpd_vendor_id < VPD_VP_ARRAY_SIZE)
1575                 return append_strbuf_quoted(buff,
1576                                 vpd_vendor_pages[hwe->vpd_vendor_id].name);
1577         return 0;
1578 }
1579
1580 /*
1581  * blacklist block handlers
1582  */
1583 static int
1584 blacklist_handler(struct config *conf, vector strvec, const char*file,
1585                   int line_nr)
1586 {
1587         if (!conf->blist_devnode)
1588                 conf->blist_devnode = vector_alloc();
1589         if (!conf->blist_wwid)
1590                 conf->blist_wwid = vector_alloc();
1591         if (!conf->blist_device)
1592                 conf->blist_device = vector_alloc();
1593         if (!conf->blist_property)
1594                 conf->blist_property = vector_alloc();
1595         if (!conf->blist_protocol)
1596                 conf->blist_protocol = vector_alloc();
1597
1598         if (!conf->blist_devnode || !conf->blist_wwid ||
1599             !conf->blist_device || !conf->blist_property ||
1600             !conf->blist_protocol)
1601                 return 1;
1602
1603         return 0;
1604 }
1605
1606 static int
1607 blacklist_exceptions_handler(struct config *conf, vector strvec,
1608                              const char *file, int line_nr)
1609 {
1610         if (!conf->elist_devnode)
1611                 conf->elist_devnode = vector_alloc();
1612         if (!conf->elist_wwid)
1613                 conf->elist_wwid = vector_alloc();
1614         if (!conf->elist_device)
1615                 conf->elist_device = vector_alloc();
1616         if (!conf->elist_property)
1617                 conf->elist_property = vector_alloc();
1618         if (!conf->elist_protocol)
1619                 conf->elist_protocol = vector_alloc();
1620
1621         if (!conf->elist_devnode || !conf->elist_wwid ||
1622             !conf->elist_device || !conf->elist_property ||
1623             !conf->elist_protocol)
1624                 return 1;
1625
1626         return 0;
1627 }
1628
1629 #define declare_ble_handler(option)                                     \
1630 static int                                                              \
1631 ble_ ## option ## _handler (struct config *conf, vector strvec,         \
1632                             const char *file, int line_nr)              \
1633 {                                                                       \
1634         char *buff;                                                     \
1635         int rc;                                                         \
1636                                                                         \
1637         if (!conf->option)                                              \
1638                 return 1;                                               \
1639                                                                         \
1640         buff = set_value(strvec);                                       \
1641         if (!buff)                                                      \
1642                 return 1;                                               \
1643                                                                         \
1644         rc = store_ble(conf->option, buff, ORIGIN_CONFIG);              \
1645         free(buff);                                                     \
1646         return rc;                                                      \
1647 }
1648
1649 #define declare_ble_device_handler(name, option, vend, prod)            \
1650 static int                                                              \
1651 ble_ ## option ## _ ## name ## _handler (struct config *conf, vector strvec, \
1652                                          const char *file, int line_nr) \
1653 {                                                                       \
1654         char * buff;                                                    \
1655         int rc;                                                         \
1656                                                                         \
1657         if (!conf->option)                                              \
1658                 return 1;                                               \
1659                                                                         \
1660         buff = set_value(strvec);                                       \
1661         if (!buff)                                                      \
1662                 return 1;                                               \
1663                                                                         \
1664         rc = set_ble_device(conf->option, vend, prod, ORIGIN_CONFIG);   \
1665         free(buff);                                                     \
1666         return rc;                                                      \
1667 }
1668
1669 declare_ble_handler(blist_devnode)
1670 declare_ble_handler(elist_devnode)
1671 declare_ble_handler(blist_wwid)
1672 declare_ble_handler(elist_wwid)
1673 declare_ble_handler(blist_property)
1674 declare_ble_handler(elist_property)
1675 declare_ble_handler(blist_protocol)
1676 declare_ble_handler(elist_protocol)
1677
1678 static int
1679 snprint_def_uxsock_timeout(struct config *conf, struct strbuf *buff,
1680                            const void *data)
1681 {
1682         return print_strbuf(buff, "%u", conf->uxsock_timeout);
1683 }
1684
1685 static int
1686 snprint_ble_simple (struct config *conf, struct strbuf *buff, const void *data)
1687 {
1688         const struct blentry *ble = (const struct blentry *)data;
1689
1690         return print_str(buff, ble->str);
1691 }
1692
1693 static int
1694 ble_device_handler(struct config *conf, vector strvec, const char *file,
1695                    int line_nr)
1696 {
1697         return alloc_ble_device(conf->blist_device);
1698 }
1699
1700 static int
1701 ble_except_device_handler(struct config *conf, vector strvec, const char *file,
1702                           int line_nr)
1703 {
1704         return alloc_ble_device(conf->elist_device);
1705 }
1706
1707 declare_ble_device_handler(vendor, blist_device, buff, NULL)
1708 declare_ble_device_handler(vendor, elist_device, buff, NULL)
1709 declare_ble_device_handler(product, blist_device, NULL, buff)
1710 declare_ble_device_handler(product, elist_device, NULL, buff)
1711
1712 static int snprint_bled_vendor(struct config *conf, struct strbuf *buff,
1713                                const void * data)
1714 {
1715         const struct blentry_device * bled =
1716                 (const struct blentry_device *)data;
1717
1718         return print_str(buff, bled->vendor);
1719 }
1720
1721 static int snprint_bled_product(struct config *conf, struct strbuf *buff,
1722                                 const void *data)
1723 {
1724         const struct blentry_device * bled =
1725                 (const struct blentry_device *)data;
1726
1727         return print_str(buff, bled->product);
1728 }
1729
1730 /*
1731  * devices block handlers
1732  */
1733 static int
1734 devices_handler(struct config *conf, vector strvec, const char *file,
1735                 int line_nr)
1736 {
1737         if (!conf->hwtable)
1738                 conf->hwtable = vector_alloc();
1739
1740         if (!conf->hwtable)
1741                 return 1;
1742
1743         return 0;
1744 }
1745
1746 static int
1747 device_handler(struct config *conf, vector strvec, const char *file,
1748                int line_nr)
1749 {
1750         struct hwentry * hwe;
1751
1752         hwe = alloc_hwe();
1753
1754         if (!hwe)
1755                 return 1;
1756
1757         if (!vector_alloc_slot(conf->hwtable)) {
1758                 free_hwe(hwe);
1759                 return 1;
1760         }
1761         vector_set_slot(conf->hwtable, hwe);
1762
1763         return 0;
1764 }
1765
1766 declare_hw_handler(vendor, set_str)
1767 declare_hw_snprint(vendor, print_str)
1768
1769 declare_hw_handler(product, set_str)
1770 declare_hw_snprint(product, print_str)
1771
1772 declare_hw_handler(revision, set_str)
1773 declare_hw_snprint(revision, print_str)
1774
1775 declare_hw_handler(bl_product, set_str)
1776 declare_hw_snprint(bl_product, print_str)
1777
1778 declare_hw_handler(hwhandler, set_str)
1779 declare_hw_snprint(hwhandler, print_str)
1780
1781 /*
1782  * overrides handlers
1783  */
1784 static int
1785 overrides_handler(struct config *conf, vector strvec, const char *file,
1786                   int line_nr)
1787 {
1788         if (!conf->overrides)
1789                 conf->overrides = alloc_hwe();
1790
1791         if (!conf->overrides)
1792                 return 1;
1793
1794         return 0;
1795 }
1796
1797
1798
1799 /*
1800  * multipaths block handlers
1801  */
1802 static int
1803 multipaths_handler(struct config *conf, vector strvec, const char *file,
1804                    int line_nr)
1805 {
1806         if (!conf->mptable)
1807                 conf->mptable = vector_alloc();
1808
1809         if (!conf->mptable)
1810                 return 1;
1811
1812         return 0;
1813 }
1814
1815 static int
1816 multipath_handler(struct config *conf, vector strvec, const char *file,
1817                   int line_nr)
1818 {
1819         struct mpentry * mpe;
1820
1821         mpe = alloc_mpe();
1822
1823         if (!mpe)
1824                 return 1;
1825
1826         if (!vector_alloc_slot(conf->mptable)) {
1827                 free_mpe(mpe);
1828                 return 1;
1829         }
1830         vector_set_slot(conf->mptable, mpe);
1831
1832         return 0;
1833 }
1834
1835 declare_mp_handler(wwid, set_str)
1836 declare_mp_snprint(wwid, print_str)
1837
1838 declare_mp_handler(alias, set_str_noslash)
1839 declare_mp_snprint(alias, print_str)
1840
1841 /*
1842  * deprecated handlers
1843  */
1844
1845 static int
1846 deprecated_handler(struct config *conf, vector strvec, const char *file,
1847                    int line_nr)
1848 {
1849         char * buff;
1850
1851         buff = set_value(strvec);
1852
1853         if (!buff)
1854                 return 1;
1855
1856         free(buff);
1857         return 0;
1858 }
1859
1860 static int
1861 snprint_deprecated (struct config *conf, struct strbuf *buff, const void * data)
1862 {
1863         return 0;
1864 }
1865
1866 #define __deprecated
1867
1868 /*
1869  * If you add or remove a keyword also update multipath/multipath.conf.5
1870  */
1871 void
1872 init_keywords(vector keywords)
1873 {
1874         install_keyword_root("defaults", NULL);
1875         install_keyword("verbosity", &def_verbosity_handler, &snprint_def_verbosity);
1876         install_keyword("polling_interval", &checkint_handler, &snprint_def_checkint);
1877         install_keyword("max_polling_interval", &def_max_checkint_handler, &snprint_def_max_checkint);
1878         install_keyword("reassign_maps", &def_reassign_maps_handler, &snprint_def_reassign_maps);
1879         install_keyword("multipath_dir", &def_multipath_dir_handler, &snprint_def_multipath_dir);
1880         install_keyword("path_selector", &def_selector_handler, &snprint_def_selector);
1881         install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_pgpolicy);
1882         install_keyword("uid_attrs", &uid_attrs_handler, &snprint_uid_attrs);
1883         install_keyword("uid_attribute", &def_uid_attribute_handler, &snprint_def_uid_attribute);
1884         install_keyword("getuid_callout", &def_getuid_handler, &snprint_def_getuid);
1885         install_keyword("prio", &def_prio_name_handler, &snprint_def_prio_name);
1886         install_keyword("prio_args", &def_prio_args_handler, &snprint_def_prio_args);
1887         install_keyword("features", &def_features_handler, &snprint_def_features);
1888         install_keyword("path_checker", &def_checker_name_handler, &snprint_def_checker_name);
1889         install_keyword("checker", &def_checker_name_handler, NULL);
1890         install_keyword("alias_prefix", &def_alias_prefix_handler, &snprint_def_alias_prefix);
1891         install_keyword("failback", &def_pgfailback_handler, &snprint_def_pgfailback);
1892         install_keyword("rr_min_io", &def_minio_handler, &snprint_def_minio);
1893         install_keyword("rr_min_io_rq", &def_minio_rq_handler, &snprint_def_minio_rq);
1894         install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
1895         install_keyword("rr_weight", &def_rr_weight_handler, &snprint_def_rr_weight);
1896         install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
1897         install_keyword("queue_without_daemon", &def_queue_without_daemon_handler, &snprint_def_queue_without_daemon);
1898         install_keyword("checker_timeout", &def_checker_timeout_handler, &snprint_def_checker_timeout);
1899         install_keyword("allow_usb_devices", &def_allow_usb_devices_handler, &snprint_def_allow_usb_devices);
1900         install_keyword("pg_timeout", &deprecated_handler, &snprint_deprecated);
1901         install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
1902         install_keyword("user_friendly_names", &def_user_friendly_names_handler, &snprint_def_user_friendly_names);
1903         install_keyword("mode", &def_mode_handler, &snprint_def_mode);
1904         install_keyword("uid", &def_uid_handler, &snprint_def_uid);
1905         install_keyword("gid", &def_gid_handler, &snprint_def_gid);
1906         install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
1907         install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
1908         install_keyword("eh_deadline", &def_eh_deadline_handler, &snprint_def_eh_deadline);
1909         install_keyword("bindings_file", &def_bindings_file_handler, &snprint_def_bindings_file);
1910         install_keyword("wwids_file", &def_wwids_file_handler, &snprint_def_wwids_file);
1911         install_keyword("prkeys_file", &def_prkeys_file_handler, &snprint_def_prkeys_file);
1912         install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
1913         install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
1914         install_keyword("all_tg_pt", &def_all_tg_pt_handler, &snprint_def_all_tg_pt);
1915         install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler);
1916         install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
1917         install_keyword("detect_checker", &def_detect_checker_handler, &snprint_def_detect_checker);
1918         install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
1919         install_keyword("strict_timing", &def_strict_timing_handler, &snprint_def_strict_timing);
1920         install_keyword("deferred_remove", &def_deferred_remove_handler, &snprint_def_deferred_remove);
1921         install_keyword("partition_delimiter", &def_partition_delim_handler, &snprint_def_partition_delim);
1922         install_keyword("config_dir", &def_config_dir_handler, &snprint_def_config_dir);
1923         install_keyword("delay_watch_checks", &def_delay_watch_checks_handler, &snprint_def_delay_watch_checks);
1924         install_keyword("delay_wait_checks", &def_delay_wait_checks_handler, &snprint_def_delay_wait_checks);
1925         install_keyword("san_path_err_threshold", &def_san_path_err_threshold_handler, &snprint_def_san_path_err_threshold);
1926         install_keyword("san_path_err_forget_rate", &def_san_path_err_forget_rate_handler, &snprint_def_san_path_err_forget_rate);
1927         install_keyword("san_path_err_recovery_time", &def_san_path_err_recovery_time_handler, &snprint_def_san_path_err_recovery_time);
1928         install_keyword("marginal_path_err_sample_time", &def_marginal_path_err_sample_time_handler, &snprint_def_marginal_path_err_sample_time);
1929         install_keyword("marginal_path_err_rate_threshold", &def_marginal_path_err_rate_threshold_handler, &snprint_def_marginal_path_err_rate_threshold);
1930         install_keyword("marginal_path_err_recheck_gap_time", &def_marginal_path_err_recheck_gap_time_handler, &snprint_def_marginal_path_err_recheck_gap_time);
1931         install_keyword("marginal_path_double_failed_time", &def_marginal_path_double_failed_time_handler, &snprint_def_marginal_path_double_failed_time);
1932
1933         install_keyword("find_multipaths", &def_find_multipaths_handler, &snprint_def_find_multipaths);
1934         install_keyword("uxsock_timeout", &def_uxsock_timeout_handler, &snprint_def_uxsock_timeout);
1935         install_keyword("retrigger_tries", &def_retrigger_tries_handler, &snprint_def_retrigger_tries);
1936         install_keyword("retrigger_delay", &def_retrigger_delay_handler, &snprint_def_retrigger_delay);
1937         install_keyword("missing_uev_wait_timeout", &def_uev_wait_timeout_handler, &snprint_def_uev_wait_timeout);
1938         install_keyword("skip_kpartx", &def_skip_kpartx_handler, &snprint_def_skip_kpartx);
1939         install_keyword("disable_changed_wwids", &def_disable_changed_wwids_handler, &snprint_def_disable_changed_wwids);
1940         install_keyword("remove_retries", &def_remove_retries_handler, &snprint_def_remove_retries);
1941         install_keyword("max_sectors_kb", &def_max_sectors_kb_handler, &snprint_def_max_sectors_kb);
1942         install_keyword("ghost_delay", &def_ghost_delay_handler, &snprint_def_ghost_delay);
1943         install_keyword("find_multipaths_timeout",
1944                         &def_find_multipaths_timeout_handler,
1945                         &snprint_def_find_multipaths_timeout);
1946         install_keyword("enable_foreign", &def_enable_foreign_handler,
1947                         &snprint_def_enable_foreign);
1948         install_keyword("marginal_pathgroups", &def_marginal_pathgroups_handler, &snprint_def_marginal_pathgroups);
1949         install_keyword("recheck_wwid", &def_recheck_wwid_handler, &snprint_def_recheck_wwid);
1950         __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
1951         __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
1952         __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
1953         __deprecated install_keyword("default_getuid_callout", &def_getuid_handler, NULL);
1954         __deprecated install_keyword("default_features", &def_features_handler, NULL);
1955         __deprecated install_keyword("default_path_checker", &def_checker_name_handler, NULL);
1956
1957         install_keyword_root("blacklist", &blacklist_handler);
1958         install_keyword_multi("devnode", &ble_blist_devnode_handler, &snprint_ble_simple);
1959         install_keyword_multi("wwid", &ble_blist_wwid_handler, &snprint_ble_simple);
1960         install_keyword_multi("property", &ble_blist_property_handler, &snprint_ble_simple);
1961         install_keyword_multi("protocol", &ble_blist_protocol_handler, &snprint_ble_simple);
1962         install_keyword_multi("device", &ble_device_handler, NULL);
1963         install_sublevel();
1964         install_keyword("vendor", &ble_blist_device_vendor_handler, &snprint_bled_vendor);
1965         install_keyword("product", &ble_blist_device_product_handler, &snprint_bled_product);
1966         install_sublevel_end();
1967         install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
1968         install_keyword_multi("devnode", &ble_elist_devnode_handler, &snprint_ble_simple);
1969         install_keyword_multi("wwid", &ble_elist_wwid_handler, &snprint_ble_simple);
1970         install_keyword_multi("property", &ble_elist_property_handler, &snprint_ble_simple);
1971         install_keyword_multi("protocol", &ble_elist_protocol_handler, &snprint_ble_simple);
1972         install_keyword_multi("device", &ble_except_device_handler, NULL);
1973         install_sublevel();
1974         install_keyword("vendor", &ble_elist_device_vendor_handler, &snprint_bled_vendor);
1975         install_keyword("product", &ble_elist_device_product_handler, &snprint_bled_product);
1976         install_sublevel_end();
1977
1978 #if 0
1979         __deprecated install_keyword_root("devnode_blacklist", &blacklist_handler);
1980         __deprecated install_keyword("devnode", &ble_devnode_handler, &snprint_ble_simple);
1981         __deprecated install_keyword("wwid", &ble_wwid_handler, &snprint_ble_simple);
1982         __deprecated install_keyword("device", &ble_device_handler, NULL);
1983         __deprecated install_sublevel();
1984         __deprecated install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
1985         __deprecated install_keyword("product", &ble_product_handler, &snprint_bled_product);
1986         __deprecated install_sublevel_end();
1987 #endif
1988 /*
1989  * If you add or remove a "device subsection" keyword also update
1990  * multipath/multipath.conf.5 and the TEMPLATE in libmultipath/hwtable.c
1991  */
1992         install_keyword_root("devices", &devices_handler);
1993         install_keyword_multi("device", &device_handler, NULL);
1994         install_sublevel();
1995         install_keyword("vendor", &hw_vendor_handler, &snprint_hw_vendor);
1996         install_keyword("product", &hw_product_handler, &snprint_hw_product);
1997         install_keyword("revision", &hw_revision_handler, &snprint_hw_revision);
1998         install_keyword("product_blacklist", &hw_bl_product_handler, &snprint_hw_bl_product);
1999         install_keyword("path_grouping_policy", &hw_pgpolicy_handler, &snprint_hw_pgpolicy);
2000         install_keyword("uid_attribute", &hw_uid_attribute_handler, &snprint_hw_uid_attribute);
2001         install_keyword("getuid_callout", &hw_getuid_handler, &snprint_hw_getuid);
2002         install_keyword("path_selector", &hw_selector_handler, &snprint_hw_selector);
2003         install_keyword("path_checker", &hw_checker_name_handler, &snprint_hw_checker_name);
2004         install_keyword("checker", &hw_checker_name_handler, NULL);
2005         install_keyword("alias_prefix", &hw_alias_prefix_handler, &snprint_hw_alias_prefix);
2006         install_keyword("features", &hw_features_handler, &snprint_hw_features);
2007         install_keyword("hardware_handler", &hw_hwhandler_handler, &snprint_hw_hwhandler);
2008         install_keyword("prio", &hw_prio_name_handler, &snprint_hw_prio_name);
2009         install_keyword("prio_args", &hw_prio_args_handler, &snprint_hw_prio_args);
2010         install_keyword("failback", &hw_pgfailback_handler, &snprint_hw_pgfailback);
2011         install_keyword("rr_weight", &hw_rr_weight_handler, &snprint_hw_rr_weight);
2012         install_keyword("no_path_retry", &hw_no_path_retry_handler, &snprint_hw_no_path_retry);
2013         install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_minio);
2014         install_keyword("rr_min_io_rq", &hw_minio_rq_handler, &snprint_hw_minio_rq);
2015         install_keyword("pg_timeout", &deprecated_handler, &snprint_deprecated);
2016         install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
2017         install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
2018         install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
2019         install_keyword("eh_deadline", &hw_eh_deadline_handler, &snprint_hw_eh_deadline);
2020         install_keyword("user_friendly_names", &hw_user_friendly_names_handler, &snprint_hw_user_friendly_names);
2021         install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler);
2022         install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_hw_detect_prio);
2023         install_keyword("detect_checker", &hw_detect_checker_handler, &snprint_hw_detect_checker);
2024         install_keyword("deferred_remove", &hw_deferred_remove_handler, &snprint_hw_deferred_remove);
2025         install_keyword("delay_watch_checks", &hw_delay_watch_checks_handler, &snprint_hw_delay_watch_checks);
2026         install_keyword("delay_wait_checks", &hw_delay_wait_checks_handler, &snprint_hw_delay_wait_checks);
2027         install_keyword("san_path_err_threshold", &hw_san_path_err_threshold_handler, &snprint_hw_san_path_err_threshold);
2028         install_keyword("san_path_err_forget_rate", &hw_san_path_err_forget_rate_handler, &snprint_hw_san_path_err_forget_rate);
2029         install_keyword("san_path_err_recovery_time", &hw_san_path_err_recovery_time_handler, &snprint_hw_san_path_err_recovery_time);
2030         install_keyword("marginal_path_err_sample_time", &hw_marginal_path_err_sample_time_handler, &snprint_hw_marginal_path_err_sample_time);
2031         install_keyword("marginal_path_err_rate_threshold", &hw_marginal_path_err_rate_threshold_handler, &snprint_hw_marginal_path_err_rate_threshold);
2032         install_keyword("marginal_path_err_recheck_gap_time", &hw_marginal_path_err_recheck_gap_time_handler, &snprint_hw_marginal_path_err_recheck_gap_time);
2033         install_keyword("marginal_path_double_failed_time", &hw_marginal_path_double_failed_time_handler, &snprint_hw_marginal_path_double_failed_time);
2034         install_keyword("skip_kpartx", &hw_skip_kpartx_handler, &snprint_hw_skip_kpartx);
2035         install_keyword("max_sectors_kb", &hw_max_sectors_kb_handler, &snprint_hw_max_sectors_kb);
2036         install_keyword("ghost_delay", &hw_ghost_delay_handler, &snprint_hw_ghost_delay);
2037         install_keyword("all_tg_pt", &hw_all_tg_pt_handler, &snprint_hw_all_tg_pt);
2038         install_keyword("vpd_vendor", &hw_vpd_vendor_handler, &snprint_hw_vpd_vendor);
2039         install_keyword("recheck_wwid", &hw_recheck_wwid_handler, &snprint_hw_recheck_wwid);
2040         install_sublevel_end();
2041
2042         install_keyword_root("overrides", &overrides_handler);
2043         install_keyword("path_grouping_policy", &ovr_pgpolicy_handler, &snprint_ovr_pgpolicy);
2044         install_keyword("uid_attribute", &ovr_uid_attribute_handler, &snprint_ovr_uid_attribute);
2045         install_keyword("getuid_callout", &ovr_getuid_handler, &snprint_ovr_getuid);
2046         install_keyword("path_selector", &ovr_selector_handler, &snprint_ovr_selector);
2047         install_keyword("path_checker", &ovr_checker_name_handler, &snprint_ovr_checker_name);
2048         install_keyword("checker", &ovr_checker_name_handler, NULL);
2049         install_keyword("alias_prefix", &ovr_alias_prefix_handler, &snprint_ovr_alias_prefix);
2050         install_keyword("features", &ovr_features_handler, &snprint_ovr_features);
2051         install_keyword("prio", &ovr_prio_name_handler, &snprint_ovr_prio_name);
2052         install_keyword("prio_args", &ovr_prio_args_handler, &snprint_ovr_prio_args);
2053         install_keyword("failback", &ovr_pgfailback_handler, &snprint_ovr_pgfailback);
2054         install_keyword("rr_weight", &ovr_rr_weight_handler, &snprint_ovr_rr_weight);
2055         install_keyword("no_path_retry", &ovr_no_path_retry_handler, &snprint_ovr_no_path_retry);
2056         install_keyword("rr_min_io", &ovr_minio_handler, &snprint_ovr_minio);
2057         install_keyword("rr_min_io_rq", &ovr_minio_rq_handler, &snprint_ovr_minio_rq);
2058         install_keyword("flush_on_last_del", &ovr_flush_on_last_del_handler, &snprint_ovr_flush_on_last_del);
2059         install_keyword("fast_io_fail_tmo", &ovr_fast_io_fail_handler, &snprint_ovr_fast_io_fail);
2060         install_keyword("dev_loss_tmo", &ovr_dev_loss_handler, &snprint_ovr_dev_loss);
2061         install_keyword("eh_deadline", &ovr_eh_deadline_handler, &snprint_ovr_eh_deadline);
2062         install_keyword("user_friendly_names", &ovr_user_friendly_names_handler, &snprint_ovr_user_friendly_names);
2063         install_keyword("retain_attached_hw_handler", &ovr_retain_hwhandler_handler, &snprint_ovr_retain_hwhandler);
2064         install_keyword("detect_prio", &ovr_detect_prio_handler, &snprint_ovr_detect_prio);
2065         install_keyword("detect_checker", &ovr_detect_checker_handler, &snprint_ovr_detect_checker);
2066         install_keyword("deferred_remove", &ovr_deferred_remove_handler, &snprint_ovr_deferred_remove);
2067         install_keyword("delay_watch_checks", &ovr_delay_watch_checks_handler, &snprint_ovr_delay_watch_checks);
2068         install_keyword("delay_wait_checks", &ovr_delay_wait_checks_handler, &snprint_ovr_delay_wait_checks);
2069         install_keyword("san_path_err_threshold", &ovr_san_path_err_threshold_handler, &snprint_ovr_san_path_err_threshold);
2070         install_keyword("san_path_err_forget_rate", &ovr_san_path_err_forget_rate_handler, &snprint_ovr_san_path_err_forget_rate);
2071         install_keyword("san_path_err_recovery_time", &ovr_san_path_err_recovery_time_handler, &snprint_ovr_san_path_err_recovery_time);
2072         install_keyword("marginal_path_err_sample_time", &ovr_marginal_path_err_sample_time_handler, &snprint_ovr_marginal_path_err_sample_time);
2073         install_keyword("marginal_path_err_rate_threshold", &ovr_marginal_path_err_rate_threshold_handler, &snprint_ovr_marginal_path_err_rate_threshold);
2074         install_keyword("marginal_path_err_recheck_gap_time", &ovr_marginal_path_err_recheck_gap_time_handler, &snprint_ovr_marginal_path_err_recheck_gap_time);
2075         install_keyword("marginal_path_double_failed_time", &ovr_marginal_path_double_failed_time_handler, &snprint_ovr_marginal_path_double_failed_time);
2076
2077         install_keyword("skip_kpartx", &ovr_skip_kpartx_handler, &snprint_ovr_skip_kpartx);
2078         install_keyword("max_sectors_kb", &ovr_max_sectors_kb_handler, &snprint_ovr_max_sectors_kb);
2079         install_keyword("ghost_delay", &ovr_ghost_delay_handler, &snprint_ovr_ghost_delay);
2080         install_keyword("all_tg_pt", &ovr_all_tg_pt_handler, &snprint_ovr_all_tg_pt);
2081         install_keyword("recheck_wwid", &ovr_recheck_wwid_handler, &snprint_ovr_recheck_wwid);
2082
2083         install_keyword_root("multipaths", &multipaths_handler);
2084         install_keyword_multi("multipath", &multipath_handler, NULL);
2085         install_sublevel();
2086         install_keyword("wwid", &mp_wwid_handler, &snprint_mp_wwid);
2087         install_keyword("alias", &mp_alias_handler, &snprint_mp_alias);
2088         install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_pgpolicy);
2089         install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
2090         install_keyword("prio", &mp_prio_name_handler, &snprint_mp_prio_name);
2091         install_keyword("prio_args", &mp_prio_args_handler, &snprint_mp_prio_args);
2092         install_keyword("failback", &mp_pgfailback_handler, &snprint_mp_pgfailback);
2093         install_keyword("rr_weight", &mp_rr_weight_handler, &snprint_mp_rr_weight);
2094         install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
2095         install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_minio);
2096         install_keyword("rr_min_io_rq", &mp_minio_rq_handler, &snprint_mp_minio_rq);
2097         install_keyword("pg_timeout", &deprecated_handler, &snprint_deprecated);
2098         install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del);
2099         install_keyword("features", &mp_features_handler, &snprint_mp_features);
2100         install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
2101         install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
2102         install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
2103         install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
2104         install_keyword("user_friendly_names", &mp_user_friendly_names_handler, &snprint_mp_user_friendly_names);
2105         install_keyword("deferred_remove", &mp_deferred_remove_handler, &snprint_mp_deferred_remove);
2106         install_keyword("delay_watch_checks", &mp_delay_watch_checks_handler, &snprint_mp_delay_watch_checks);
2107         install_keyword("delay_wait_checks", &mp_delay_wait_checks_handler, &snprint_mp_delay_wait_checks);
2108         install_keyword("san_path_err_threshold", &mp_san_path_err_threshold_handler, &snprint_mp_san_path_err_threshold);
2109         install_keyword("san_path_err_forget_rate", &mp_san_path_err_forget_rate_handler, &snprint_mp_san_path_err_forget_rate);
2110         install_keyword("san_path_err_recovery_time", &mp_san_path_err_recovery_time_handler, &snprint_mp_san_path_err_recovery_time);
2111         install_keyword("marginal_path_err_sample_time", &mp_marginal_path_err_sample_time_handler, &snprint_mp_marginal_path_err_sample_time);
2112         install_keyword("marginal_path_err_rate_threshold", &mp_marginal_path_err_rate_threshold_handler, &snprint_mp_marginal_path_err_rate_threshold);
2113         install_keyword("marginal_path_err_recheck_gap_time", &mp_marginal_path_err_recheck_gap_time_handler, &snprint_mp_marginal_path_err_recheck_gap_time);
2114         install_keyword("marginal_path_double_failed_time", &mp_marginal_path_double_failed_time_handler, &snprint_mp_marginal_path_double_failed_time);
2115         install_keyword("skip_kpartx", &mp_skip_kpartx_handler, &snprint_mp_skip_kpartx);
2116         install_keyword("max_sectors_kb", &mp_max_sectors_kb_handler, &snprint_mp_max_sectors_kb);
2117         install_keyword("ghost_delay", &mp_ghost_delay_handler, &snprint_mp_ghost_delay);
2118         install_sublevel_end();
2119 }