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