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