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