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