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