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