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