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