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