14e7c572fca4dd80ab719fbdae1fe9d527fc62a8
[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 "errno.h"
23 #include <inttypes.h>
24
25 /*
26  * default block handlers
27  */
28 static int
29 polling_interval_handler(vector strvec)
30 {
31         char * buff;
32
33         buff = VECTOR_SLOT(strvec, 1);
34         conf->checkint = atoi(buff);
35         conf->max_checkint = MAX_CHECKINT(conf->checkint);
36
37         return 0;
38 }
39
40 static int
41 def_fast_io_fail_handler(vector strvec)
42 {
43         char * buff;
44
45         buff = set_value(strvec);
46         if (strlen(buff) == 3 && !strcmp(buff, "off"))
47                 conf->fast_io_fail = MP_FAST_IO_FAIL_OFF;
48         else if (sscanf(buff, "%d", &conf->fast_io_fail) != 1 ||
49                  conf->fast_io_fail < MP_FAST_IO_FAIL_ZERO)
50                 conf->fast_io_fail = MP_FAST_IO_FAIL_UNSET;
51         else if (conf->fast_io_fail == 0)
52                 conf->fast_io_fail = MP_FAST_IO_FAIL_ZERO;
53
54         FREE(buff);
55         return 0;
56 }
57
58 static int
59 def_dev_loss_handler(vector strvec)
60 {
61         char * buff;
62
63         buff = set_value(strvec);
64         if (!buff)
65                 return 1;
66
67         if (strlen(buff) == 8 && !strcmp(buff, "infinity"))
68                 conf->dev_loss = MAX_DEV_LOSS_TMO;
69         else if (sscanf(buff, "%u", &conf->dev_loss) != 1)
70                 conf->dev_loss = 0;
71
72         FREE(buff);
73         return 0;
74 }
75
76 static int
77 verbosity_handler(vector strvec)
78 {
79         char * buff;
80
81         buff = VECTOR_SLOT(strvec, 1);
82         conf->verbosity = atoi(buff);
83
84         return 0;
85 }
86
87 static int
88 max_polling_interval_handler(vector strvec)
89 {
90         char *buff;
91
92         buff = VECTOR_SLOT(strvec, 1);
93         conf->max_checkint = atoi(buff);
94
95         return 0;
96 }
97
98 static int
99 reassign_maps_handler(vector strvec)
100 {
101         char * buff;
102
103         buff = set_value(strvec);
104         if (!strcmp(buff, "yes"))
105                 conf->reassign_maps = 1;
106         else if (!strcmp(buff, "no"))
107                 conf->reassign_maps = 0;
108         else
109                 return 1;
110
111         return 0;
112 }
113
114 static int
115 multipath_dir_handler(vector strvec)
116 {
117         conf->multipath_dir = set_value(strvec);
118
119         if (!conf->multipath_dir)
120                 return 1;
121
122         return 0;
123 }
124
125 static int
126 def_selector_handler(vector strvec)
127 {
128         conf->selector = set_value(strvec);
129
130         if (!conf->selector)
131                 return 1;
132
133         return 0;
134 }
135
136 static int
137 def_pgpolicy_handler(vector strvec)
138 {
139         char * buff;
140
141         buff = set_value(strvec);
142
143         if (!buff)
144                 return 1;
145
146         conf->pgpolicy = get_pgpolicy_id(buff);
147         FREE(buff);
148
149         return 0;
150 }
151
152 static int
153 def_uid_attribute_handler(vector strvec)
154 {
155         conf->uid_attribute = set_value(strvec);
156
157         if (!conf->uid_attribute)
158                 return 1;
159
160         return 0;
161 }
162
163 static int
164 def_prio_handler(vector strvec)
165 {
166         conf->prio_name = set_value(strvec);
167
168         if (!conf->prio_name)
169                 return 1;
170
171         return 0;
172 }
173
174 static int
175 def_alias_prefix_handler(vector strvec)
176 {
177         conf->alias_prefix = set_value(strvec);
178
179         if (!conf->alias_prefix)
180                 return 1;
181
182         return 0;
183 }
184
185 static int
186 def_prio_args_handler(vector strvec)
187 {
188         conf->prio_args = set_value(strvec);
189
190         if (!conf->prio_args)
191                 return 1;
192
193         return 0;
194 }
195
196 static int
197 def_features_handler(vector strvec)
198 {
199         conf->features = set_value(strvec);
200
201         if (!conf->features)
202                 return 1;
203
204         return 0;
205 }
206
207 static int
208 def_path_checker_handler(vector strvec)
209 {
210         conf->checker_name = set_value(strvec);
211
212         if (!conf->checker_name)
213                 return 1;
214
215         return 0;
216 }
217
218 static int
219 def_minio_handler(vector strvec)
220 {
221         char * buff;
222
223         buff = set_value(strvec);
224
225         if (!buff)
226                 return 1;
227
228         conf->minio = atoi(buff);
229         FREE(buff);
230
231         return 0;
232 }
233
234 static int
235 def_minio_rq_handler(vector strvec)
236 {
237         char * buff;
238
239         buff = set_value(strvec);
240
241         if (!buff)
242                 return 1;
243
244         conf->minio_rq = atoi(buff);
245         FREE(buff);
246
247         return 0;
248 }
249
250 int
251 get_sys_max_fds(int *max_fds)
252 {
253         FILE *file;
254         int nr_open;
255         int ret = 1;
256
257         file = fopen("/proc/sys/fs/nr_open", "r");
258         if (!file) {
259                 fprintf(stderr, "Cannot open /proc/sys/fs/nr_open : %s\n",
260                         strerror(errno));
261                 return 1;
262         }
263         if (fscanf(file, "%d", &nr_open) != 1) {
264                 fprintf(stderr, "Cannot read max open fds from /proc/sys/fs/nr_open");
265                 if (ferror(file))
266                         fprintf(stderr, " : %s\n", strerror(errno));
267                 else
268                         fprintf(stderr, "\n");
269         } else {
270                 *max_fds = nr_open;
271                 ret = 0;
272         }
273         fclose(file);
274         return ret;
275 }
276
277
278 static int
279 max_fds_handler(vector strvec)
280 {
281         char * buff;
282         int r = 0;
283
284         buff = set_value(strvec);
285
286         if (!buff)
287                 return 1;
288
289         if (strlen(buff) == 3 &&
290             !strcmp(buff, "max"))
291                 r = get_sys_max_fds(&conf->max_fds);
292         else
293                 conf->max_fds = atoi(buff);
294         FREE(buff);
295
296         return r;
297 }
298
299 static int
300 def_mode_handler(vector strvec)
301 {
302         mode_t mode;
303         char *buff;
304
305         buff = set_value(strvec);
306
307         if (!buff)
308                 return 1;
309
310         if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
311                 conf->attribute_flags |= (1 << ATTR_MODE);
312                 conf->mode = mode;
313         }
314
315         FREE(buff);
316         return 0;
317 }
318
319 static int
320 def_uid_handler(vector strvec)
321 {
322         uid_t uid;
323         char *buff;
324         char passwd_buf[1024];
325         struct passwd info, *found;
326
327         buff = set_value(strvec);
328         if (!buff)
329                 return 1;
330         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
331                 conf->attribute_flags |= (1 << ATTR_UID);
332                 conf->uid = info.pw_uid;
333         }
334         else if (sscanf(buff, "%u", &uid) == 1){
335                 conf->attribute_flags |= (1 << ATTR_UID);
336                 conf->uid = uid;
337         }
338
339         FREE(buff);
340         return 0;
341 }
342
343 static int
344 def_gid_handler(vector strvec)
345 {
346         gid_t gid;
347         char *buff;
348         char passwd_buf[1024];
349         struct passwd info, *found;
350
351         buff = set_value(strvec);
352         if (!buff)
353                 return 1;
354
355         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
356                 conf->attribute_flags |= (1 << ATTR_GID);
357                 conf->gid = info.pw_gid;
358         }
359         else if (sscanf(buff, "%u", &gid) == 1){
360                 conf->attribute_flags |= (1 << ATTR_GID);
361                 conf->gid = gid;
362         }
363         FREE(buff);
364         return 0;
365 }
366
367 static int
368 def_weight_handler(vector strvec)
369 {
370         char * buff;
371
372         buff = set_value(strvec);
373
374         if (!buff)
375                 return 1;
376
377         if (strlen(buff) == 10 &&
378             !strcmp(buff, "priorities"))
379                 conf->rr_weight = RR_WEIGHT_PRIO;
380
381         if (strlen(buff) == strlen("uniform") &&
382             !strcmp(buff, "uniform"))
383                 conf->rr_weight = RR_WEIGHT_NONE;
384
385         FREE(buff);
386
387         return 0;
388 }
389
390 static int
391 default_failback_handler(vector strvec)
392 {
393         char * buff;
394
395         buff = set_value(strvec);
396
397         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
398                 conf->pgfailback = -FAILBACK_MANUAL;
399         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
400                 conf->pgfailback = -FAILBACK_IMMEDIATE;
401         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
402                 conf->pgfailback = -FAILBACK_FOLLOWOVER;
403         else
404                 conf->pgfailback = atoi(buff);
405
406         FREE(buff);
407
408         return 0;
409 }
410
411 static int
412 def_no_path_retry_handler(vector strvec)
413 {
414         char * buff;
415
416         buff = set_value(strvec);
417         if (!buff)
418                 return 1;
419
420         if ((strlen(buff) == 4 && !strcmp(buff, "fail")) ||
421             (strlen(buff) == 1 && !strcmp(buff, "0")))
422                 conf->no_path_retry = NO_PATH_RETRY_FAIL;
423         else if (strlen(buff) == 5 && !strcmp(buff, "queue"))
424                 conf->no_path_retry = NO_PATH_RETRY_QUEUE;
425         else if ((conf->no_path_retry = atoi(buff)) < 1)
426                 conf->no_path_retry = NO_PATH_RETRY_UNDEF;
427
428         FREE(buff);
429         return 0;
430 }
431
432 static int
433 def_queue_without_daemon(vector strvec)
434 {
435         char * buff;
436
437         buff = set_value(strvec);
438         if (!buff)
439                 return 1;
440
441         if (!strncmp(buff, "on", 2) || !strncmp(buff, "yes", 3) ||
442                  !strncmp(buff, "1", 1))
443                 conf->queue_without_daemon = QUE_NO_DAEMON_ON;
444         else
445                 conf->queue_without_daemon = QUE_NO_DAEMON_OFF;
446
447         free(buff);
448         return 0;
449 }
450
451 static int
452 def_checker_timeout_handler(vector strvec)
453 {
454         unsigned int checker_timeout;
455         char *buff;
456
457         buff = set_value(strvec);
458         if (!buff)
459                 return 1;
460
461         if (sscanf(buff, "%u", &checker_timeout) == 1)
462                 conf->checker_timeout = checker_timeout;
463         else
464                 conf->checker_timeout = 0;
465
466         free(buff);
467         return 0;
468 }
469
470 static int
471 def_pg_timeout_handler(vector strvec)
472 {
473         int pg_timeout;
474         char * buff;
475
476         buff = set_value(strvec);
477
478         if (!buff)
479                 return 1;
480
481         if (strlen(buff) == 4 && !strcmp(buff, "none"))
482                 conf->pg_timeout = -PGTIMEOUT_NONE;
483         else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
484                 if (pg_timeout == 0)
485                         conf->pg_timeout = -PGTIMEOUT_NONE;
486                 else
487                         conf->pg_timeout = pg_timeout;
488         }
489         else
490                 conf->pg_timeout = PGTIMEOUT_UNDEF;
491
492         FREE(buff);
493         return 0;
494 }
495
496 static int
497 def_flush_on_last_del_handler(vector strvec)
498 {
499         char * buff;
500
501         buff = set_value(strvec);
502         if (!buff)
503                 return 1;
504
505         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
506             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
507                 conf->flush_on_last_del = FLUSH_DISABLED;
508         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
509             (strlen(buff) == 1 && strcmp(buff, "1") == 0))
510                 conf->flush_on_last_del = FLUSH_ENABLED;
511         else
512                 conf->flush_on_last_del = FLUSH_UNDEF;
513
514         FREE(buff);
515         return 0;
516 }
517
518 static int
519 def_log_checker_err_handler(vector strvec)
520 {
521         char * buff;
522
523         buff = set_value(strvec);
524
525         if (!buff)
526                 return 1;
527
528         if (strlen(buff) == 4 && !strcmp(buff, "once"))
529                 conf->log_checker_err = LOG_CHKR_ERR_ONCE;
530         else if (strlen(buff) == 6 && !strcmp(buff, "always"))
531                 conf->log_checker_err = LOG_CHKR_ERR_ALWAYS;
532
533         free(buff);
534         return 0;
535 }
536
537 static int
538 def_reservation_key_handler(vector strvec)
539 {
540         char *buff;
541         char *tbuff;
542         int j, k;
543         int len;
544         uint64_t prkey;
545
546         buff = set_value(strvec);
547         if (!buff)
548                 return 1;
549
550         tbuff = buff;
551
552         if (!memcmp("0x",buff, 2))
553                 buff = buff + 2;
554
555         len = strlen(buff);
556
557         k = strspn(buff, "0123456789aAbBcCdDeEfF");
558
559         if (len != k) {
560                 FREE(tbuff);
561                 return 1;
562         }
563
564         if (1 != sscanf (buff, "%" SCNx64 "", &prkey))
565         {
566                 FREE(tbuff);
567                 return 1;
568         }
569
570         if (!conf->reservation_key)
571                 conf->reservation_key = (unsigned char *) malloc(8);
572
573         memset(conf->reservation_key, 0, 8);
574
575         for (j = 7; j >= 0; --j) {
576                 conf->reservation_key[j] = (prkey & 0xff);
577                 prkey >>= 8;
578         }
579
580         FREE(tbuff);
581         return 0;
582 }
583
584 static int
585 def_names_handler(vector strvec)
586 {
587         char * buff;
588
589         buff = set_value(strvec);
590
591         if (!buff)
592                 return 1;
593
594         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
595             (strlen(buff) == 1 && !strcmp(buff, "0")))
596                 conf->user_friendly_names = USER_FRIENDLY_NAMES_OFF;
597         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
598                  (strlen(buff) == 1 && !strcmp(buff, "1")))
599                 conf->user_friendly_names = USER_FRIENDLY_NAMES_ON;
600         else
601                 conf->user_friendly_names = USER_FRIENDLY_NAMES_UNDEF;
602
603         FREE(buff);
604         return 0;
605 }
606
607 static int
608 bindings_file_handler(vector strvec)
609 {
610         conf->bindings_file = set_value(strvec);
611
612         if (!conf->bindings_file)
613                 return 1;
614
615         return 0;
616 }
617
618 static int
619 wwids_file_handler(vector strvec)
620 {
621         conf->wwids_file = set_value(strvec);
622
623         if (!conf->wwids_file)
624                 return 1;
625
626         return 0;
627 }
628
629 static int
630 def_retain_hwhandler_handler(vector strvec)
631 {
632         char * buff;
633
634         buff = set_value(strvec);
635
636         if (!buff)
637                 return 1;
638
639         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
640             (strlen(buff) == 1 && !strcmp(buff, "0")))
641                 conf->retain_hwhandler = RETAIN_HWHANDLER_OFF;
642         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
643                  (strlen(buff) == 1 && !strcmp(buff, "1")))
644                 conf->retain_hwhandler = RETAIN_HWHANDLER_ON;
645         else
646                 conf->retain_hwhandler = RETAIN_HWHANDLER_UNDEF;
647
648         FREE(buff);
649         return 0;
650 }
651
652 static int
653 def_detect_prio_handler(vector strvec)
654 {
655         char * buff;
656
657         buff = set_value(strvec);
658
659         if (!buff)
660                 return 1;
661
662         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
663             (strlen(buff) == 1 && !strcmp(buff, "0")))
664                 conf->detect_prio = DETECT_PRIO_OFF;
665         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
666                  (strlen(buff) == 1 && !strcmp(buff, "1")))
667                 conf->detect_prio = DETECT_PRIO_ON;
668         else
669                 conf->detect_prio = DETECT_PRIO_UNDEF;
670
671         FREE(buff);
672         return 0;
673 }
674
675 /*
676  * blacklist block handlers
677  */
678 static int
679 blacklist_handler(vector strvec)
680 {
681         conf->blist_devnode = vector_alloc();
682         conf->blist_wwid = vector_alloc();
683         conf->blist_device = vector_alloc();
684
685         if (!conf->blist_devnode || !conf->blist_wwid || !conf->blist_device)
686                 return 1;
687
688         return 0;
689 }
690
691 static int
692 blacklist_exceptions_handler(vector strvec)
693 {
694         conf->elist_devnode = vector_alloc();
695         conf->elist_wwid = vector_alloc();
696         conf->elist_device = vector_alloc();
697
698         if (!conf->elist_devnode || !conf->elist_wwid || !conf->elist_device)
699                 return 1;
700
701         return 0;
702 }
703
704 static int
705 ble_devnode_handler(vector strvec)
706 {
707         char * buff;
708
709         buff = set_value(strvec);
710
711         if (!buff)
712                 return 1;
713
714         return store_ble(conf->blist_devnode, buff, ORIGIN_CONFIG);
715 }
716
717 static int
718 ble_except_devnode_handler(vector strvec)
719 {
720         char * buff;
721
722         buff = set_value(strvec);
723
724         if (!buff)
725                 return 1;
726
727         return store_ble(conf->elist_devnode, buff, ORIGIN_CONFIG);
728 }
729
730 static int
731 ble_wwid_handler(vector strvec)
732 {
733         char * buff;
734
735         buff = set_value(strvec);
736
737         if (!buff)
738                 return 1;
739
740         return store_ble(conf->blist_wwid, buff, ORIGIN_CONFIG);
741 }
742
743 static int
744 ble_except_wwid_handler(vector strvec)
745 {
746         char * buff;
747
748         buff = set_value(strvec);
749
750         if (!buff)
751                 return 1;
752
753         return store_ble(conf->elist_wwid, buff, ORIGIN_CONFIG);
754 }
755
756 static int
757 ble_device_handler(vector strvec)
758 {
759         return alloc_ble_device(conf->blist_device);
760 }
761
762 static int
763 ble_except_device_handler(vector strvec)
764 {
765         return alloc_ble_device(conf->elist_device);
766 }
767
768 static int
769 ble_vendor_handler(vector strvec)
770 {
771         char * buff;
772
773         buff = set_value(strvec);
774
775         if (!buff)
776                 return 1;
777
778         return set_ble_device(conf->blist_device, buff, NULL, ORIGIN_CONFIG);
779 }
780
781 static int
782 ble_except_vendor_handler(vector strvec)
783 {
784         char * buff;
785
786         buff = set_value(strvec);
787
788         if (!buff)
789                 return 1;
790
791         return set_ble_device(conf->elist_device, buff, NULL, ORIGIN_CONFIG);
792 }
793
794 static int
795 ble_product_handler(vector strvec)
796 {
797         char * buff;
798
799         buff = set_value(strvec);
800
801         if (!buff)
802                 return 1;
803
804         return set_ble_device(conf->blist_device, NULL, buff, ORIGIN_CONFIG);
805 }
806
807 static int
808 ble_except_product_handler(vector strvec)
809 {
810         char * buff;
811
812         buff = set_value(strvec);
813
814         if (!buff)
815                 return 1;
816
817         return set_ble_device(conf->elist_device, NULL, buff, ORIGIN_CONFIG);
818 }
819
820 /*
821  * devices block handlers
822  */
823 static int
824 devices_handler(vector strvec)
825 {
826         if (!conf->hwtable)
827                 conf->hwtable = vector_alloc();
828
829         if (!conf->hwtable)
830                 return 1;
831
832         return 0;
833 }
834
835 static int
836 device_handler(vector strvec)
837 {
838         struct hwentry * hwe;
839
840         hwe = alloc_hwe();
841
842         if (!hwe)
843                 return 1;
844
845         if (!vector_alloc_slot(conf->hwtable)) {
846                 free_hwe(hwe);
847                 return 1;
848         }
849         vector_set_slot(conf->hwtable, hwe);
850
851         return 0;
852 }
853
854 static int
855 vendor_handler(vector strvec)
856 {
857         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
858
859         if (!hwe)
860                 return 1;
861
862         hwe->vendor = set_value(strvec);
863
864         if (!hwe->vendor)
865                 return 1;
866
867         return 0;
868 }
869
870 static int
871 product_handler(vector strvec)
872 {
873         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
874
875         if (!hwe)
876                 return 1;
877
878         hwe->product = set_value(strvec);
879
880         if (!hwe->product)
881                 return 1;
882
883         return 0;
884 }
885
886 static int
887 revision_handler(vector strvec)
888 {
889         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
890
891         if (!hwe)
892                 return 1;
893
894         hwe->revision = set_value(strvec);
895
896         if (!hwe->revision)
897                 return 1;
898
899         return 0;
900 }
901
902 static int
903 bl_product_handler(vector strvec)
904 {
905         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
906
907         if (!hwe)
908                 return 1;
909
910         hwe->bl_product = set_value(strvec);
911         if (!hwe->bl_product)
912                 return 1;
913
914         return 0;
915 }
916
917 static int
918 hw_fast_io_fail_handler(vector strvec)
919 {
920         char * buff;
921         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
922
923         buff = set_value(strvec);
924         if (strlen(buff) == 3 && !strcmp(buff, "off"))
925                 hwe->fast_io_fail = MP_FAST_IO_FAIL_OFF;
926         else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 ||
927                  hwe->fast_io_fail < MP_FAST_IO_FAIL_ZERO)
928                 hwe->fast_io_fail = MP_FAST_IO_FAIL_UNSET;
929         else if (hwe->fast_io_fail == 0)
930                 hwe->fast_io_fail = MP_FAST_IO_FAIL_ZERO;
931
932         FREE(buff);
933         return 0;
934 }
935
936 static int
937 hw_dev_loss_handler(vector strvec)
938 {
939         char * buff;
940         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
941
942         buff = set_value(strvec);
943         if (!buff)
944                 return 1;
945
946         if (strlen(buff) == 8 && !strcmp(buff, "infinity"))
947                 hwe->dev_loss = MAX_DEV_LOSS_TMO;
948         else if (sscanf(buff, "%u", &hwe->dev_loss) != 1)
949                 hwe->dev_loss = 0;
950
951         FREE(buff);
952         return 0;
953 }
954
955 static int
956 hw_pgpolicy_handler(vector strvec)
957 {
958         char * buff;
959         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
960
961         buff = set_value(strvec);
962
963         if (!buff)
964                 return 1;
965
966         hwe->pgpolicy = get_pgpolicy_id(buff);
967         FREE(buff);
968
969         return 0;
970 }
971
972 static int
973 hw_uid_attribute_handler(vector strvec)
974 {
975         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
976
977         hwe->uid_attribute = set_value(strvec);
978
979         if (!hwe->uid_attribute)
980                 return 1;
981
982         return 0;
983 }
984
985 static int
986 hw_selector_handler(vector strvec)
987 {
988         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
989
990         if (!hwe)
991                 return 1;
992
993         hwe->selector = set_value(strvec);
994
995         if (!hwe->selector)
996                 return 1;
997
998         return 0;
999 }
1000
1001 static int
1002 hw_path_checker_handler(vector strvec)
1003 {
1004         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1005
1006         if (!hwe)
1007                 return 1;
1008
1009         hwe->checker_name = set_value(strvec);
1010
1011         if (!hwe->checker_name)
1012                 return 1;
1013
1014         return 0;
1015 }
1016
1017 static int
1018 hw_features_handler(vector strvec)
1019 {
1020         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1021
1022         if (!hwe)
1023                 return 1;
1024
1025         hwe->features = set_value(strvec);
1026
1027         if (!hwe->features)
1028                 return 1;
1029
1030         return 0;
1031 }
1032
1033 static int
1034 hw_handler_handler(vector strvec)
1035 {
1036         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1037
1038         if (!hwe)
1039                 return 1;
1040
1041         hwe->hwhandler = set_value(strvec);
1042
1043         if (!hwe->hwhandler)
1044                 return 1;
1045
1046         return 0;
1047 }
1048
1049 static int
1050 hw_prio_handler(vector strvec)
1051 {
1052         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1053
1054         if (!hwe)
1055                 return 1;
1056
1057         hwe->prio_name = set_value(strvec);
1058
1059         if (!hwe->prio_name)
1060                 return 1;
1061
1062         return 0;
1063 }
1064
1065 static int
1066 hw_alias_prefix_handler(vector strvec)
1067 {
1068         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1069
1070         if (!hwe)
1071                 return 1;
1072
1073         hwe->alias_prefix = set_value(strvec);
1074
1075         if (!hwe->alias_prefix)
1076                 return 1;
1077
1078         return 0;
1079 }
1080
1081 static int
1082 hw_prio_args_handler(vector strvec)
1083 {
1084         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1085
1086         if (!hwe)
1087                 return 1;
1088
1089         hwe->prio_args = set_value(strvec);
1090
1091         if (!hwe->prio_args)
1092                 return 1;
1093
1094         return 0;
1095 }
1096
1097 static int
1098 hw_failback_handler(vector strvec)
1099 {
1100         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1101         char * buff;
1102
1103         if (!hwe)
1104                 return 1;
1105
1106         buff = set_value(strvec);
1107
1108         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
1109                 hwe->pgfailback = -FAILBACK_MANUAL;
1110         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
1111                 hwe->pgfailback = -FAILBACK_IMMEDIATE;
1112         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
1113                 hwe->pgfailback = -FAILBACK_FOLLOWOVER;
1114         else
1115                 hwe->pgfailback = atoi(buff);
1116
1117         FREE(buff);
1118
1119         return 0;
1120 }
1121
1122 static int
1123 hw_weight_handler(vector strvec)
1124 {
1125         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1126         char * buff;
1127
1128         if (!hwe)
1129                 return 1;
1130
1131         buff = set_value(strvec);
1132
1133         if (!buff)
1134                 return 1;
1135
1136         if (strlen(buff) == 10 &&
1137             !strcmp(buff, "priorities"))
1138                 hwe->rr_weight = RR_WEIGHT_PRIO;
1139
1140         if (strlen(buff) == strlen("uniform") &&
1141             !strcmp(buff, "uniform"))
1142                 hwe->rr_weight = RR_WEIGHT_NONE;
1143
1144         FREE(buff);
1145
1146         return 0;
1147 }
1148
1149 static int
1150 hw_no_path_retry_handler(vector strvec)
1151 {
1152         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1153         char *buff;
1154
1155         if (!hwe)
1156                 return 1;
1157
1158         buff = set_value(strvec);
1159         if (!buff)
1160                 return 1;
1161
1162         if ((strlen(buff) == 4 && !strcmp(buff, "fail")) ||
1163             (strlen(buff) == 1 && !strcmp(buff, "0")))
1164                 hwe->no_path_retry = NO_PATH_RETRY_FAIL;
1165         else if (strlen(buff) == 5 && !strcmp(buff, "queue"))
1166                 hwe->no_path_retry = NO_PATH_RETRY_QUEUE;
1167         else if ((hwe->no_path_retry = atoi(buff)) < 1)
1168                 hwe->no_path_retry = NO_PATH_RETRY_UNDEF;
1169
1170         FREE(buff);
1171         return 0;
1172 }
1173
1174 static int
1175 hw_minio_handler(vector strvec)
1176 {
1177         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1178         char * buff;
1179
1180         if (!hwe)
1181                 return 1;
1182
1183         buff = set_value(strvec);
1184
1185         if (!buff)
1186                 return 1;
1187
1188         hwe->minio = atoi(buff);
1189         FREE(buff);
1190
1191         return 0;
1192 }
1193
1194 static int
1195 hw_minio_rq_handler(vector strvec)
1196 {
1197         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1198         char * buff;
1199
1200         if (!hwe)
1201                 return 1;
1202
1203         buff = set_value(strvec);
1204
1205         if (!buff)
1206                 return 1;
1207
1208         hwe->minio_rq = atoi(buff);
1209         FREE(buff);
1210
1211         return 0;
1212 }
1213
1214 static int
1215 hw_pg_timeout_handler(vector strvec)
1216 {
1217         int pg_timeout;
1218         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1219         char *buff;
1220
1221         if (!hwe)
1222                 return 1;
1223
1224         buff = set_value(strvec);
1225
1226         if (!buff)
1227                 return 1;
1228
1229         if (strlen(buff) == 4 && !strcmp(buff, "none"))
1230                 hwe->pg_timeout = -PGTIMEOUT_NONE;
1231         else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
1232                 if (pg_timeout == 0)
1233                         hwe->pg_timeout = -PGTIMEOUT_NONE;
1234                 else
1235                         hwe->pg_timeout = pg_timeout;
1236         }
1237         else
1238                 hwe->pg_timeout = PGTIMEOUT_UNDEF;
1239
1240         FREE(buff);
1241         return 0;
1242 }
1243
1244 static int
1245 hw_flush_on_last_del_handler(vector strvec)
1246 {
1247         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1248         char * buff;
1249
1250         if (!hwe)
1251                 return 1;
1252
1253         buff = set_value(strvec);
1254         if (!buff)
1255                 return 1;
1256
1257         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1258             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1259                 hwe->flush_on_last_del = FLUSH_DISABLED;
1260         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1261             (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1262                 hwe->flush_on_last_del = FLUSH_ENABLED;
1263         else
1264                 hwe->flush_on_last_del = FLUSH_UNDEF;
1265
1266         FREE(buff);
1267         return 0;
1268 }
1269
1270 static int
1271 hw_names_handler(vector strvec)
1272 {
1273         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1274         char * buff;
1275
1276         if (!hwe)
1277                 return 1;
1278
1279         buff = set_value(strvec);
1280         if (!buff)
1281                 return 1;
1282
1283         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1284             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1285                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_OFF;
1286         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1287                  (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1288                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_ON;
1289         else
1290                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_UNDEF;
1291
1292         FREE(buff);
1293         return 0;
1294 }
1295
1296 static int
1297 hw_retain_hwhandler_handler(vector strvec)
1298 {
1299         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1300         char * buff;
1301
1302         if (!hwe)
1303                 return 1;
1304
1305         buff = set_value(strvec);
1306
1307         if (!buff)
1308                 return 1;
1309
1310         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
1311             (strlen(buff) == 1 && !strcmp(buff, "0")))
1312                 hwe->retain_hwhandler = RETAIN_HWHANDLER_OFF;
1313         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
1314                  (strlen(buff) == 1 && !strcmp(buff, "1")))
1315                 hwe->retain_hwhandler = RETAIN_HWHANDLER_ON;
1316         else
1317                 hwe->user_friendly_names = RETAIN_HWHANDLER_UNDEF;
1318
1319         FREE(buff);
1320         return 0;
1321 }
1322
1323 static int
1324 hw_detect_prio_handler(vector strvec)
1325 {
1326         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1327         char * buff;
1328
1329         if (!hwe)
1330                 return 1;
1331
1332         buff = set_value(strvec);
1333
1334         if (!buff)
1335                 return 1;
1336
1337         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
1338             (strlen(buff) == 1 && !strcmp(buff, "0")))
1339                 hwe->detect_prio = DETECT_PRIO_OFF;
1340         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
1341                  (strlen(buff) == 1 && !strcmp(buff, "1")))
1342                 hwe->detect_prio = DETECT_PRIO_ON;
1343         else
1344                 hwe->detect_prio = DETECT_PRIO_UNDEF;
1345
1346         FREE(buff);
1347         return 0;
1348 }
1349
1350 /*
1351  * multipaths block handlers
1352  */
1353 static int
1354 multipaths_handler(vector strvec)
1355 {
1356         conf->mptable = vector_alloc();
1357
1358         if (!conf->mptable)
1359                 return 1;
1360
1361         return 0;
1362 }
1363
1364 static int
1365 multipath_handler(vector strvec)
1366 {
1367         struct mpentry * mpe;
1368
1369         mpe = alloc_mpe();
1370
1371         if (!mpe)
1372                 return 1;
1373
1374         if (!vector_alloc_slot(conf->mptable)) {
1375                 free_mpe(mpe);
1376                 return 1;
1377         }
1378         vector_set_slot(conf->mptable, mpe);
1379
1380         return 0;
1381 }
1382
1383 static int
1384 wwid_handler(vector strvec)
1385 {
1386         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1387
1388         if (!mpe)
1389                 return 1;
1390
1391         mpe->wwid = set_value(strvec);
1392
1393         if (!mpe->wwid)
1394                 return 1;
1395
1396         return 0;
1397 }
1398
1399 static int
1400 alias_handler(vector strvec)
1401 {
1402         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1403
1404         if (!mpe)
1405                 return 1;
1406
1407         mpe->alias = set_value(strvec);
1408
1409         if (!mpe->alias)
1410                 return 1;
1411
1412         return 0;
1413 }
1414
1415 static int
1416 mp_pgpolicy_handler(vector strvec)
1417 {
1418         char * buff;
1419         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1420
1421         if (!mpe)
1422                 return 1;
1423
1424         buff = set_value(strvec);
1425
1426         if (!buff)
1427                 return 1;
1428
1429         mpe->pgpolicy = get_pgpolicy_id(buff);
1430         FREE(buff);
1431
1432         return 0;
1433 }
1434
1435 static int
1436 mp_selector_handler(vector strvec)
1437 {
1438         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1439
1440         if (!mpe)
1441                 return 1;
1442
1443         mpe->selector = set_value(strvec);
1444
1445         if (!mpe->selector)
1446                 return 1;
1447
1448         return 0;
1449 }
1450
1451 static int
1452 mp_failback_handler(vector strvec)
1453 {
1454         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1455         char * buff;
1456
1457         if (!mpe)
1458                 return 1;
1459
1460         buff = set_value(strvec);
1461
1462         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
1463                 mpe->pgfailback = -FAILBACK_MANUAL;
1464         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
1465                 mpe->pgfailback = -FAILBACK_IMMEDIATE;
1466         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
1467                 mpe->pgfailback = -FAILBACK_FOLLOWOVER;
1468         else
1469                 mpe->pgfailback = atoi(buff);
1470
1471         FREE(buff);
1472
1473         return 0;
1474 }
1475
1476 static int
1477 mp_mode_handler(vector strvec)
1478 {
1479         mode_t mode;
1480         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1481         char *buff;
1482
1483         if (!mpe)
1484                 return 1;
1485
1486         buff = set_value(strvec);
1487         if (!buff)
1488                 return 1;
1489         if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
1490                 mpe->attribute_flags |= (1 << ATTR_MODE);
1491                 mpe->mode = mode;
1492         }
1493
1494         FREE(buff);
1495         return 0;
1496 }
1497
1498 static int
1499 mp_uid_handler(vector strvec)
1500 {
1501         uid_t uid;
1502         char *buff;
1503         char passwd_buf[1024];
1504         struct passwd info, *found;
1505
1506         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1507
1508         if (!mpe)
1509                 return 1;
1510
1511         buff = set_value(strvec);
1512         if (!buff)
1513                 return 1;
1514
1515         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
1516                 mpe->attribute_flags |= (1 << ATTR_UID);
1517                 mpe->uid = info.pw_uid;
1518         }
1519         else if (sscanf(buff, "%u", &uid) == 1){
1520                 mpe->attribute_flags |= (1 << ATTR_UID);
1521                 mpe->uid = uid;
1522         }
1523         FREE(buff);
1524         return 0;
1525 }
1526
1527 static int
1528 mp_gid_handler(vector strvec)
1529 {
1530         gid_t gid;
1531         char *buff;
1532         char passwd_buf[1024];
1533         struct passwd info, *found;
1534
1535         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1536
1537         if (!mpe)
1538                 return 1;
1539
1540         buff = set_value(strvec);
1541         if (!buff)
1542                 return 1;
1543
1544         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
1545                 mpe->attribute_flags |= (1 << ATTR_GID);
1546                 mpe->gid = info.pw_gid;
1547         }
1548         else if (sscanf(buff, "%u", &gid) == 1) {
1549                 mpe->attribute_flags |= (1 << ATTR_GID);
1550                 mpe->gid = gid;
1551         }
1552         FREE(buff);
1553         return 0;
1554 }
1555
1556 static int
1557 mp_weight_handler(vector strvec)
1558 {
1559         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1560         char * buff;
1561
1562         if (!mpe)
1563                 return 1;
1564
1565         buff = set_value(strvec);
1566
1567         if (!buff)
1568                 return 1;
1569
1570         if (strlen(buff) == 10 &&
1571             !strcmp(buff, "priorities"))
1572                 mpe->rr_weight = RR_WEIGHT_PRIO;
1573
1574         if (strlen(buff) == strlen("uniform") &&
1575             !strcmp(buff, "uniform"))
1576                 mpe->rr_weight = RR_WEIGHT_NONE;
1577
1578         FREE(buff);
1579
1580         return 0;
1581 }
1582
1583 static int
1584 mp_no_path_retry_handler(vector strvec)
1585 {
1586         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1587         char *buff;
1588
1589         if (!mpe)
1590                 return 1;
1591
1592         buff = set_value(strvec);
1593         if (!buff)
1594                 return 1;
1595
1596         if ((strlen(buff) == 4 && !strcmp(buff, "fail")) ||
1597             (strlen(buff) == 1 && !strcmp(buff, "0")))
1598                 mpe->no_path_retry = NO_PATH_RETRY_FAIL;
1599         else if (strlen(buff) == 5 && !strcmp(buff, "queue"))
1600                 mpe->no_path_retry = NO_PATH_RETRY_QUEUE;
1601         else if ((mpe->no_path_retry = atoi(buff)) < 1)
1602                 mpe->no_path_retry = NO_PATH_RETRY_UNDEF;
1603
1604         FREE(buff);
1605         return 0;
1606 }
1607
1608 static int
1609 mp_minio_handler(vector strvec)
1610 {
1611         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1612         char * buff;
1613
1614         if (!mpe)
1615                 return 1;
1616
1617         buff = set_value(strvec);
1618
1619         if (!buff)
1620                 return 1;
1621
1622         mpe->minio = atoi(buff);
1623         FREE(buff);
1624
1625         return 0;
1626 }
1627
1628 static int
1629 mp_minio_rq_handler(vector strvec)
1630 {
1631         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1632         char * buff;
1633
1634         if (!mpe)
1635                 return 1;
1636
1637         buff = set_value(strvec);
1638
1639         if (!buff)
1640                 return 1;
1641
1642         mpe->minio_rq = atoi(buff);
1643         FREE(buff);
1644
1645         return 0;
1646 }
1647
1648 static int
1649 mp_pg_timeout_handler(vector strvec)
1650 {
1651         int pg_timeout;
1652         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1653         char *buff;
1654
1655         if (!mpe)
1656                 return 1;
1657
1658         buff = set_value(strvec);
1659
1660         if (!buff)
1661                 return 1;
1662         if (strlen(buff) == 4 && !strcmp(buff, "none"))
1663                 mpe->pg_timeout = -PGTIMEOUT_NONE;
1664         else if (sscanf(buff, "%d", &pg_timeout) == 1 && pg_timeout >= 0) {
1665                 if (pg_timeout == 0)
1666                         mpe->pg_timeout = -PGTIMEOUT_NONE;
1667                 else
1668                         mpe->pg_timeout = pg_timeout;
1669         }
1670         else
1671                 mpe->pg_timeout = PGTIMEOUT_UNDEF;
1672
1673         FREE(buff);
1674         return 0;
1675 }
1676
1677 static int
1678 mp_features_handler(vector strvec)
1679 {
1680         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1681
1682         if (!mpe)
1683                 return 1;
1684
1685         mpe->features = set_value(strvec);
1686
1687         if (!mpe->features)
1688                 return 1;
1689
1690         return 0;
1691 }
1692
1693 static int
1694 mp_flush_on_last_del_handler(vector strvec)
1695 {
1696         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1697         char * buff;
1698
1699         if (!mpe)
1700                 return 1;
1701
1702         buff = set_value(strvec);
1703         if (!buff)
1704                 return 1;
1705
1706         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1707             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1708                 mpe->flush_on_last_del = FLUSH_DISABLED;
1709         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1710             (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1711                 mpe->flush_on_last_del = FLUSH_ENABLED;
1712         else
1713                 mpe->flush_on_last_del = FLUSH_UNDEF;
1714
1715         FREE(buff);
1716         return 0;
1717 }
1718
1719 static int
1720 mp_prio_handler(vector strvec)
1721 {
1722         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1723
1724         if (!mpe)
1725                 return 1;
1726
1727         mpe->prio_name = set_value(strvec);
1728
1729         if (!mpe->prio_name)
1730                 return 1;
1731
1732         return 0;
1733 }
1734
1735 static int
1736 mp_prio_args_handler (vector strvec)
1737 {
1738         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1739
1740         if (!mpe)
1741                 return 1;
1742
1743         mpe->prio_args = set_value(strvec);
1744         if (!mpe->prio_args)
1745                 return 1;
1746
1747         return 0;
1748 }
1749
1750 static int
1751 mp_reservation_key_handler (vector strvec)
1752 {
1753         char *buff;
1754         char *tbuff;
1755         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1756
1757         int j, k, len;
1758         uint64_t prkey;
1759
1760         if (!mpe)
1761                 return 1;
1762
1763         buff = set_value(strvec);
1764         if (!buff)
1765                 return 1;
1766
1767         tbuff = buff;
1768         if (!memcmp(buff, "0x", 2))
1769                 buff = buff + 2;
1770
1771         len = strlen(buff);
1772
1773         k = strspn(buff, "0123456789aAbBcCdDeEfF");
1774         if (len != k) {
1775                 FREE(tbuff);
1776                 return 1;
1777         }
1778
1779         if (1 != sscanf (buff, "%" SCNx64 "", &prkey))
1780         {
1781                 FREE(tbuff);
1782                 return 1;
1783         }
1784
1785         if (!mpe->reservation_key)
1786                 mpe->reservation_key = (unsigned char *) malloc(8);
1787
1788         memset(mpe->reservation_key, 0, 8);
1789
1790         for (j = 7; j >= 0; --j) {
1791                 mpe->reservation_key[j] = (prkey & 0xff);
1792                 prkey >>= 8;
1793         }
1794
1795         FREE(tbuff);
1796         return 0;
1797 }
1798
1799 static int
1800 mp_names_handler(vector strvec)
1801 {
1802         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1803         char * buff;
1804
1805         if (!mpe)
1806                 return 1;
1807
1808         buff = set_value(strvec);
1809         if (!buff)
1810                 return 1;
1811
1812         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1813             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1814                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_OFF;
1815         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1816                  (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1817                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_ON;
1818         else
1819                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_UNDEF;
1820
1821         FREE(buff);
1822         return 0;
1823 }
1824
1825 /*
1826  * config file keywords printing
1827  */
1828 static int
1829 snprint_mp_wwid (char * buff, int len, void * data)
1830 {
1831         struct mpentry * mpe = (struct mpentry *)data;
1832
1833         return snprintf(buff, len, "%s", mpe->wwid);
1834 }
1835
1836 static int
1837 snprint_mp_alias (char * buff, int len, void * data)
1838 {
1839         struct mpentry * mpe = (struct mpentry *)data;
1840
1841         if (!mpe->alias)
1842                 return 0;
1843
1844         return snprintf(buff, len, "%s", mpe->alias);
1845 }
1846
1847 static int
1848 snprint_mp_path_grouping_policy (char * buff, int len, void * data)
1849 {
1850         struct mpentry * mpe = (struct mpentry *)data;
1851         char str[POLICY_NAME_SIZE];
1852
1853         if (!mpe->pgpolicy)
1854                 return 0;
1855         get_pgpolicy_name(str, POLICY_NAME_SIZE, mpe->pgpolicy);
1856
1857         return snprintf(buff, len, "\"%s\"", str);
1858 }
1859
1860 static int
1861 snprint_mp_selector (char * buff, int len, void * data)
1862 {
1863         struct mpentry * mpe = (struct mpentry *)data;
1864
1865         if (!mpe->selector)
1866                 return 0;
1867
1868         return snprintf(buff, len, "\"%s\"", mpe->selector);
1869 }
1870
1871 static int
1872 snprint_mp_failback (char * buff, int len, void * data)
1873 {
1874         struct mpentry * mpe = (struct mpentry *)data;
1875
1876         if (!mpe->pgfailback)
1877                 return 0;
1878
1879         switch(mpe->pgfailback) {
1880         case  FAILBACK_UNDEF:
1881                 break;
1882         case -FAILBACK_MANUAL:
1883                 return snprintf(buff, len, "\"manual\"");
1884         case -FAILBACK_IMMEDIATE:
1885                 return snprintf(buff, len, "\"immediate\"");
1886         case -FAILBACK_FOLLOWOVER:
1887                 return snprintf(buff, len, "\"followover\"");
1888         default:
1889                 return snprintf(buff, len, "%i", mpe->pgfailback);
1890         }
1891         return 0;
1892 }
1893
1894 static int
1895 snprint_mp_mode(char * buff, int len, void * data)
1896 {
1897         struct mpentry * mpe = (struct mpentry *)data;
1898
1899         if ((mpe->attribute_flags & (1 << ATTR_MODE)) == 0)
1900                 return 0;
1901         return snprintf(buff, len, "0%o", mpe->mode);
1902 }
1903
1904 static int
1905 snprint_mp_uid(char * buff, int len, void * data)
1906 {
1907         struct mpentry * mpe = (struct mpentry *)data;
1908
1909         if ((mpe->attribute_flags & (1 << ATTR_UID)) == 0)
1910                 return 0;
1911         return snprintf(buff, len, "0%o", mpe->uid);
1912 }
1913
1914 static int
1915 snprint_mp_gid(char * buff, int len, void * data)
1916 {
1917         struct mpentry * mpe = (struct mpentry *)data;
1918
1919         if ((mpe->attribute_flags & (1 << ATTR_GID)) == 0)
1920                 return 0;
1921         return snprintf(buff, len, "0%o", mpe->gid);
1922 }
1923
1924 static int
1925 snprint_mp_rr_weight (char * buff, int len, void * data)
1926 {
1927         struct mpentry * mpe = (struct mpentry *)data;
1928
1929         if (!mpe->rr_weight)
1930                 return 0;
1931         if (mpe->rr_weight == RR_WEIGHT_PRIO)
1932                 return snprintf(buff, len, "\"priorities\"");
1933         if (mpe->rr_weight == RR_WEIGHT_NONE)
1934                 return snprintf(buff, len, "\"uniform\"");
1935
1936         return 0;
1937 }
1938
1939 static int
1940 snprint_mp_no_path_retry (char * buff, int len, void * data)
1941 {
1942         struct mpentry * mpe = (struct mpentry *)data;
1943
1944         if (!mpe->no_path_retry)
1945                 return 0;
1946
1947         switch(mpe->no_path_retry) {
1948         case NO_PATH_RETRY_UNDEF:
1949                 break;
1950         case NO_PATH_RETRY_FAIL:
1951                 return snprintf(buff, len, "\"fail\"");
1952         case NO_PATH_RETRY_QUEUE:
1953                 return snprintf(buff, len, "\"queue\"");
1954         default:
1955                 return snprintf(buff, len, "%i",
1956                                 mpe->no_path_retry);
1957         }
1958         return 0;
1959 }
1960
1961 static int
1962 snprint_mp_rr_min_io (char * buff, int len, void * data)
1963 {
1964         struct mpentry * mpe = (struct mpentry *)data;
1965
1966         if (!mpe->minio)
1967                 return 0;
1968
1969         return snprintf(buff, len, "%u", mpe->minio);
1970 }
1971
1972 static int
1973 snprint_mp_rr_min_io_rq (char * buff, int len, void * data)
1974 {
1975         struct mpentry * mpe = (struct mpentry *)data;
1976
1977         if (!mpe->minio_rq)
1978                 return 0;
1979
1980         return snprintf(buff, len, "%u", mpe->minio_rq);
1981 }
1982
1983 static int
1984 snprint_mp_pg_timeout (char * buff, int len, void * data)
1985 {
1986         struct mpentry * mpe = (struct mpentry *)data;
1987
1988         switch (mpe->pg_timeout) {
1989         case PGTIMEOUT_UNDEF:
1990                 break;
1991         case -PGTIMEOUT_NONE:
1992                 return snprintf(buff, len, "\"none\"");
1993         default:
1994                 return snprintf(buff, len, "%i", mpe->pg_timeout);
1995         }
1996         return 0;
1997 }
1998
1999 static int
2000 snprint_mp_features (char * buff, int len, void * data)
2001 {
2002         struct mpentry * mpe = (struct mpentry *)data;
2003
2004         if (!mpe->features)
2005                 return 0;
2006         if (strlen(mpe->features) == strlen(conf->features) &&
2007             !strcmp(mpe->features, conf->features))
2008                 return 0;
2009
2010         return snprintf(buff, len, "\"%s\"", mpe->features);
2011 }
2012
2013 static int
2014 snprint_mp_flush_on_last_del (char * buff, int len, void * data)
2015 {
2016         struct mpentry * mpe = (struct mpentry *)data;
2017
2018         switch (mpe->flush_on_last_del) {
2019         case FLUSH_DISABLED:
2020                 return snprintf(buff, len, "\"no\"");
2021         case FLUSH_ENABLED:
2022                 return snprintf(buff, len, "\"yes\"");
2023         }
2024         return 0;
2025 }
2026
2027 static int
2028 snprint_mp_prio(char * buff, int len, void * data)
2029 {
2030         struct mpentry * mpe = (struct mpentry *)data;
2031
2032         if (!mpe->prio_name)
2033                 return 0;
2034
2035         return snprintf(buff, len, "\"%s\"", mpe->prio_name);
2036 }
2037
2038 static int
2039 snprint_mp_prio_args(char * buff, int len, void * data)
2040 {
2041         struct mpentry * mpe = (struct mpentry *)data;
2042
2043         if (!mpe->prio_args)
2044                 return 0;
2045
2046         return snprintf(buff, len, "\"%s\"", mpe->prio_args);
2047 }
2048
2049 static int
2050 snprint_mp_reservation_key (char * buff, int len, void * data)
2051 {
2052         int i;
2053         unsigned char *keyp;
2054         uint64_t prkey = 0;
2055         struct mpentry * mpe = (struct mpentry *)data;
2056
2057         if (!mpe->reservation_key)
2058                 return 0;
2059         keyp = (unsigned char *)mpe->reservation_key;
2060         for (i = 0; i < 8; i++) {
2061                 if (i > 0)
2062                         prkey <<= 8;
2063                 prkey |= *keyp;
2064                 keyp++;
2065         }
2066
2067         return snprintf(buff, len, "0x%" PRIx64, prkey);
2068 }
2069
2070         static int
2071 snprint_mp_user_friendly_names (char * buff, int len, void * data)
2072 {
2073         struct mpentry * mpe = (struct mpentry *)data;
2074
2075         if (mpe->user_friendly_names == USER_FRIENDLY_NAMES_UNDEF)
2076                 return 0;
2077         else if (mpe->user_friendly_names == USER_FRIENDLY_NAMES_OFF)
2078                 return snprintf(buff, len, "\"no\"");
2079         else
2080                 return snprintf(buff, len, "\"yes\"");
2081 }
2082
2083 static int
2084 snprint_hw_fast_io_fail(char * buff, int len, void * data)
2085 {
2086         struct hwentry * hwe = (struct hwentry *)data;
2087         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
2088                 return 0;
2089         if (hwe->fast_io_fail == conf->fast_io_fail)
2090                 return 0;
2091         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_OFF)
2092                 return snprintf(buff, len, "\"off\"");
2093         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
2094                 return snprintf(buff, len, "0");
2095         return snprintf(buff, len, "%d", hwe->fast_io_fail);
2096 }
2097
2098 static int
2099 snprint_hw_dev_loss(char * buff, int len, void * data)
2100 {
2101         struct hwentry * hwe = (struct hwentry *)data;
2102         if (!hwe->dev_loss)
2103                 return 0;
2104         if (hwe->dev_loss == conf->dev_loss)
2105                 return 0;
2106         if (hwe->dev_loss >= MAX_DEV_LOSS_TMO)
2107                 return snprintf(buff, len, "\"infinity\"");
2108
2109         return snprintf(buff, len, "%u", hwe->dev_loss);
2110 }
2111
2112 static int
2113 snprint_hw_vendor (char * buff, int len, void * data)
2114 {
2115         struct hwentry * hwe = (struct hwentry *)data;
2116
2117         if (!hwe->vendor)
2118                 return 0;
2119
2120         return snprintf(buff, len, "\"%s\"", hwe->vendor);
2121 }
2122
2123 static int
2124 snprint_hw_product (char * buff, int len, void * data)
2125 {
2126         struct hwentry * hwe = (struct hwentry *)data;
2127
2128         if (!hwe->product)
2129                 return 0;
2130
2131         return snprintf(buff, len, "\"%s\"", hwe->product);
2132 }
2133
2134 static int
2135 snprint_hw_revision (char * buff, int len, void * data)
2136 {
2137         struct hwentry * hwe = (struct hwentry *)data;
2138
2139         if (!hwe->revision)
2140                 return 0;
2141
2142         return snprintf(buff, len, "\"%s\"", hwe->revision);
2143 }
2144
2145 static int
2146 snprint_hw_bl_product (char * buff, int len, void * data)
2147 {
2148         struct hwentry * hwe = (struct hwentry *)data;
2149
2150         if (!hwe->bl_product)
2151                 return 0;
2152
2153         return snprintf(buff, len, "\"%s\"", hwe->bl_product);
2154 }
2155
2156 static int
2157 snprint_hw_uid_attribute (char * buff, int len, void * data)
2158 {
2159         struct hwentry * hwe = (struct hwentry *)data;
2160
2161         if (!hwe->uid_attribute)
2162                 return 0;
2163
2164         return snprintf(buff, len, "\"%s\"", hwe->uid_attribute);
2165 }
2166
2167 static int
2168 snprint_hw_prio (char * buff, int len, void * data)
2169 {
2170         struct hwentry * hwe = (struct hwentry *)data;
2171
2172         if (!hwe->prio_name)
2173                 return 0;
2174
2175         return snprintf(buff, len, "\"%s\"", hwe->prio_name);
2176 }
2177
2178 static int
2179 snprint_hw_alias_prefix (char * buff, int len, void * data)
2180 {
2181         struct hwentry * hwe = (struct hwentry *)data;
2182
2183         if (!hwe->alias_prefix)
2184                 return 0;
2185
2186         return snprintf(buff, len, "\"%s\"", hwe->alias_prefix);
2187 }
2188
2189 static int
2190 snprint_hw_prio_args (char * buff, int len, void * data)
2191 {
2192         struct hwentry * hwe = (struct hwentry *)data;
2193
2194         if (!hwe->prio_args)
2195                 return 0;
2196
2197         return snprintf(buff, len, "\"%s\"", hwe->prio_args);
2198 }
2199
2200 static int
2201 snprint_hw_features (char * buff, int len, void * data)
2202 {
2203         struct hwentry * hwe = (struct hwentry *)data;
2204
2205         if (!hwe->features)
2206                 return 0;
2207
2208         return snprintf(buff, len, "\"%s\"", hwe->features);
2209 }
2210
2211 static int
2212 snprint_hw_hardware_handler (char * buff, int len, void * data)
2213 {
2214         struct hwentry * hwe = (struct hwentry *)data;
2215
2216         if (!hwe->hwhandler)
2217                 return 0;
2218
2219         return snprintf(buff, len, "\"%s\"", hwe->hwhandler);
2220 }
2221
2222 static int
2223 snprint_hw_selector (char * buff, int len, void * data)
2224 {
2225         struct hwentry * hwe = (struct hwentry *)data;
2226
2227         if (!hwe->selector)
2228                 return 0;
2229
2230         return snprintf(buff, len, "\"%s\"", hwe->selector);
2231 }
2232
2233 static int
2234 snprint_hw_path_grouping_policy (char * buff, int len, void * data)
2235 {
2236         struct hwentry * hwe = (struct hwentry *)data;
2237
2238         char str[POLICY_NAME_SIZE];
2239
2240         if (!hwe->pgpolicy)
2241                 return 0;
2242
2243         get_pgpolicy_name(str, POLICY_NAME_SIZE, hwe->pgpolicy);
2244
2245         return snprintf(buff, len, "\"%s\"", str);
2246 }
2247
2248 static int
2249 snprint_hw_failback (char * buff, int len, void * data)
2250 {
2251         struct hwentry * hwe = (struct hwentry *)data;
2252
2253         if (!hwe->pgfailback)
2254                 return 0;
2255
2256         switch(hwe->pgfailback) {
2257         case  FAILBACK_UNDEF:
2258                 break;
2259         case -FAILBACK_MANUAL:
2260                 return snprintf(buff, len, "\"manual\"");
2261         case -FAILBACK_IMMEDIATE:
2262                 return snprintf(buff, len, "\"immediate\"");
2263         case -FAILBACK_FOLLOWOVER:
2264                 return snprintf(buff, len, "\"followover\"");
2265         default:
2266                 return snprintf(buff, len, "%i", hwe->pgfailback);
2267         }
2268         return 0;
2269 }
2270
2271 static int
2272 snprint_hw_rr_weight (char * buff, int len, void * data)
2273 {
2274         struct hwentry * hwe = (struct hwentry *)data;
2275
2276         if (!hwe->rr_weight)
2277                 return 0;
2278         if (hwe->rr_weight == RR_WEIGHT_PRIO)
2279                 return snprintf(buff, len, "\"priorities\"");
2280         if (hwe->rr_weight == RR_WEIGHT_NONE)
2281                 return snprintf(buff, len, "\"uniform\"");
2282
2283         return 0;
2284 }
2285
2286 static int
2287 snprint_hw_no_path_retry (char * buff, int len, void * data)
2288 {
2289         struct hwentry * hwe = (struct hwentry *)data;
2290
2291         if (!hwe->no_path_retry)
2292                 return 0;
2293
2294         switch(hwe->no_path_retry) {
2295         case NO_PATH_RETRY_UNDEF:
2296                 break;
2297         case NO_PATH_RETRY_FAIL:
2298                 return snprintf(buff, len, "\"fail\"");
2299         case NO_PATH_RETRY_QUEUE:
2300                 return snprintf(buff, len, "\"queue\"");
2301         default:
2302                 return snprintf(buff, len, "%i",
2303                                 hwe->no_path_retry);
2304         }
2305         return 0;
2306 }
2307
2308 static int
2309 snprint_hw_rr_min_io (char * buff, int len, void * data)
2310 {
2311         struct hwentry * hwe = (struct hwentry *)data;
2312
2313         if (!hwe->minio)
2314                 return 0;
2315
2316         return snprintf(buff, len, "%u", hwe->minio);
2317 }
2318
2319 static int
2320 snprint_hw_rr_min_io_rq (char * buff, int len, void * data)
2321 {
2322         struct hwentry * hwe = (struct hwentry *)data;
2323
2324         if (!hwe->minio_rq)
2325                 return 0;
2326
2327         return snprintf(buff, len, "%u", hwe->minio_rq);
2328 }
2329
2330 static int
2331 snprint_hw_pg_timeout (char * buff, int len, void * data)
2332 {
2333         struct hwentry * hwe = (struct hwentry *)data;
2334
2335         if (!hwe->pg_timeout)
2336                 return 0;
2337
2338         switch (hwe->pg_timeout) {
2339         case PGTIMEOUT_UNDEF:
2340                 break;
2341         case -PGTIMEOUT_NONE:
2342                 return snprintf(buff, len, "\"none\"");
2343         default:
2344                 return snprintf(buff, len, "%i", hwe->pg_timeout);
2345         }
2346         return 0;
2347 }
2348
2349 static int
2350 snprint_hw_flush_on_last_del (char * buff, int len, void * data)
2351 {
2352         struct hwentry * hwe = (struct hwentry *)data;
2353
2354         switch (hwe->flush_on_last_del) {
2355         case FLUSH_DISABLED:
2356                 return snprintf(buff, len, "\"no\"");
2357         case FLUSH_ENABLED:
2358                 return snprintf(buff, len, "\"yes\"");
2359         }
2360         return 0;
2361 }
2362
2363 static int
2364 snprint_hw_path_checker (char * buff, int len, void * data)
2365 {
2366         struct hwentry * hwe = (struct hwentry *)data;
2367
2368         if (!hwe->checker_name)
2369                 return 0;
2370
2371         return snprintf(buff, len, "\"%s\"", hwe->checker_name);
2372 }
2373
2374         static int
2375 snprint_hw_user_friendly_names (char * buff, int len, void * data)
2376 {
2377         struct hwentry * hwe = (struct hwentry *)data;
2378
2379         if (hwe->user_friendly_names == USER_FRIENDLY_NAMES_UNDEF)
2380                 return 0;
2381         else if (hwe->user_friendly_names == USER_FRIENDLY_NAMES_OFF)
2382                 return snprintf(buff, len, "\"no\"");
2383         else
2384                 return snprintf(buff, len, "\"yes\"");
2385 }
2386
2387 static int
2388 snprint_hw_retain_hwhandler_handler(char * buff, int len, void * data)
2389 {
2390         struct hwentry * hwe = (struct hwentry *)data;
2391
2392         if (hwe->retain_hwhandler == RETAIN_HWHANDLER_ON)
2393                 return snprintf(buff, len, "\"yes\"");
2394         else if (hwe->retain_hwhandler == RETAIN_HWHANDLER_OFF)
2395                 return snprintf(buff, len, "\"no\"");
2396         else
2397                 return 0;
2398 }
2399
2400 static int
2401 snprint_detect_prio(char * buff, int len, void * data)
2402 {
2403         struct hwentry * hwe = (struct hwentry *)data;
2404
2405         if (hwe->detect_prio == DETECT_PRIO_ON)
2406                 return snprintf(buff, len, "\"yes\"");
2407         else if (hwe->detect_prio == DETECT_PRIO_OFF)
2408                 return snprintf(buff, len, "\"no\"");
2409         else
2410                 return 0;
2411 }
2412
2413 static int
2414 snprint_def_polling_interval (char * buff, int len, void * data)
2415 {
2416         return snprintf(buff, len, "%i", conf->checkint);
2417 }
2418
2419 static int
2420 snprint_def_fast_io_fail(char * buff, int len, void * data)
2421 {
2422         if (conf->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
2423                 return 0;
2424         if (conf->fast_io_fail == MP_FAST_IO_FAIL_OFF)
2425                 return snprintf(buff, len, "\"off\"");
2426         if (conf->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
2427                 return snprintf(buff, len, "0");
2428         return snprintf(buff, len, "%d", conf->fast_io_fail);
2429 }
2430
2431 static int
2432 snprint_def_dev_loss(char * buff, int len, void * data)
2433 {
2434         if (!conf->dev_loss)
2435                 return 0;
2436         if (conf->dev_loss >= MAX_DEV_LOSS_TMO)
2437                 return snprintf(buff, len, "\"infinity\"");
2438         return snprintf(buff, len, "%u", conf->dev_loss);
2439 }
2440
2441 static int
2442 snprint_def_verbosity (char * buff, int len, void * data)
2443 {
2444         return snprintf(buff, len, "%i", conf->verbosity);
2445 }
2446
2447 static int
2448 snprint_def_max_polling_interval (char * buff, int len, void * data)
2449 {
2450         if (conf->max_checkint == MAX_CHECKINT(conf->checkint))
2451                 return 0;
2452         return snprintf(buff, len, "%i", conf->max_checkint);
2453 }
2454
2455 static int
2456 snprint_reassign_maps (char * buff, int len, void * data)
2457 {
2458         if (conf->reassign_maps == DEFAULT_REASSIGN_MAPS)
2459                 return 0;
2460         return snprintf(buff, len, "\"%s\"",
2461                         conf->reassign_maps?"yes":"no");
2462 }
2463
2464 static int
2465 snprint_def_multipath_dir (char * buff, int len, void * data)
2466 {
2467         if (!conf->multipath_dir)
2468                 return 0;
2469
2470         return snprintf(buff, len, "\"%s\"", conf->multipath_dir);
2471 }
2472
2473 static int
2474 snprint_def_selector (char * buff, int len, void * data)
2475 {
2476         if (!conf->selector)
2477                 return snprintf(buff, len, "\"%s\"", DEFAULT_SELECTOR);
2478
2479         return snprintf(buff, len, "\"%s\"", conf->selector);
2480 }
2481
2482 static int
2483 snprint_def_path_grouping_policy (char * buff, int len, void * data)
2484 {
2485         char str[POLICY_NAME_SIZE];
2486         int pgpolicy = conf->pgpolicy;
2487
2488         if (!pgpolicy)
2489                 pgpolicy = DEFAULT_PGPOLICY;
2490
2491         get_pgpolicy_name(str, POLICY_NAME_SIZE, pgpolicy);
2492
2493         return snprintf(buff, len, "\"%s\"", str);
2494 }
2495
2496 static int
2497 snprint_def_uid_attribute (char * buff, int len, void * data)
2498 {
2499         if (!conf->uid_attribute)
2500                 return snprintf(buff, len, "\"%s\"", DEFAULT_UID_ATTRIBUTE);
2501
2502         return snprintf(buff, len, "\"%s\"", conf->uid_attribute);
2503 }
2504
2505 static int
2506 snprint_def_prio (char * buff, int len, void * data)
2507 {
2508         if (!conf->prio_name)
2509                 return snprintf(buff, len, "\"%s\"", DEFAULT_PRIO);
2510
2511         return snprintf(buff, len, "\"%s\"", conf->prio_name);
2512 }
2513
2514 static int
2515 snprint_def_prio_args (char * buff, int len, void * data)
2516 {
2517         if (!conf->prio_args)
2518                 return snprintf(buff, len, "\"%s\"", DEFAULT_PRIO_ARGS);
2519
2520         return snprintf(buff, len, "\"%s\"", conf->prio_args);
2521 }
2522
2523 static int
2524 snprint_def_features (char * buff, int len, void * data)
2525 {
2526         if (!conf->features)
2527                 return snprintf(buff, len, "\"%s\"", DEFAULT_FEATURES);
2528
2529         return snprintf(buff, len, "\"%s\"", conf->features);
2530 }
2531
2532 static int
2533 snprint_def_path_checker (char * buff, int len, void * data)
2534 {
2535         if (!conf->checker_name)
2536                 return snprintf(buff, len, "\"%s\"", DEFAULT_CHECKER);
2537
2538         return snprintf(buff, len, "\"%s\"", conf->checker_name);
2539 }
2540
2541 static int
2542 snprint_def_failback (char * buff, int len, void * data)
2543 {
2544         int pgfailback = conf->pgfailback;
2545         if (!pgfailback)
2546                 pgfailback = DEFAULT_FAILBACK;
2547
2548         switch(conf->pgfailback) {
2549         case  FAILBACK_UNDEF:
2550                 break;
2551         case -FAILBACK_MANUAL:
2552                 return snprintf(buff, len, "\"manual\"");
2553         case -FAILBACK_IMMEDIATE:
2554                 return snprintf(buff, len, "\"immediate\"");
2555         case -FAILBACK_FOLLOWOVER:
2556                 return snprintf(buff, len, "\"followover\"");
2557         default:
2558                 return snprintf(buff, len, "%i", conf->pgfailback);
2559         }
2560         return 0;
2561 }
2562
2563 static int
2564 snprint_def_rr_min_io (char * buff, int len, void * data)
2565 {
2566         if (!conf->minio)
2567                 return 0;
2568
2569         return snprintf(buff, len, "%u", conf->minio);
2570 }
2571
2572 static int
2573 snprint_def_rr_min_io_rq (char * buff, int len, void * data)
2574 {
2575         if (!conf->minio_rq)
2576                 return 0;
2577
2578         return snprintf(buff, len, "%u", conf->minio_rq);
2579 }
2580
2581 static int
2582 snprint_max_fds (char * buff, int len, void * data)
2583 {
2584         if (!conf->max_fds)
2585                 return 0;
2586
2587         return snprintf(buff, len, "%d", conf->max_fds);
2588 }
2589
2590 static int
2591 snprint_def_mode(char * buff, int len, void * data)
2592 {
2593         if ((conf->attribute_flags & (1 << ATTR_MODE)) == 0)
2594                 return 0;
2595         return snprintf(buff, len, "0%o", conf->mode);
2596 }
2597
2598 static int
2599 snprint_def_uid(char * buff, int len, void * data)
2600 {
2601         if ((conf->attribute_flags & (1 << ATTR_UID)) == 0)
2602                 return 0;
2603         return snprintf(buff, len, "0%o", conf->uid);
2604 }
2605
2606 static int
2607 snprint_def_gid(char * buff, int len, void * data)
2608 {
2609         if ((conf->attribute_flags & (1 << ATTR_GID)) == 0)
2610                 return 0;
2611         return snprintf(buff, len, "0%o", conf->gid);
2612 }
2613
2614 static int
2615 snprint_def_rr_weight (char * buff, int len, void * data)
2616 {
2617         if (!conf->rr_weight || conf->rr_weight == RR_WEIGHT_NONE)
2618                 return snprintf(buff, len, "\"uniform\"");
2619         if (conf->rr_weight == RR_WEIGHT_PRIO)
2620                 return snprintf(buff, len, "\"priorities\"");
2621
2622         return 0;
2623 }
2624
2625 static int
2626 snprint_def_no_path_retry (char * buff, int len, void * data)
2627 {
2628         switch(conf->no_path_retry) {
2629         case NO_PATH_RETRY_UNDEF:
2630                 break;
2631         case NO_PATH_RETRY_FAIL:
2632                 return snprintf(buff, len, "\"fail\"");
2633         case NO_PATH_RETRY_QUEUE:
2634                 return snprintf(buff, len, "\"queue\"");
2635         default:
2636                 return snprintf(buff, len, "%i",
2637                                 conf->no_path_retry);
2638         }
2639         return 0;
2640 }
2641
2642 static int
2643 snprint_def_queue_without_daemon (char * buff, int len, void * data)
2644 {
2645         switch (conf->queue_without_daemon) {
2646         case QUE_NO_DAEMON_OFF:
2647                 return snprintf(buff, len, "\"no\"");
2648         case QUE_NO_DAEMON_ON:
2649                 return snprintf(buff, len, "\"yes\"");
2650         case QUE_NO_DAEMON_FORCE:
2651                 return snprintf(buff, len, "\"forced\"");
2652         }
2653         return 0;
2654 }
2655
2656 static int
2657 snprint_def_checker_timeout (char *buff, int len, void *data)
2658 {
2659         if (!conf->checker_timeout)
2660                 return 0;
2661
2662         return snprintf(buff, len, "%u", conf->checker_timeout);
2663 }
2664
2665 static int
2666 snprint_def_pg_timeout (char * buff, int len, void * data)
2667 {
2668         switch (conf->pg_timeout) {
2669         case PGTIMEOUT_UNDEF:
2670         case -PGTIMEOUT_NONE:
2671                 return snprintf(buff, len, "\"none\"");
2672         default:
2673                 return snprintf(buff, len, "%i", conf->pg_timeout);
2674         }
2675         return 0;
2676 }
2677
2678 static int
2679 snprint_def_flush_on_last_del (char * buff, int len, void * data)
2680 {
2681         switch (conf->flush_on_last_del) {
2682         case FLUSH_UNDEF:
2683         case FLUSH_DISABLED:
2684                 return snprintf(buff, len, "\"no\"");
2685         case FLUSH_ENABLED:
2686         case FLUSH_IN_PROGRESS:
2687                 return snprintf(buff, len, "\"yes\"");
2688         }
2689         return 0;
2690 }
2691
2692 static int
2693 snprint_def_log_checker_err (char * buff, int len, void * data)
2694 {
2695         if (conf->log_checker_err == LOG_CHKR_ERR_ONCE)
2696                 return snprintf(buff, len, "once");
2697         return snprintf(buff, len, "always");
2698 }
2699
2700 static int
2701 snprint_def_user_friendly_names (char * buff, int len, void * data)
2702 {
2703         if (conf->user_friendly_names  == USER_FRIENDLY_NAMES_ON)
2704                 return snprintf(buff, len, "\"yes\"");
2705         else
2706                 return snprintf(buff, len, "\"no\"");
2707 }
2708
2709 static int
2710 snprint_def_alias_prefix (char * buff, int len, void * data)
2711 {
2712         if (!conf->alias_prefix)
2713                 return snprintf(buff, len, "\"%s\"", DEFAULT_ALIAS_PREFIX);
2714         return snprintf(buff, len, "\"%s\"", conf->alias_prefix);
2715 }
2716
2717 static int
2718 snprint_def_bindings_file (char * buff, int len, void * data)
2719 {
2720         if (conf->bindings_file == NULL)
2721                 return 0;
2722         return snprintf(buff, len, "\"%s\"", conf->bindings_file);
2723 }
2724
2725 static int
2726 snprint_def_wwids_file (char * buff, int len, void * data)
2727 {
2728         if (conf->wwids_file == NULL)
2729                 return 0;
2730         return snprintf(buff, len, "%s", conf->wwids_file);
2731 }
2732
2733 static int
2734 snprint_def_reservation_key(char * buff, int len, void * data)
2735 {
2736         int i;
2737         unsigned char *keyp;
2738         uint64_t prkey = 0;
2739
2740         if (!conf->reservation_key)
2741                 return 0;
2742         keyp = (unsigned char *)conf->reservation_key;
2743         for (i = 0; i < 8; i++) {
2744                 if (i > 0)
2745                         prkey <<= 8;
2746                 prkey |= *keyp;
2747                 keyp++;
2748         }
2749         return snprintf(buff, len, "0x%" PRIx64, prkey);
2750 }
2751
2752 static int
2753 snprint_def_retain_hwhandler_handler(char * buff, int len, void * data)
2754 {
2755         if (conf->retain_hwhandler == RETAIN_HWHANDLER_ON)
2756                 return snprintf(buff, len, "yes");
2757         else
2758                 return snprintf(buff, len, "no");
2759 }
2760
2761 static int
2762 snprint_def_detect_prio(char * buff, int len, void * data)
2763 {
2764         if (conf->detect_prio == DETECT_PRIO_ON)
2765                 return snprintf(buff, len, "yes");
2766         else
2767                 return snprintf(buff, len, "no");
2768 }
2769
2770 static int
2771 snprint_ble_simple (char * buff, int len, void * data)
2772 {
2773         struct blentry * ble = (struct blentry *)data;
2774
2775         return snprintf(buff, len, "\"%s\"", ble->str);
2776 }
2777
2778 static int
2779 snprint_bled_vendor (char * buff, int len, void * data)
2780 {
2781         struct blentry_device * bled = (struct blentry_device *)data;
2782
2783         return snprintf(buff, len, "\"%s\"", bled->vendor);
2784 }
2785
2786 static int
2787 snprint_bled_product (char * buff, int len, void * data)
2788 {
2789         struct blentry_device * bled = (struct blentry_device *)data;
2790
2791         return snprintf(buff, len, "\"%s\"", bled->product);
2792 }
2793
2794 #define __deprecated
2795
2796 void
2797 init_keywords(void)
2798 {
2799         install_keyword_root("defaults", NULL);
2800         install_keyword("verbosity", &verbosity_handler, &snprint_def_verbosity);
2801         install_keyword("polling_interval", &polling_interval_handler, &snprint_def_polling_interval);
2802         install_keyword("max_polling_interval", &max_polling_interval_handler, &snprint_def_max_polling_interval);
2803         install_keyword("reassign_maps", &reassign_maps_handler, &snprint_reassign_maps);
2804         install_keyword("multipath_dir", &multipath_dir_handler, &snprint_def_multipath_dir);
2805         install_keyword("path_selector", &def_selector_handler, &snprint_def_selector);
2806         install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_path_grouping_policy);
2807         install_keyword("uid_attribute", &def_uid_attribute_handler, &snprint_def_uid_attribute);
2808         install_keyword("prio", &def_prio_handler, &snprint_def_prio);
2809         install_keyword("prio_args", &def_prio_args_handler, &snprint_def_prio_args);
2810         install_keyword("features", &def_features_handler, &snprint_def_features);
2811         install_keyword("path_checker", &def_path_checker_handler, &snprint_def_path_checker);
2812         install_keyword("checker", &def_path_checker_handler, NULL);
2813         install_keyword("alias_prefix", &def_alias_prefix_handler, &snprint_def_alias_prefix);
2814         install_keyword("failback", &default_failback_handler, &snprint_def_failback);
2815         install_keyword("rr_min_io", &def_minio_handler, &snprint_def_rr_min_io);
2816         install_keyword("rr_min_io_rq", &def_minio_rq_handler, &snprint_def_rr_min_io_rq);
2817         install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
2818         install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
2819         install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
2820         install_keyword("queue_without_daemon", &def_queue_without_daemon, &snprint_def_queue_without_daemon);
2821         install_keyword("checker_timeout", &def_checker_timeout_handler, &snprint_def_checker_timeout);
2822         install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
2823         install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
2824         install_keyword("user_friendly_names", &def_names_handler, &snprint_def_user_friendly_names);
2825         install_keyword("mode", &def_mode_handler, &snprint_def_mode);
2826         install_keyword("uid", &def_uid_handler, &snprint_def_uid);
2827         install_keyword("gid", &def_gid_handler, &snprint_def_gid);
2828         install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
2829         install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
2830         install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
2831         install_keyword("wwids_file", &wwids_file_handler, &snprint_def_wwids_file);
2832         install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
2833         install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
2834         install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
2835         install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
2836         __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
2837         __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
2838         __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
2839         __deprecated install_keyword("default_features", &def_features_handler, NULL);
2840         __deprecated install_keyword("default_path_checker", &def_path_checker_handler, NULL);
2841
2842         install_keyword_root("blacklist", &blacklist_handler);
2843         install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple);
2844         install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple);
2845         install_keyword_multi("device", &ble_device_handler, NULL);
2846         install_sublevel();
2847         install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
2848         install_keyword("product", &ble_product_handler, &snprint_bled_product);
2849         install_sublevel_end();
2850         install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
2851         install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
2852         install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
2853         install_keyword_multi("device", &ble_except_device_handler, NULL);
2854         install_sublevel();
2855         install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor);
2856         install_keyword("product", &ble_except_product_handler, &snprint_bled_product);
2857         install_sublevel_end();
2858
2859 #if 0
2860         __deprecated install_keyword_root("devnode_blacklist", &blacklist_handler);
2861         __deprecated install_keyword("devnode", &ble_devnode_handler, &snprint_ble_simple);
2862         __deprecated install_keyword("wwid", &ble_wwid_handler, &snprint_ble_simple);
2863         __deprecated install_keyword("device", &ble_device_handler, NULL);
2864         __deprecated install_sublevel();
2865         __deprecated install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
2866         __deprecated install_keyword("product", &ble_product_handler, &snprint_bled_product);
2867         __deprecated install_sublevel_end();
2868 #endif
2869
2870         install_keyword_root("devices", &devices_handler);
2871         install_keyword_multi("device", &device_handler, NULL);
2872         install_sublevel();
2873         install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
2874         install_keyword("product", &product_handler, &snprint_hw_product);
2875         install_keyword("revision", &revision_handler, &snprint_hw_revision);
2876         install_keyword("product_blacklist", &bl_product_handler, &snprint_hw_bl_product);
2877         install_keyword("path_grouping_policy", &hw_pgpolicy_handler, &snprint_hw_path_grouping_policy);
2878         install_keyword("uid_attribute", &hw_uid_attribute_handler, &snprint_hw_uid_attribute);
2879         install_keyword("path_selector", &hw_selector_handler, &snprint_hw_selector);
2880         install_keyword("path_checker", &hw_path_checker_handler, &snprint_hw_path_checker);
2881         install_keyword("checker", &hw_path_checker_handler, NULL);
2882         install_keyword("alias_prefix", &hw_alias_prefix_handler, &snprint_hw_alias_prefix);
2883         install_keyword("features", &hw_features_handler, &snprint_hw_features);
2884         install_keyword("hardware_handler", &hw_handler_handler, &snprint_hw_hardware_handler);
2885         install_keyword("prio", &hw_prio_handler, &snprint_hw_prio);
2886         install_keyword("prio_args", &hw_prio_args_handler, &snprint_hw_prio_args);
2887         install_keyword("failback", &hw_failback_handler, &snprint_hw_failback);
2888         install_keyword("rr_weight", &hw_weight_handler, &snprint_hw_rr_weight);
2889         install_keyword("no_path_retry", &hw_no_path_retry_handler, &snprint_hw_no_path_retry);
2890         install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io);
2891         install_keyword("rr_min_io_rq", &hw_minio_rq_handler, &snprint_hw_rr_min_io_rq);
2892         install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout);
2893         install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
2894         install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
2895         install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
2896         install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names);
2897         install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
2898         install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
2899         install_sublevel_end();
2900
2901         install_keyword_root("multipaths", &multipaths_handler);
2902         install_keyword_multi("multipath", &multipath_handler, NULL);
2903         install_sublevel();
2904         install_keyword("wwid", &wwid_handler, &snprint_mp_wwid);
2905         install_keyword("alias", &alias_handler, &snprint_mp_alias);
2906         install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_path_grouping_policy);
2907         install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
2908         install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
2909         install_keyword("prio_args", &mp_prio_args_handler, &snprint_mp_prio_args);
2910         install_keyword("failback", &mp_failback_handler, &snprint_mp_failback);
2911         install_keyword("rr_weight", &mp_weight_handler, &snprint_mp_rr_weight);
2912         install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
2913         install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_rr_min_io);
2914         install_keyword("rr_min_io_rq", &mp_minio_rq_handler, &snprint_mp_rr_min_io_rq);
2915         install_keyword("pg_timeout", &mp_pg_timeout_handler, &snprint_mp_pg_timeout);
2916         install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del);
2917         install_keyword("features", &mp_features_handler, &snprint_mp_features);
2918         install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
2919         install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
2920         install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
2921         install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
2922         install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
2923         install_sublevel_end();
2924 }