Add multipath.conf force_sync option
[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 static int
689 def_force_sync_handler(vector strvec)
690 {
691         char * buff;
692
693         buff = set_value(strvec);
694
695         if (!buff)
696                 return 1;
697
698         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
699             (strlen(buff) == 1 && !strcmp(buff, "0")))
700                 conf->force_sync = 0;
701         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
702                  (strlen(buff) == 1 && !strcmp(buff, "1")))
703                 conf->force_sync = 1;
704         else
705                 conf->force_sync = 0;
706
707         FREE(buff);
708         return 0;
709 }
710
711 /*
712  * blacklist block handlers
713  */
714 static int
715 blacklist_handler(vector strvec)
716 {
717         conf->blist_devnode = vector_alloc();
718         conf->blist_wwid = vector_alloc();
719         conf->blist_device = vector_alloc();
720         conf->blist_property = vector_alloc();
721
722         if (!conf->blist_devnode || !conf->blist_wwid ||
723             !conf->blist_device || !conf->blist_property)
724                 return 1;
725
726         return 0;
727 }
728
729 static int
730 blacklist_exceptions_handler(vector strvec)
731 {
732         conf->elist_devnode = vector_alloc();
733         conf->elist_wwid = vector_alloc();
734         conf->elist_device = vector_alloc();
735         conf->elist_property = vector_alloc();
736
737         if (!conf->elist_devnode || !conf->elist_wwid ||
738             !conf->elist_device || !conf->elist_property)
739                 return 1;
740
741         return 0;
742 }
743
744 static int
745 ble_devnode_handler(vector strvec)
746 {
747         char * buff;
748
749         buff = set_value(strvec);
750
751         if (!buff)
752                 return 1;
753
754         return store_ble(conf->blist_devnode, buff, ORIGIN_CONFIG);
755 }
756
757 static int
758 ble_except_devnode_handler(vector strvec)
759 {
760         char * buff;
761
762         buff = set_value(strvec);
763
764         if (!buff)
765                 return 1;
766
767         return store_ble(conf->elist_devnode, buff, ORIGIN_CONFIG);
768 }
769
770 static int
771 ble_wwid_handler(vector strvec)
772 {
773         char * buff;
774
775         buff = set_value(strvec);
776
777         if (!buff)
778                 return 1;
779
780         return store_ble(conf->blist_wwid, buff, ORIGIN_CONFIG);
781 }
782
783 static int
784 ble_except_wwid_handler(vector strvec)
785 {
786         char * buff;
787
788         buff = set_value(strvec);
789
790         if (!buff)
791                 return 1;
792
793         return store_ble(conf->elist_wwid, buff, ORIGIN_CONFIG);
794 }
795
796 static int
797 ble_property_handler(vector strvec)
798 {
799         char * buff;
800
801         buff = set_value(strvec);
802
803         if (!buff)
804                 return 1;
805
806         return store_ble(conf->blist_property, buff, ORIGIN_CONFIG);
807 }
808
809 static int
810 ble_except_property_handler(vector strvec)
811 {
812         char * buff;
813
814         buff = set_value(strvec);
815
816         if (!buff)
817                 return 1;
818
819         return store_ble(conf->elist_property, buff, ORIGIN_CONFIG);
820 }
821
822 static int
823 ble_device_handler(vector strvec)
824 {
825         return alloc_ble_device(conf->blist_device);
826 }
827
828 static int
829 ble_except_device_handler(vector strvec)
830 {
831         return alloc_ble_device(conf->elist_device);
832 }
833
834 static int
835 ble_vendor_handler(vector strvec)
836 {
837         char * buff;
838
839         buff = set_value(strvec);
840
841         if (!buff)
842                 return 1;
843
844         return set_ble_device(conf->blist_device, buff, NULL, ORIGIN_CONFIG);
845 }
846
847 static int
848 ble_except_vendor_handler(vector strvec)
849 {
850         char * buff;
851
852         buff = set_value(strvec);
853
854         if (!buff)
855                 return 1;
856
857         return set_ble_device(conf->elist_device, buff, NULL, ORIGIN_CONFIG);
858 }
859
860 static int
861 ble_product_handler(vector strvec)
862 {
863         char * buff;
864
865         buff = set_value(strvec);
866
867         if (!buff)
868                 return 1;
869
870         return set_ble_device(conf->blist_device, NULL, buff, ORIGIN_CONFIG);
871 }
872
873 static int
874 ble_except_product_handler(vector strvec)
875 {
876         char * buff;
877
878         buff = set_value(strvec);
879
880         if (!buff)
881                 return 1;
882
883         return set_ble_device(conf->elist_device, NULL, buff, ORIGIN_CONFIG);
884 }
885
886 /*
887  * devices block handlers
888  */
889 static int
890 devices_handler(vector strvec)
891 {
892         if (!conf->hwtable)
893                 conf->hwtable = vector_alloc();
894
895         if (!conf->hwtable)
896                 return 1;
897
898         return 0;
899 }
900
901 static int
902 device_handler(vector strvec)
903 {
904         struct hwentry * hwe;
905
906         hwe = alloc_hwe();
907
908         if (!hwe)
909                 return 1;
910
911         if (!vector_alloc_slot(conf->hwtable)) {
912                 free_hwe(hwe);
913                 return 1;
914         }
915         vector_set_slot(conf->hwtable, hwe);
916
917         return 0;
918 }
919
920 static int
921 vendor_handler(vector strvec)
922 {
923         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
924
925         if (!hwe)
926                 return 1;
927
928         hwe->vendor = set_value(strvec);
929
930         if (!hwe->vendor)
931                 return 1;
932
933         return 0;
934 }
935
936 static int
937 product_handler(vector strvec)
938 {
939         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
940
941         if (!hwe)
942                 return 1;
943
944         hwe->product = set_value(strvec);
945
946         if (!hwe->product)
947                 return 1;
948
949         return 0;
950 }
951
952 static int
953 revision_handler(vector strvec)
954 {
955         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
956
957         if (!hwe)
958                 return 1;
959
960         hwe->revision = set_value(strvec);
961
962         if (!hwe->revision)
963                 return 1;
964
965         return 0;
966 }
967
968 static int
969 bl_product_handler(vector strvec)
970 {
971         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
972
973         if (!hwe)
974                 return 1;
975
976         hwe->bl_product = set_value(strvec);
977         if (!hwe->bl_product)
978                 return 1;
979
980         return 0;
981 }
982
983 static int
984 hw_fast_io_fail_handler(vector strvec)
985 {
986         char * buff;
987         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
988
989         buff = set_value(strvec);
990         if (strlen(buff) == 3 && !strcmp(buff, "off"))
991                 hwe->fast_io_fail = MP_FAST_IO_FAIL_OFF;
992         else if (sscanf(buff, "%d", &hwe->fast_io_fail) != 1 ||
993                  hwe->fast_io_fail < MP_FAST_IO_FAIL_ZERO)
994                 hwe->fast_io_fail = MP_FAST_IO_FAIL_UNSET;
995         else if (hwe->fast_io_fail == 0)
996                 hwe->fast_io_fail = MP_FAST_IO_FAIL_ZERO;
997
998         FREE(buff);
999         return 0;
1000 }
1001
1002 static int
1003 hw_dev_loss_handler(vector strvec)
1004 {
1005         char * buff;
1006         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1007
1008         buff = set_value(strvec);
1009         if (!buff)
1010                 return 1;
1011
1012         if (strlen(buff) == 8 && !strcmp(buff, "infinity"))
1013                 hwe->dev_loss = MAX_DEV_LOSS_TMO;
1014         else if (sscanf(buff, "%u", &hwe->dev_loss) != 1)
1015                 hwe->dev_loss = 0;
1016
1017         FREE(buff);
1018         return 0;
1019 }
1020
1021 static int
1022 hw_pgpolicy_handler(vector strvec)
1023 {
1024         char * buff;
1025         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1026
1027         buff = set_value(strvec);
1028
1029         if (!buff)
1030                 return 1;
1031
1032         hwe->pgpolicy = get_pgpolicy_id(buff);
1033         FREE(buff);
1034
1035         return 0;
1036 }
1037
1038 static int
1039 hw_uid_attribute_handler(vector strvec)
1040 {
1041         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1042
1043         hwe->uid_attribute = set_value(strvec);
1044
1045         if (!hwe->uid_attribute)
1046                 return 1;
1047
1048         return 0;
1049 }
1050
1051 static int
1052 hw_getuid_callout_handler(vector strvec)
1053 {
1054         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1055
1056         hwe->getuid = set_value(strvec);
1057
1058         if (!hwe->getuid)
1059                 return 1;
1060
1061         return 0;
1062 }
1063
1064 static int
1065 hw_selector_handler(vector strvec)
1066 {
1067         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1068
1069         if (!hwe)
1070                 return 1;
1071
1072         hwe->selector = set_value(strvec);
1073
1074         if (!hwe->selector)
1075                 return 1;
1076
1077         return 0;
1078 }
1079
1080 static int
1081 hw_path_checker_handler(vector strvec)
1082 {
1083         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1084
1085         if (!hwe)
1086                 return 1;
1087
1088         hwe->checker_name = set_value(strvec);
1089
1090         if (!hwe->checker_name)
1091                 return 1;
1092
1093         return 0;
1094 }
1095
1096 static int
1097 hw_features_handler(vector strvec)
1098 {
1099         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1100
1101         if (!hwe)
1102                 return 1;
1103
1104         hwe->features = set_value(strvec);
1105
1106         if (!hwe->features)
1107                 return 1;
1108
1109         return 0;
1110 }
1111
1112 static int
1113 hw_handler_handler(vector strvec)
1114 {
1115         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1116
1117         if (!hwe)
1118                 return 1;
1119
1120         hwe->hwhandler = set_value(strvec);
1121
1122         if (!hwe->hwhandler)
1123                 return 1;
1124
1125         return 0;
1126 }
1127
1128 static int
1129 hw_prio_handler(vector strvec)
1130 {
1131         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1132
1133         if (!hwe)
1134                 return 1;
1135
1136         hwe->prio_name = set_value(strvec);
1137
1138         if (!hwe->prio_name)
1139                 return 1;
1140
1141         return 0;
1142 }
1143
1144 static int
1145 hw_alias_prefix_handler(vector strvec)
1146 {
1147         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1148
1149         if (!hwe)
1150                 return 1;
1151
1152         hwe->alias_prefix = set_value(strvec);
1153
1154         if (!hwe->alias_prefix)
1155                 return 1;
1156
1157         return 0;
1158 }
1159
1160 static int
1161 hw_prio_args_handler(vector strvec)
1162 {
1163         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1164
1165         if (!hwe)
1166                 return 1;
1167
1168         hwe->prio_args = set_value(strvec);
1169
1170         if (!hwe->prio_args)
1171                 return 1;
1172
1173         return 0;
1174 }
1175
1176 static int
1177 hw_failback_handler(vector strvec)
1178 {
1179         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1180         char * buff;
1181
1182         if (!hwe)
1183                 return 1;
1184
1185         buff = set_value(strvec);
1186
1187         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
1188                 hwe->pgfailback = -FAILBACK_MANUAL;
1189         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
1190                 hwe->pgfailback = -FAILBACK_IMMEDIATE;
1191         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
1192                 hwe->pgfailback = -FAILBACK_FOLLOWOVER;
1193         else
1194                 hwe->pgfailback = atoi(buff);
1195
1196         FREE(buff);
1197
1198         return 0;
1199 }
1200
1201 static int
1202 hw_weight_handler(vector strvec)
1203 {
1204         struct hwentry * hwe = VECTOR_LAST_SLOT(conf->hwtable);
1205         char * buff;
1206
1207         if (!hwe)
1208                 return 1;
1209
1210         buff = set_value(strvec);
1211
1212         if (!buff)
1213                 return 1;
1214
1215         if (strlen(buff) == 10 &&
1216             !strcmp(buff, "priorities"))
1217                 hwe->rr_weight = RR_WEIGHT_PRIO;
1218
1219         if (strlen(buff) == strlen("uniform") &&
1220             !strcmp(buff, "uniform"))
1221                 hwe->rr_weight = RR_WEIGHT_NONE;
1222
1223         FREE(buff);
1224
1225         return 0;
1226 }
1227
1228 static int
1229 hw_no_path_retry_handler(vector strvec)
1230 {
1231         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1232         char *buff;
1233
1234         if (!hwe)
1235                 return 1;
1236
1237         buff = set_value(strvec);
1238         if (!buff)
1239                 return 1;
1240
1241         if ((strlen(buff) == 4 && !strcmp(buff, "fail")) ||
1242             (strlen(buff) == 1 && !strcmp(buff, "0")))
1243                 hwe->no_path_retry = NO_PATH_RETRY_FAIL;
1244         else if (strlen(buff) == 5 && !strcmp(buff, "queue"))
1245                 hwe->no_path_retry = NO_PATH_RETRY_QUEUE;
1246         else if ((hwe->no_path_retry = atoi(buff)) < 1)
1247                 hwe->no_path_retry = NO_PATH_RETRY_UNDEF;
1248
1249         FREE(buff);
1250         return 0;
1251 }
1252
1253 static int
1254 hw_minio_handler(vector strvec)
1255 {
1256         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1257         char * buff;
1258
1259         if (!hwe)
1260                 return 1;
1261
1262         buff = set_value(strvec);
1263
1264         if (!buff)
1265                 return 1;
1266
1267         hwe->minio = atoi(buff);
1268         FREE(buff);
1269
1270         return 0;
1271 }
1272
1273 static int
1274 hw_minio_rq_handler(vector strvec)
1275 {
1276         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1277         char * buff;
1278
1279         if (!hwe)
1280                 return 1;
1281
1282         buff = set_value(strvec);
1283
1284         if (!buff)
1285                 return 1;
1286
1287         hwe->minio_rq = atoi(buff);
1288         FREE(buff);
1289
1290         return 0;
1291 }
1292
1293 static int
1294 hw_pg_timeout_handler(vector strvec)
1295 {
1296         char *buff;
1297
1298         buff = set_value(strvec);
1299
1300         if (!buff)
1301                 return 1;
1302
1303         /* Deprecated; device-mapper support has been removed */
1304
1305         FREE(buff);
1306         return 0;
1307 }
1308
1309 static int
1310 hw_flush_on_last_del_handler(vector strvec)
1311 {
1312         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1313         char * buff;
1314
1315         if (!hwe)
1316                 return 1;
1317
1318         buff = set_value(strvec);
1319         if (!buff)
1320                 return 1;
1321
1322         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1323             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1324                 hwe->flush_on_last_del = FLUSH_DISABLED;
1325         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1326             (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1327                 hwe->flush_on_last_del = FLUSH_ENABLED;
1328         else
1329                 hwe->flush_on_last_del = FLUSH_UNDEF;
1330
1331         FREE(buff);
1332         return 0;
1333 }
1334
1335 static int
1336 hw_names_handler(vector strvec)
1337 {
1338         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1339         char * buff;
1340
1341         if (!hwe)
1342                 return 1;
1343
1344         buff = set_value(strvec);
1345         if (!buff)
1346                 return 1;
1347
1348         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1349             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1350                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_OFF;
1351         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1352                  (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1353                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_ON;
1354         else
1355                 hwe->user_friendly_names = USER_FRIENDLY_NAMES_UNDEF;
1356
1357         FREE(buff);
1358         return 0;
1359 }
1360
1361 static int
1362 hw_retain_hwhandler_handler(vector strvec)
1363 {
1364         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1365         char * buff;
1366
1367         if (!hwe)
1368                 return 1;
1369
1370         buff = set_value(strvec);
1371
1372         if (!buff)
1373                 return 1;
1374
1375         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
1376             (strlen(buff) == 1 && !strcmp(buff, "0")))
1377                 hwe->retain_hwhandler = RETAIN_HWHANDLER_OFF;
1378         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
1379                  (strlen(buff) == 1 && !strcmp(buff, "1")))
1380                 hwe->retain_hwhandler = RETAIN_HWHANDLER_ON;
1381         else
1382                 hwe->user_friendly_names = RETAIN_HWHANDLER_UNDEF;
1383
1384         FREE(buff);
1385         return 0;
1386 }
1387
1388 static int
1389 hw_detect_prio_handler(vector strvec)
1390 {
1391         struct hwentry *hwe = VECTOR_LAST_SLOT(conf->hwtable);
1392         char * buff;
1393
1394         if (!hwe)
1395                 return 1;
1396
1397         buff = set_value(strvec);
1398
1399         if (!buff)
1400                 return 1;
1401
1402         if ((strlen(buff) == 2 && !strcmp(buff, "no")) ||
1403             (strlen(buff) == 1 && !strcmp(buff, "0")))
1404                 hwe->detect_prio = DETECT_PRIO_OFF;
1405         else if ((strlen(buff) == 3 && !strcmp(buff, "yes")) ||
1406                  (strlen(buff) == 1 && !strcmp(buff, "1")))
1407                 hwe->detect_prio = DETECT_PRIO_ON;
1408         else
1409                 hwe->detect_prio = DETECT_PRIO_UNDEF;
1410
1411         FREE(buff);
1412         return 0;
1413 }
1414
1415 /*
1416  * multipaths block handlers
1417  */
1418 static int
1419 multipaths_handler(vector strvec)
1420 {
1421         conf->mptable = vector_alloc();
1422
1423         if (!conf->mptable)
1424                 return 1;
1425
1426         return 0;
1427 }
1428
1429 static int
1430 multipath_handler(vector strvec)
1431 {
1432         struct mpentry * mpe;
1433
1434         mpe = alloc_mpe();
1435
1436         if (!mpe)
1437                 return 1;
1438
1439         if (!vector_alloc_slot(conf->mptable)) {
1440                 free_mpe(mpe);
1441                 return 1;
1442         }
1443         vector_set_slot(conf->mptable, mpe);
1444
1445         return 0;
1446 }
1447
1448 static int
1449 wwid_handler(vector strvec)
1450 {
1451         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1452
1453         if (!mpe)
1454                 return 1;
1455
1456         mpe->wwid = set_value(strvec);
1457
1458         if (!mpe->wwid)
1459                 return 1;
1460
1461         return 0;
1462 }
1463
1464 static int
1465 alias_handler(vector strvec)
1466 {
1467         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1468
1469         if (!mpe)
1470                 return 1;
1471
1472         mpe->alias = set_value(strvec);
1473
1474         if (!mpe->alias)
1475                 return 1;
1476
1477         return 0;
1478 }
1479
1480 static int
1481 mp_pgpolicy_handler(vector strvec)
1482 {
1483         char * buff;
1484         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1485
1486         if (!mpe)
1487                 return 1;
1488
1489         buff = set_value(strvec);
1490
1491         if (!buff)
1492                 return 1;
1493
1494         mpe->pgpolicy = get_pgpolicy_id(buff);
1495         FREE(buff);
1496
1497         return 0;
1498 }
1499
1500 static int
1501 mp_selector_handler(vector strvec)
1502 {
1503         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1504
1505         if (!mpe)
1506                 return 1;
1507
1508         mpe->selector = set_value(strvec);
1509
1510         if (!mpe->selector)
1511                 return 1;
1512
1513         return 0;
1514 }
1515
1516 static int
1517 mp_failback_handler(vector strvec)
1518 {
1519         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1520         char * buff;
1521
1522         if (!mpe)
1523                 return 1;
1524
1525         buff = set_value(strvec);
1526
1527         if (strlen(buff) == 6 && !strcmp(buff, "manual"))
1528                 mpe->pgfailback = -FAILBACK_MANUAL;
1529         else if (strlen(buff) == 9 && !strcmp(buff, "immediate"))
1530                 mpe->pgfailback = -FAILBACK_IMMEDIATE;
1531         else if (strlen(buff) == 10 && !strcmp(buff, "followover"))
1532                 mpe->pgfailback = -FAILBACK_FOLLOWOVER;
1533         else
1534                 mpe->pgfailback = atoi(buff);
1535
1536         FREE(buff);
1537
1538         return 0;
1539 }
1540
1541 static int
1542 mp_mode_handler(vector strvec)
1543 {
1544         mode_t mode;
1545         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1546         char *buff;
1547
1548         if (!mpe)
1549                 return 1;
1550
1551         buff = set_value(strvec);
1552         if (!buff)
1553                 return 1;
1554         if (sscanf(buff, "%o", &mode) == 1 && mode <= 0777) {
1555                 mpe->attribute_flags |= (1 << ATTR_MODE);
1556                 mpe->mode = mode;
1557         }
1558
1559         FREE(buff);
1560         return 0;
1561 }
1562
1563 static int
1564 mp_uid_handler(vector strvec)
1565 {
1566         uid_t uid;
1567         char *buff;
1568         char passwd_buf[1024];
1569         struct passwd info, *found;
1570
1571         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1572
1573         if (!mpe)
1574                 return 1;
1575
1576         buff = set_value(strvec);
1577         if (!buff)
1578                 return 1;
1579
1580         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
1581                 mpe->attribute_flags |= (1 << ATTR_UID);
1582                 mpe->uid = info.pw_uid;
1583         }
1584         else if (sscanf(buff, "%u", &uid) == 1){
1585                 mpe->attribute_flags |= (1 << ATTR_UID);
1586                 mpe->uid = uid;
1587         }
1588         FREE(buff);
1589         return 0;
1590 }
1591
1592 static int
1593 mp_gid_handler(vector strvec)
1594 {
1595         gid_t gid;
1596         char *buff;
1597         char passwd_buf[1024];
1598         struct passwd info, *found;
1599
1600         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1601
1602         if (!mpe)
1603                 return 1;
1604
1605         buff = set_value(strvec);
1606         if (!buff)
1607                 return 1;
1608
1609         if (getpwnam_r(buff, &info, passwd_buf, 1024, &found) == 0 && found) {
1610                 mpe->attribute_flags |= (1 << ATTR_GID);
1611                 mpe->gid = info.pw_gid;
1612         }
1613         else if (sscanf(buff, "%u", &gid) == 1) {
1614                 mpe->attribute_flags |= (1 << ATTR_GID);
1615                 mpe->gid = gid;
1616         }
1617         FREE(buff);
1618         return 0;
1619 }
1620
1621 static int
1622 mp_weight_handler(vector strvec)
1623 {
1624         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1625         char * buff;
1626
1627         if (!mpe)
1628                 return 1;
1629
1630         buff = set_value(strvec);
1631
1632         if (!buff)
1633                 return 1;
1634
1635         if (strlen(buff) == 10 &&
1636             !strcmp(buff, "priorities"))
1637                 mpe->rr_weight = RR_WEIGHT_PRIO;
1638
1639         if (strlen(buff) == strlen("uniform") &&
1640             !strcmp(buff, "uniform"))
1641                 mpe->rr_weight = RR_WEIGHT_NONE;
1642
1643         FREE(buff);
1644
1645         return 0;
1646 }
1647
1648 static int
1649 mp_no_path_retry_handler(vector strvec)
1650 {
1651         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1652         char *buff;
1653
1654         if (!mpe)
1655                 return 1;
1656
1657         buff = set_value(strvec);
1658         if (!buff)
1659                 return 1;
1660
1661         if ((strlen(buff) == 4 && !strcmp(buff, "fail")) ||
1662             (strlen(buff) == 1 && !strcmp(buff, "0")))
1663                 mpe->no_path_retry = NO_PATH_RETRY_FAIL;
1664         else if (strlen(buff) == 5 && !strcmp(buff, "queue"))
1665                 mpe->no_path_retry = NO_PATH_RETRY_QUEUE;
1666         else if ((mpe->no_path_retry = atoi(buff)) < 1)
1667                 mpe->no_path_retry = NO_PATH_RETRY_UNDEF;
1668
1669         FREE(buff);
1670         return 0;
1671 }
1672
1673 static int
1674 mp_minio_handler(vector strvec)
1675 {
1676         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1677         char * buff;
1678
1679         if (!mpe)
1680                 return 1;
1681
1682         buff = set_value(strvec);
1683
1684         if (!buff)
1685                 return 1;
1686
1687         mpe->minio = atoi(buff);
1688         FREE(buff);
1689
1690         return 0;
1691 }
1692
1693 static int
1694 mp_minio_rq_handler(vector strvec)
1695 {
1696         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1697         char * buff;
1698
1699         if (!mpe)
1700                 return 1;
1701
1702         buff = set_value(strvec);
1703
1704         if (!buff)
1705                 return 1;
1706
1707         mpe->minio_rq = atoi(buff);
1708         FREE(buff);
1709
1710         return 0;
1711 }
1712
1713 static int
1714 mp_pg_timeout_handler(vector strvec)
1715 {
1716         char *buff;
1717
1718         buff = set_value(strvec);
1719
1720         if (!buff)
1721                 return 1;
1722
1723         /* Deprecated; device-mapper support has been removed */
1724
1725         FREE(buff);
1726         return 0;
1727 }
1728
1729 static int
1730 mp_features_handler(vector strvec)
1731 {
1732         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1733
1734         if (!mpe)
1735                 return 1;
1736
1737         mpe->features = set_value(strvec);
1738
1739         if (!mpe->features)
1740                 return 1;
1741
1742         return 0;
1743 }
1744
1745 static int
1746 mp_flush_on_last_del_handler(vector strvec)
1747 {
1748         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1749         char * buff;
1750
1751         if (!mpe)
1752                 return 1;
1753
1754         buff = set_value(strvec);
1755         if (!buff)
1756                 return 1;
1757
1758         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1759             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1760                 mpe->flush_on_last_del = FLUSH_DISABLED;
1761         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1762             (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1763                 mpe->flush_on_last_del = FLUSH_ENABLED;
1764         else
1765                 mpe->flush_on_last_del = FLUSH_UNDEF;
1766
1767         FREE(buff);
1768         return 0;
1769 }
1770
1771 static int
1772 mp_prio_handler(vector strvec)
1773 {
1774         struct mpentry * mpe = VECTOR_LAST_SLOT(conf->mptable);
1775
1776         if (!mpe)
1777                 return 1;
1778
1779         mpe->prio_name = set_value(strvec);
1780
1781         if (!mpe->prio_name)
1782                 return 1;
1783
1784         return 0;
1785 }
1786
1787 static int
1788 mp_prio_args_handler (vector strvec)
1789 {
1790         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1791
1792         if (!mpe)
1793                 return 1;
1794
1795         mpe->prio_args = set_value(strvec);
1796         if (!mpe->prio_args)
1797                 return 1;
1798
1799         return 0;
1800 }
1801
1802 static int
1803 mp_reservation_key_handler (vector strvec)
1804 {
1805         char *buff;
1806         char *tbuff;
1807         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1808
1809         int j, k, len;
1810         uint64_t prkey;
1811
1812         if (!mpe)
1813                 return 1;
1814
1815         buff = set_value(strvec);
1816         if (!buff)
1817                 return 1;
1818
1819         tbuff = buff;
1820         if (!memcmp(buff, "0x", 2))
1821                 buff = buff + 2;
1822
1823         len = strlen(buff);
1824
1825         k = strspn(buff, "0123456789aAbBcCdDeEfF");
1826         if (len != k) {
1827                 FREE(tbuff);
1828                 return 1;
1829         }
1830
1831         if (1 != sscanf (buff, "%" SCNx64 "", &prkey))
1832         {
1833                 FREE(tbuff);
1834                 return 1;
1835         }
1836
1837         if (!mpe->reservation_key)
1838                 mpe->reservation_key = (unsigned char *) malloc(8);
1839
1840         memset(mpe->reservation_key, 0, 8);
1841
1842         for (j = 7; j >= 0; --j) {
1843                 mpe->reservation_key[j] = (prkey & 0xff);
1844                 prkey >>= 8;
1845         }
1846
1847         FREE(tbuff);
1848         return 0;
1849 }
1850
1851 static int
1852 mp_names_handler(vector strvec)
1853 {
1854         struct mpentry *mpe = VECTOR_LAST_SLOT(conf->mptable);
1855         char * buff;
1856
1857         if (!mpe)
1858                 return 1;
1859
1860         buff = set_value(strvec);
1861         if (!buff)
1862                 return 1;
1863
1864         if ((strlen(buff) == 2 && strcmp(buff, "no") == 0) ||
1865             (strlen(buff) == 1 && strcmp(buff, "0") == 0))
1866                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_OFF;
1867         else if ((strlen(buff) == 3 && strcmp(buff, "yes") == 0) ||
1868                  (strlen(buff) == 1 && strcmp(buff, "1") == 0))
1869                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_ON;
1870         else
1871                 mpe->user_friendly_names = USER_FRIENDLY_NAMES_UNDEF;
1872
1873         FREE(buff);
1874         return 0;
1875 }
1876
1877 /*
1878  * config file keywords printing
1879  */
1880 static int
1881 snprint_mp_wwid (char * buff, int len, void * data)
1882 {
1883         struct mpentry * mpe = (struct mpentry *)data;
1884
1885         return snprintf(buff, len, "%s", mpe->wwid);
1886 }
1887
1888 static int
1889 snprint_mp_alias (char * buff, int len, void * data)
1890 {
1891         struct mpentry * mpe = (struct mpentry *)data;
1892
1893         if (!mpe->alias)
1894                 return 0;
1895
1896         return snprintf(buff, len, "%s", mpe->alias);
1897 }
1898
1899 static int
1900 snprint_mp_path_grouping_policy (char * buff, int len, void * data)
1901 {
1902         struct mpentry * mpe = (struct mpentry *)data;
1903         char str[POLICY_NAME_SIZE];
1904
1905         if (!mpe->pgpolicy)
1906                 return 0;
1907         get_pgpolicy_name(str, POLICY_NAME_SIZE, mpe->pgpolicy);
1908
1909         return snprintf(buff, len, "\"%s\"", str);
1910 }
1911
1912 static int
1913 snprint_mp_selector (char * buff, int len, void * data)
1914 {
1915         struct mpentry * mpe = (struct mpentry *)data;
1916
1917         if (!mpe->selector)
1918                 return 0;
1919
1920         return snprintf(buff, len, "\"%s\"", mpe->selector);
1921 }
1922
1923 static int
1924 snprint_mp_failback (char * buff, int len, void * data)
1925 {
1926         struct mpentry * mpe = (struct mpentry *)data;
1927
1928         if (mpe->pgfailback == FAILBACK_UNDEF ||
1929             mpe->pgfailback == DEFAULT_FAILBACK)
1930                 return 0;
1931
1932         switch(mpe->pgfailback) {
1933         case -FAILBACK_MANUAL:
1934                 return snprintf(buff, len, "\"manual\"");
1935         case -FAILBACK_IMMEDIATE:
1936                 return snprintf(buff, len, "\"immediate\"");
1937         case -FAILBACK_FOLLOWOVER:
1938                 return snprintf(buff, len, "\"followover\"");
1939         default:
1940                 return snprintf(buff, len, "%i", mpe->pgfailback);
1941         }
1942         return 0;
1943 }
1944
1945 static int
1946 snprint_mp_mode(char * buff, int len, void * data)
1947 {
1948         struct mpentry * mpe = (struct mpentry *)data;
1949
1950         if ((mpe->attribute_flags & (1 << ATTR_MODE)) == 0)
1951                 return 0;
1952         return snprintf(buff, len, "0%o", mpe->mode);
1953 }
1954
1955 static int
1956 snprint_mp_uid(char * buff, int len, void * data)
1957 {
1958         struct mpentry * mpe = (struct mpentry *)data;
1959
1960         if ((mpe->attribute_flags & (1 << ATTR_UID)) == 0)
1961                 return 0;
1962         return snprintf(buff, len, "0%o", mpe->uid);
1963 }
1964
1965 static int
1966 snprint_mp_gid(char * buff, int len, void * data)
1967 {
1968         struct mpentry * mpe = (struct mpentry *)data;
1969
1970         if ((mpe->attribute_flags & (1 << ATTR_GID)) == 0)
1971                 return 0;
1972         return snprintf(buff, len, "0%o", mpe->gid);
1973 }
1974
1975 static int
1976 snprint_mp_rr_weight (char * buff, int len, void * data)
1977 {
1978         struct mpentry * mpe = (struct mpentry *)data;
1979
1980         if (!mpe->rr_weight)
1981                 return 0;
1982         if (mpe->rr_weight == RR_WEIGHT_PRIO)
1983                 return snprintf(buff, len, "\"priorities\"");
1984         if (mpe->rr_weight == RR_WEIGHT_NONE)
1985                 return snprintf(buff, len, "\"uniform\"");
1986
1987         return 0;
1988 }
1989
1990 static int
1991 snprint_mp_no_path_retry (char * buff, int len, void * data)
1992 {
1993         struct mpentry * mpe = (struct mpentry *)data;
1994
1995         if (!mpe->no_path_retry)
1996                 return 0;
1997
1998         switch(mpe->no_path_retry) {
1999         case NO_PATH_RETRY_UNDEF:
2000                 break;
2001         case NO_PATH_RETRY_FAIL:
2002                 return snprintf(buff, len, "\"fail\"");
2003         case NO_PATH_RETRY_QUEUE:
2004                 return snprintf(buff, len, "\"queue\"");
2005         default:
2006                 return snprintf(buff, len, "%i",
2007                                 mpe->no_path_retry);
2008         }
2009         return 0;
2010 }
2011
2012 static int
2013 snprint_mp_rr_min_io (char * buff, int len, void * data)
2014 {
2015         struct mpentry * mpe = (struct mpentry *)data;
2016
2017         if (!mpe->minio)
2018                 return 0;
2019
2020         return snprintf(buff, len, "%u", mpe->minio);
2021 }
2022
2023 static int
2024 snprint_mp_rr_min_io_rq (char * buff, int len, void * data)
2025 {
2026         struct mpentry * mpe = (struct mpentry *)data;
2027
2028         if (!mpe->minio_rq)
2029                 return 0;
2030
2031         return snprintf(buff, len, "%u", mpe->minio_rq);
2032 }
2033
2034 static int
2035 snprint_mp_pg_timeout (char * buff, int len, void * data)
2036 {
2037         return 0;
2038 }
2039
2040 static int
2041 snprint_mp_features (char * buff, int len, void * data)
2042 {
2043         struct mpentry * mpe = (struct mpentry *)data;
2044
2045         if (!mpe->features)
2046                 return 0;
2047         if (strlen(mpe->features) == strlen(conf->features) &&
2048             !strcmp(mpe->features, conf->features))
2049                 return 0;
2050
2051         return snprintf(buff, len, "\"%s\"", mpe->features);
2052 }
2053
2054 static int
2055 snprint_mp_flush_on_last_del (char * buff, int len, void * data)
2056 {
2057         struct mpentry * mpe = (struct mpentry *)data;
2058
2059         switch (mpe->flush_on_last_del) {
2060         case FLUSH_DISABLED:
2061                 return snprintf(buff, len, "\"no\"");
2062         case FLUSH_ENABLED:
2063                 return snprintf(buff, len, "\"yes\"");
2064         }
2065         return 0;
2066 }
2067
2068 static int
2069 snprint_mp_prio(char * buff, int len, void * data)
2070 {
2071         struct mpentry * mpe = (struct mpentry *)data;
2072
2073         if (!mpe->prio_name)
2074                 return 0;
2075
2076         return snprintf(buff, len, "\"%s\"", mpe->prio_name);
2077 }
2078
2079 static int
2080 snprint_mp_prio_args(char * buff, int len, void * data)
2081 {
2082         struct mpentry * mpe = (struct mpentry *)data;
2083
2084         if (!mpe->prio_args)
2085                 return 0;
2086
2087         return snprintf(buff, len, "\"%s\"", mpe->prio_args);
2088 }
2089
2090 static int
2091 snprint_mp_reservation_key (char * buff, int len, void * data)
2092 {
2093         int i;
2094         unsigned char *keyp;
2095         uint64_t prkey = 0;
2096         struct mpentry * mpe = (struct mpentry *)data;
2097
2098         if (!mpe->reservation_key)
2099                 return 0;
2100         keyp = (unsigned char *)mpe->reservation_key;
2101         for (i = 0; i < 8; i++) {
2102                 if (i > 0)
2103                         prkey <<= 8;
2104                 prkey |= *keyp;
2105                 keyp++;
2106         }
2107
2108         return snprintf(buff, len, "0x%" PRIx64, prkey);
2109 }
2110
2111         static int
2112 snprint_mp_user_friendly_names (char * buff, int len, void * data)
2113 {
2114         struct mpentry * mpe = (struct mpentry *)data;
2115
2116         if (mpe->user_friendly_names == USER_FRIENDLY_NAMES_UNDEF)
2117                 return 0;
2118         else if (mpe->user_friendly_names == USER_FRIENDLY_NAMES_OFF)
2119                 return snprintf(buff, len, "\"no\"");
2120         else
2121                 return snprintf(buff, len, "\"yes\"");
2122 }
2123
2124 static int
2125 snprint_hw_fast_io_fail(char * buff, int len, void * data)
2126 {
2127         struct hwentry * hwe = (struct hwentry *)data;
2128         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
2129                 return 0;
2130         if (hwe->fast_io_fail == conf->fast_io_fail)
2131                 return 0;
2132         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_OFF)
2133                 return snprintf(buff, len, "\"off\"");
2134         if (hwe->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
2135                 return snprintf(buff, len, "0");
2136         return snprintf(buff, len, "%d", hwe->fast_io_fail);
2137 }
2138
2139 static int
2140 snprint_hw_dev_loss(char * buff, int len, void * data)
2141 {
2142         struct hwentry * hwe = (struct hwentry *)data;
2143         if (!hwe->dev_loss)
2144                 return 0;
2145         if (hwe->dev_loss == conf->dev_loss)
2146                 return 0;
2147         if (hwe->dev_loss >= MAX_DEV_LOSS_TMO)
2148                 return snprintf(buff, len, "\"infinity\"");
2149
2150         return snprintf(buff, len, "%u", hwe->dev_loss);
2151 }
2152
2153 static int
2154 snprint_hw_vendor (char * buff, int len, void * data)
2155 {
2156         struct hwentry * hwe = (struct hwentry *)data;
2157
2158         if (!hwe->vendor)
2159                 return 0;
2160
2161         return snprintf(buff, len, "\"%s\"", hwe->vendor);
2162 }
2163
2164 static int
2165 snprint_hw_product (char * buff, int len, void * data)
2166 {
2167         struct hwentry * hwe = (struct hwentry *)data;
2168
2169         if (!hwe->product)
2170                 return 0;
2171
2172         return snprintf(buff, len, "\"%s\"", hwe->product);
2173 }
2174
2175 static int
2176 snprint_hw_revision (char * buff, int len, void * data)
2177 {
2178         struct hwentry * hwe = (struct hwentry *)data;
2179
2180         if (!hwe->revision)
2181                 return 0;
2182
2183         return snprintf(buff, len, "\"%s\"", hwe->revision);
2184 }
2185
2186 static int
2187 snprint_hw_bl_product (char * buff, int len, void * data)
2188 {
2189         struct hwentry * hwe = (struct hwentry *)data;
2190
2191         if (!hwe->bl_product)
2192                 return 0;
2193
2194         return snprintf(buff, len, "\"%s\"", hwe->bl_product);
2195 }
2196
2197 static int
2198 snprint_hw_uid_attribute (char * buff, int len, void * data)
2199 {
2200         struct hwentry * hwe = (struct hwentry *)data;
2201
2202         if (!hwe->uid_attribute)
2203                 return 0;
2204
2205         return snprintf(buff, len, "\"%s\"", hwe->uid_attribute);
2206 }
2207
2208 static int
2209 snprint_hw_getuid_callout (char * buff, int len, void * data)
2210 {
2211         struct hwentry * hwe = (struct hwentry *)data;
2212
2213         if (!hwe->getuid)
2214                 return 0;
2215
2216         return snprintf(buff, len, "\"%s\"", hwe->getuid);
2217 }
2218
2219 static int
2220 snprint_hw_prio (char * buff, int len, void * data)
2221 {
2222         struct hwentry * hwe = (struct hwentry *)data;
2223
2224         if (!hwe->prio_name)
2225                 return 0;
2226
2227         return snprintf(buff, len, "\"%s\"", hwe->prio_name);
2228 }
2229
2230 static int
2231 snprint_hw_alias_prefix (char * buff, int len, void * data)
2232 {
2233         struct hwentry * hwe = (struct hwentry *)data;
2234
2235         if (!hwe->alias_prefix)
2236                 return 0;
2237
2238         return snprintf(buff, len, "\"%s\"", hwe->alias_prefix);
2239 }
2240
2241 static int
2242 snprint_hw_prio_args (char * buff, int len, void * data)
2243 {
2244         struct hwentry * hwe = (struct hwentry *)data;
2245
2246         if (!hwe->prio_args)
2247                 return 0;
2248
2249         return snprintf(buff, len, "\"%s\"", hwe->prio_args);
2250 }
2251
2252 static int
2253 snprint_hw_features (char * buff, int len, void * data)
2254 {
2255         struct hwentry * hwe = (struct hwentry *)data;
2256
2257         if (!hwe->features)
2258                 return 0;
2259
2260         return snprintf(buff, len, "\"%s\"", hwe->features);
2261 }
2262
2263 static int
2264 snprint_hw_hardware_handler (char * buff, int len, void * data)
2265 {
2266         struct hwentry * hwe = (struct hwentry *)data;
2267
2268         if (!hwe->hwhandler)
2269                 return 0;
2270
2271         return snprintf(buff, len, "\"%s\"", hwe->hwhandler);
2272 }
2273
2274 static int
2275 snprint_hw_selector (char * buff, int len, void * data)
2276 {
2277         struct hwentry * hwe = (struct hwentry *)data;
2278
2279         if (!hwe->selector)
2280                 return 0;
2281
2282         return snprintf(buff, len, "\"%s\"", hwe->selector);
2283 }
2284
2285 static int
2286 snprint_hw_path_grouping_policy (char * buff, int len, void * data)
2287 {
2288         struct hwentry * hwe = (struct hwentry *)data;
2289
2290         char str[POLICY_NAME_SIZE];
2291
2292         if (!hwe->pgpolicy)
2293                 return 0;
2294
2295         get_pgpolicy_name(str, POLICY_NAME_SIZE, hwe->pgpolicy);
2296
2297         return snprintf(buff, len, "\"%s\"", str);
2298 }
2299
2300 static int
2301 snprint_hw_failback (char * buff, int len, void * data)
2302 {
2303         struct hwentry * hwe = (struct hwentry *)data;
2304
2305         if (hwe->pgfailback == FAILBACK_UNDEF ||
2306             hwe->pgfailback == DEFAULT_FAILBACK)
2307                 return 0;
2308
2309         switch(hwe->pgfailback) {
2310         case -FAILBACK_MANUAL:
2311                 return snprintf(buff, len, "\"manual\"");
2312         case -FAILBACK_IMMEDIATE:
2313                 return snprintf(buff, len, "\"immediate\"");
2314         case -FAILBACK_FOLLOWOVER:
2315                 return snprintf(buff, len, "\"followover\"");
2316         default:
2317                 return snprintf(buff, len, "%i", hwe->pgfailback);
2318         }
2319         return 0;
2320 }
2321
2322 static int
2323 snprint_hw_rr_weight (char * buff, int len, void * data)
2324 {
2325         struct hwentry * hwe = (struct hwentry *)data;
2326
2327         if (!hwe->rr_weight)
2328                 return 0;
2329         if (hwe->rr_weight == RR_WEIGHT_PRIO)
2330                 return snprintf(buff, len, "\"priorities\"");
2331         if (hwe->rr_weight == RR_WEIGHT_NONE)
2332                 return snprintf(buff, len, "\"uniform\"");
2333
2334         return 0;
2335 }
2336
2337 static int
2338 snprint_hw_no_path_retry (char * buff, int len, void * data)
2339 {
2340         struct hwentry * hwe = (struct hwentry *)data;
2341
2342         if (!hwe->no_path_retry)
2343                 return 0;
2344
2345         switch(hwe->no_path_retry) {
2346         case NO_PATH_RETRY_UNDEF:
2347                 break;
2348         case NO_PATH_RETRY_FAIL:
2349                 return snprintf(buff, len, "\"fail\"");
2350         case NO_PATH_RETRY_QUEUE:
2351                 return snprintf(buff, len, "\"queue\"");
2352         default:
2353                 return snprintf(buff, len, "%i",
2354                                 hwe->no_path_retry);
2355         }
2356         return 0;
2357 }
2358
2359 static int
2360 snprint_hw_rr_min_io (char * buff, int len, void * data)
2361 {
2362         struct hwentry * hwe = (struct hwentry *)data;
2363
2364         if (!hwe->minio)
2365                 return 0;
2366
2367         return snprintf(buff, len, "%u", hwe->minio);
2368 }
2369
2370 static int
2371 snprint_hw_rr_min_io_rq (char * buff, int len, void * data)
2372 {
2373         struct hwentry * hwe = (struct hwentry *)data;
2374
2375         if (!hwe->minio_rq)
2376                 return 0;
2377
2378         return snprintf(buff, len, "%u", hwe->minio_rq);
2379 }
2380
2381 static int
2382 snprint_hw_pg_timeout (char * buff, int len, void * data)
2383 {
2384         return 0;
2385 }
2386
2387 static int
2388 snprint_hw_flush_on_last_del (char * buff, int len, void * data)
2389 {
2390         struct hwentry * hwe = (struct hwentry *)data;
2391
2392         switch (hwe->flush_on_last_del) {
2393         case FLUSH_DISABLED:
2394                 return snprintf(buff, len, "\"no\"");
2395         case FLUSH_ENABLED:
2396                 return snprintf(buff, len, "\"yes\"");
2397         }
2398         return 0;
2399 }
2400
2401 static int
2402 snprint_hw_path_checker (char * buff, int len, void * data)
2403 {
2404         struct hwentry * hwe = (struct hwentry *)data;
2405
2406         if (!hwe->checker_name)
2407                 return 0;
2408
2409         return snprintf(buff, len, "\"%s\"", hwe->checker_name);
2410 }
2411
2412         static int
2413 snprint_hw_user_friendly_names (char * buff, int len, void * data)
2414 {
2415         struct hwentry * hwe = (struct hwentry *)data;
2416
2417         if (hwe->user_friendly_names == USER_FRIENDLY_NAMES_UNDEF)
2418                 return 0;
2419         else if (hwe->user_friendly_names == USER_FRIENDLY_NAMES_OFF)
2420                 return snprintf(buff, len, "\"no\"");
2421         else
2422                 return snprintf(buff, len, "\"yes\"");
2423 }
2424
2425 static int
2426 snprint_hw_retain_hwhandler_handler(char * buff, int len, void * data)
2427 {
2428         struct hwentry * hwe = (struct hwentry *)data;
2429
2430         if (hwe->retain_hwhandler == RETAIN_HWHANDLER_ON)
2431                 return snprintf(buff, len, "\"yes\"");
2432         else if (hwe->retain_hwhandler == RETAIN_HWHANDLER_OFF)
2433                 return snprintf(buff, len, "\"no\"");
2434         else
2435                 return 0;
2436 }
2437
2438 static int
2439 snprint_detect_prio(char * buff, int len, void * data)
2440 {
2441         struct hwentry * hwe = (struct hwentry *)data;
2442
2443         if (hwe->detect_prio == DETECT_PRIO_ON)
2444                 return snprintf(buff, len, "\"yes\"");
2445         else if (hwe->detect_prio == DETECT_PRIO_OFF)
2446                 return snprintf(buff, len, "\"no\"");
2447         else
2448                 return 0;
2449 }
2450
2451 static int
2452 snprint_def_polling_interval (char * buff, int len, void * data)
2453 {
2454         return snprintf(buff, len, "%i", conf->checkint);
2455 }
2456
2457 static int
2458 snprint_def_fast_io_fail(char * buff, int len, void * data)
2459 {
2460         if (conf->fast_io_fail == MP_FAST_IO_FAIL_UNSET)
2461                 return 0;
2462         if (conf->fast_io_fail == MP_FAST_IO_FAIL_OFF)
2463                 return snprintf(buff, len, "\"off\"");
2464         if (conf->fast_io_fail == MP_FAST_IO_FAIL_ZERO)
2465                 return snprintf(buff, len, "0");
2466         return snprintf(buff, len, "%d", conf->fast_io_fail);
2467 }
2468
2469 static int
2470 snprint_def_dev_loss(char * buff, int len, void * data)
2471 {
2472         if (!conf->dev_loss)
2473                 return 0;
2474         if (conf->dev_loss >= MAX_DEV_LOSS_TMO)
2475                 return snprintf(buff, len, "\"infinity\"");
2476         return snprintf(buff, len, "%u", conf->dev_loss);
2477 }
2478
2479 static int
2480 snprint_def_verbosity (char * buff, int len, void * data)
2481 {
2482         return snprintf(buff, len, "%i", conf->verbosity);
2483 }
2484
2485 static int
2486 snprint_def_max_polling_interval (char * buff, int len, void * data)
2487 {
2488         return snprintf(buff, len, "%i", conf->max_checkint);
2489 }
2490
2491 static int
2492 snprint_reassign_maps (char * buff, int len, void * data)
2493 {
2494         return snprintf(buff, len, "\"%s\"",
2495                         conf->reassign_maps?"yes":"no");
2496 }
2497
2498 static int
2499 snprint_def_multipath_dir (char * buff, int len, void * data)
2500 {
2501         if (!conf->multipath_dir)
2502                 return 0;
2503
2504         return snprintf(buff, len, "\"%s\"", conf->multipath_dir);
2505 }
2506
2507 static int
2508 snprint_def_selector (char * buff, int len, void * data)
2509 {
2510         if (!conf->selector)
2511                 return snprintf(buff, len, "\"%s\"", DEFAULT_SELECTOR);
2512
2513         return snprintf(buff, len, "\"%s\"", conf->selector);
2514 }
2515
2516 static int
2517 snprint_def_path_grouping_policy (char * buff, int len, void * data)
2518 {
2519         char str[POLICY_NAME_SIZE];
2520         int pgpolicy = conf->pgpolicy;
2521
2522         if (!pgpolicy)
2523                 pgpolicy = DEFAULT_PGPOLICY;
2524
2525         get_pgpolicy_name(str, POLICY_NAME_SIZE, pgpolicy);
2526
2527         return snprintf(buff, len, "\"%s\"", str);
2528 }
2529
2530 static int
2531 snprint_def_uid_attribute (char * buff, int len, void * data)
2532 {
2533         if (!conf->uid_attribute)
2534                 return snprintf(buff, len, "\"%s\"", DEFAULT_UID_ATTRIBUTE);
2535
2536         return snprintf(buff, len, "\"%s\"", conf->uid_attribute);
2537 }
2538
2539 static int
2540 snprint_def_getuid_callout (char * buff, int len, void * data)
2541 {
2542         if (!conf->getuid)
2543                 return 0;
2544
2545         return snprintf(buff, len, "\"%s\"", conf->getuid);
2546 }
2547
2548 static int
2549 snprint_def_prio (char * buff, int len, void * data)
2550 {
2551         if (!conf->prio_name)
2552                 return snprintf(buff, len, "\"%s\"", DEFAULT_PRIO);
2553
2554         return snprintf(buff, len, "\"%s\"", conf->prio_name);
2555 }
2556
2557 static int
2558 snprint_def_prio_args (char * buff, int len, void * data)
2559 {
2560         if (!conf->prio_args)
2561                 return snprintf(buff, len, "\"%s\"", DEFAULT_PRIO_ARGS);
2562
2563         return snprintf(buff, len, "\"%s\"", conf->prio_args);
2564 }
2565
2566 static int
2567 snprint_def_features (char * buff, int len, void * data)
2568 {
2569         if (!conf->features)
2570                 return snprintf(buff, len, "\"%s\"", DEFAULT_FEATURES);
2571
2572         return snprintf(buff, len, "\"%s\"", conf->features);
2573 }
2574
2575 static int
2576 snprint_def_path_checker (char * buff, int len, void * data)
2577 {
2578         if (!conf->checker_name)
2579                 return snprintf(buff, len, "\"%s\"", DEFAULT_CHECKER);
2580
2581         return snprintf(buff, len, "\"%s\"", conf->checker_name);
2582 }
2583
2584 static int
2585 snprint_def_failback (char * buff, int len, void * data)
2586 {
2587         switch(conf->pgfailback) {
2588         case  FAILBACK_UNDEF:
2589                 return snprintf(buff, len, "\"undef\"");
2590         case -FAILBACK_MANUAL:
2591                 return snprintf(buff, len, "\"manual\"");
2592         case -FAILBACK_IMMEDIATE:
2593                 return snprintf(buff, len, "\"immediate\"");
2594         case -FAILBACK_FOLLOWOVER:
2595                 return snprintf(buff, len, "\"followover\"");
2596         default:
2597                 return snprintf(buff, len, "%i", conf->pgfailback);
2598         }
2599         return 0;
2600 }
2601
2602 static int
2603 snprint_def_rr_min_io (char * buff, int len, void * data)
2604 {
2605         if (!conf->minio)
2606                 return 0;
2607
2608         return snprintf(buff, len, "%u", conf->minio);
2609 }
2610
2611 static int
2612 snprint_def_rr_min_io_rq (char * buff, int len, void * data)
2613 {
2614         if (!conf->minio_rq)
2615                 return 0;
2616
2617         return snprintf(buff, len, "%u", conf->minio_rq);
2618 }
2619
2620 static int
2621 snprint_max_fds (char * buff, int len, void * data)
2622 {
2623         int r = 0, max_fds;
2624
2625         if (!conf->max_fds)
2626                 return 0;
2627
2628         r = get_sys_max_fds(&max_fds);
2629         if (!r && conf->max_fds >= max_fds)
2630                 return snprintf(buff, len, "\"max\"");
2631         else
2632                 return snprintf(buff, len, "%d", conf->max_fds);
2633 }
2634
2635 static int
2636 snprint_def_mode(char * buff, int len, void * data)
2637 {
2638         if ((conf->attribute_flags & (1 << ATTR_MODE)) == 0)
2639                 return 0;
2640         return snprintf(buff, len, "0%o", conf->mode);
2641 }
2642
2643 static int
2644 snprint_def_uid(char * buff, int len, void * data)
2645 {
2646         if ((conf->attribute_flags & (1 << ATTR_UID)) == 0)
2647                 return 0;
2648         return snprintf(buff, len, "0%o", conf->uid);
2649 }
2650
2651 static int
2652 snprint_def_gid(char * buff, int len, void * data)
2653 {
2654         if ((conf->attribute_flags & (1 << ATTR_GID)) == 0)
2655                 return 0;
2656         return snprintf(buff, len, "0%o", conf->gid);
2657 }
2658
2659 static int
2660 snprint_def_rr_weight (char * buff, int len, void * data)
2661 {
2662         if (!conf->rr_weight || conf->rr_weight == RR_WEIGHT_NONE)
2663                 return snprintf(buff, len, "\"uniform\"");
2664         if (conf->rr_weight == RR_WEIGHT_PRIO)
2665                 return snprintf(buff, len, "\"priorities\"");
2666
2667         return 0;
2668 }
2669
2670 static int
2671 snprint_def_no_path_retry (char * buff, int len, void * data)
2672 {
2673         switch(conf->no_path_retry) {
2674         case NO_PATH_RETRY_UNDEF:
2675                 break;
2676         case NO_PATH_RETRY_FAIL:
2677                 return snprintf(buff, len, "\"fail\"");
2678         case NO_PATH_RETRY_QUEUE:
2679                 return snprintf(buff, len, "\"queue\"");
2680         default:
2681                 return snprintf(buff, len, "%i",
2682                                 conf->no_path_retry);
2683         }
2684         return 0;
2685 }
2686
2687 static int
2688 snprint_def_queue_without_daemon (char * buff, int len, void * data)
2689 {
2690         switch (conf->queue_without_daemon) {
2691         case QUE_NO_DAEMON_OFF:
2692                 return snprintf(buff, len, "\"no\"");
2693         case QUE_NO_DAEMON_ON:
2694                 return snprintf(buff, len, "\"yes\"");
2695         case QUE_NO_DAEMON_FORCE:
2696                 return snprintf(buff, len, "\"forced\"");
2697         }
2698         return 0;
2699 }
2700
2701 static int
2702 snprint_def_checker_timeout (char *buff, int len, void *data)
2703 {
2704         if (!conf->checker_timeout)
2705                 return 0;
2706
2707         return snprintf(buff, len, "%u", conf->checker_timeout);
2708 }
2709
2710 static int
2711 snprint_def_pg_timeout (char * buff, int len, void * data)
2712 {
2713         return 0;
2714 }
2715
2716 static int
2717 snprint_def_flush_on_last_del (char * buff, int len, void * data)
2718 {
2719         switch (conf->flush_on_last_del) {
2720         case FLUSH_UNDEF:
2721         case FLUSH_DISABLED:
2722                 return snprintf(buff, len, "\"no\"");
2723         case FLUSH_ENABLED:
2724         case FLUSH_IN_PROGRESS:
2725                 return snprintf(buff, len, "\"yes\"");
2726         }
2727         return 0;
2728 }
2729
2730 static int
2731 snprint_def_log_checker_err (char * buff, int len, void * data)
2732 {
2733         if (conf->log_checker_err == LOG_CHKR_ERR_ONCE)
2734                 return snprintf(buff, len, "once");
2735         return snprintf(buff, len, "always");
2736 }
2737
2738 static int
2739 snprint_def_user_friendly_names (char * buff, int len, void * data)
2740 {
2741         if (conf->user_friendly_names  == USER_FRIENDLY_NAMES_ON)
2742                 return snprintf(buff, len, "\"yes\"");
2743         else
2744                 return snprintf(buff, len, "\"no\"");
2745 }
2746
2747 static int
2748 snprint_def_alias_prefix (char * buff, int len, void * data)
2749 {
2750         if (!conf->alias_prefix)
2751                 return snprintf(buff, len, "\"%s\"", DEFAULT_ALIAS_PREFIX);
2752         return snprintf(buff, len, "\"%s\"", conf->alias_prefix);
2753 }
2754
2755 static int
2756 snprint_def_bindings_file (char * buff, int len, void * data)
2757 {
2758         if (conf->bindings_file == NULL)
2759                 return 0;
2760         return snprintf(buff, len, "\"%s\"", conf->bindings_file);
2761 }
2762
2763 static int
2764 snprint_def_wwids_file (char * buff, int len, void * data)
2765 {
2766         if (conf->wwids_file == NULL)
2767                 return 0;
2768         return snprintf(buff, len, "%s", conf->wwids_file);
2769 }
2770
2771 static int
2772 snprint_def_reservation_key(char * buff, int len, void * data)
2773 {
2774         int i;
2775         unsigned char *keyp;
2776         uint64_t prkey = 0;
2777
2778         if (!conf->reservation_key)
2779                 return 0;
2780         keyp = (unsigned char *)conf->reservation_key;
2781         for (i = 0; i < 8; i++) {
2782                 if (i > 0)
2783                         prkey <<= 8;
2784                 prkey |= *keyp;
2785                 keyp++;
2786         }
2787         return snprintf(buff, len, "0x%" PRIx64, prkey);
2788 }
2789
2790 static int
2791 snprint_def_retain_hwhandler_handler(char * buff, int len, void * data)
2792 {
2793         if (conf->retain_hwhandler == RETAIN_HWHANDLER_ON)
2794                 return snprintf(buff, len, "yes");
2795         else
2796                 return snprintf(buff, len, "no");
2797 }
2798
2799 static int
2800 snprint_def_detect_prio(char * buff, int len, void * data)
2801 {
2802         if (conf->detect_prio == DETECT_PRIO_ON)
2803                 return snprintf(buff, len, "yes");
2804         else
2805                 return snprintf(buff, len, "no");
2806 }
2807
2808 static int
2809 snprint_def_force_sync(char * buff, int len, void * data)
2810 {
2811         if (conf->force_sync)
2812                 return snprintf(buff, len, "yes");
2813         else
2814                 return snprintf(buff, len, "no");
2815 }
2816
2817 static int
2818 snprint_ble_simple (char * buff, int len, void * data)
2819 {
2820         struct blentry * ble = (struct blentry *)data;
2821
2822         return snprintf(buff, len, "\"%s\"", ble->str);
2823 }
2824
2825 static int
2826 snprint_bled_vendor (char * buff, int len, void * data)
2827 {
2828         struct blentry_device * bled = (struct blentry_device *)data;
2829
2830         return snprintf(buff, len, "\"%s\"", bled->vendor);
2831 }
2832
2833 static int
2834 snprint_bled_product (char * buff, int len, void * data)
2835 {
2836         struct blentry_device * bled = (struct blentry_device *)data;
2837
2838         return snprintf(buff, len, "\"%s\"", bled->product);
2839 }
2840
2841 #define __deprecated
2842
2843 void
2844 init_keywords(void)
2845 {
2846         install_keyword_root("defaults", NULL);
2847         install_keyword("verbosity", &verbosity_handler, &snprint_def_verbosity);
2848         install_keyword("polling_interval", &polling_interval_handler, &snprint_def_polling_interval);
2849         install_keyword("max_polling_interval", &max_polling_interval_handler, &snprint_def_max_polling_interval);
2850         install_keyword("reassign_maps", &reassign_maps_handler, &snprint_reassign_maps);
2851         install_keyword("multipath_dir", &multipath_dir_handler, &snprint_def_multipath_dir);
2852         install_keyword("path_selector", &def_selector_handler, &snprint_def_selector);
2853         install_keyword("path_grouping_policy", &def_pgpolicy_handler, &snprint_def_path_grouping_policy);
2854         install_keyword("uid_attribute", &def_uid_attribute_handler, &snprint_def_uid_attribute);
2855         install_keyword("getuid_callout", &def_getuid_callout_handler, &snprint_def_getuid_callout);
2856         install_keyword("prio", &def_prio_handler, &snprint_def_prio);
2857         install_keyword("prio_args", &def_prio_args_handler, &snprint_def_prio_args);
2858         install_keyword("features", &def_features_handler, &snprint_def_features);
2859         install_keyword("path_checker", &def_path_checker_handler, &snprint_def_path_checker);
2860         install_keyword("checker", &def_path_checker_handler, NULL);
2861         install_keyword("alias_prefix", &def_alias_prefix_handler, &snprint_def_alias_prefix);
2862         install_keyword("failback", &default_failback_handler, &snprint_def_failback);
2863         install_keyword("rr_min_io", &def_minio_handler, &snprint_def_rr_min_io);
2864         install_keyword("rr_min_io_rq", &def_minio_rq_handler, &snprint_def_rr_min_io_rq);
2865         install_keyword("max_fds", &max_fds_handler, &snprint_max_fds);
2866         install_keyword("rr_weight", &def_weight_handler, &snprint_def_rr_weight);
2867         install_keyword("no_path_retry", &def_no_path_retry_handler, &snprint_def_no_path_retry);
2868         install_keyword("queue_without_daemon", &def_queue_without_daemon, &snprint_def_queue_without_daemon);
2869         install_keyword("checker_timeout", &def_checker_timeout_handler, &snprint_def_checker_timeout);
2870         install_keyword("pg_timeout", &def_pg_timeout_handler, &snprint_def_pg_timeout);
2871         install_keyword("flush_on_last_del", &def_flush_on_last_del_handler, &snprint_def_flush_on_last_del);
2872         install_keyword("user_friendly_names", &def_names_handler, &snprint_def_user_friendly_names);
2873         install_keyword("mode", &def_mode_handler, &snprint_def_mode);
2874         install_keyword("uid", &def_uid_handler, &snprint_def_uid);
2875         install_keyword("gid", &def_gid_handler, &snprint_def_gid);
2876         install_keyword("fast_io_fail_tmo", &def_fast_io_fail_handler, &snprint_def_fast_io_fail);
2877         install_keyword("dev_loss_tmo", &def_dev_loss_handler, &snprint_def_dev_loss);
2878         install_keyword("bindings_file", &bindings_file_handler, &snprint_def_bindings_file);
2879         install_keyword("wwids_file", &wwids_file_handler, &snprint_def_wwids_file);
2880         install_keyword("log_checker_err", &def_log_checker_err_handler, &snprint_def_log_checker_err);
2881         install_keyword("reservation_key", &def_reservation_key_handler, &snprint_def_reservation_key);
2882         install_keyword("retain_attached_hw_handler", &def_retain_hwhandler_handler, &snprint_def_retain_hwhandler_handler);
2883         install_keyword("detect_prio", &def_detect_prio_handler, &snprint_def_detect_prio);
2884         install_keyword("force_sync", &def_force_sync_handler, &snprint_def_force_sync);
2885         __deprecated install_keyword("default_selector", &def_selector_handler, NULL);
2886         __deprecated install_keyword("default_path_grouping_policy", &def_pgpolicy_handler, NULL);
2887         __deprecated install_keyword("default_uid_attribute", &def_uid_attribute_handler, NULL);
2888         __deprecated install_keyword("default_getuid_callout", &def_getuid_callout_handler, NULL);
2889         __deprecated install_keyword("default_features", &def_features_handler, NULL);
2890         __deprecated install_keyword("default_path_checker", &def_path_checker_handler, NULL);
2891
2892         install_keyword_root("blacklist", &blacklist_handler);
2893         install_keyword_multi("devnode", &ble_devnode_handler, &snprint_ble_simple);
2894         install_keyword_multi("wwid", &ble_wwid_handler, &snprint_ble_simple);
2895         install_keyword_multi("property", &ble_property_handler, &snprint_ble_simple);
2896         install_keyword_multi("device", &ble_device_handler, NULL);
2897         install_sublevel();
2898         install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
2899         install_keyword("product", &ble_product_handler, &snprint_bled_product);
2900         install_sublevel_end();
2901         install_keyword_root("blacklist_exceptions", &blacklist_exceptions_handler);
2902         install_keyword_multi("devnode", &ble_except_devnode_handler, &snprint_ble_simple);
2903         install_keyword_multi("wwid", &ble_except_wwid_handler, &snprint_ble_simple);
2904         install_keyword_multi("property", &ble_except_property_handler, &snprint_ble_simple);
2905         install_keyword_multi("device", &ble_except_device_handler, NULL);
2906         install_sublevel();
2907         install_keyword("vendor", &ble_except_vendor_handler, &snprint_bled_vendor);
2908         install_keyword("product", &ble_except_product_handler, &snprint_bled_product);
2909         install_sublevel_end();
2910
2911 #if 0
2912         __deprecated install_keyword_root("devnode_blacklist", &blacklist_handler);
2913         __deprecated install_keyword("devnode", &ble_devnode_handler, &snprint_ble_simple);
2914         __deprecated install_keyword("wwid", &ble_wwid_handler, &snprint_ble_simple);
2915         __deprecated install_keyword("device", &ble_device_handler, NULL);
2916         __deprecated install_sublevel();
2917         __deprecated install_keyword("vendor", &ble_vendor_handler, &snprint_bled_vendor);
2918         __deprecated install_keyword("product", &ble_product_handler, &snprint_bled_product);
2919         __deprecated install_sublevel_end();
2920 #endif
2921
2922         install_keyword_root("devices", &devices_handler);
2923         install_keyword_multi("device", &device_handler, NULL);
2924         install_sublevel();
2925         install_keyword("vendor", &vendor_handler, &snprint_hw_vendor);
2926         install_keyword("product", &product_handler, &snprint_hw_product);
2927         install_keyword("revision", &revision_handler, &snprint_hw_revision);
2928         install_keyword("product_blacklist", &bl_product_handler, &snprint_hw_bl_product);
2929         install_keyword("path_grouping_policy", &hw_pgpolicy_handler, &snprint_hw_path_grouping_policy);
2930         install_keyword("uid_attribute", &hw_uid_attribute_handler, &snprint_hw_uid_attribute);
2931         install_keyword("getuid_callout", &hw_getuid_callout_handler, &snprint_hw_getuid_callout);
2932         install_keyword("path_selector", &hw_selector_handler, &snprint_hw_selector);
2933         install_keyword("path_checker", &hw_path_checker_handler, &snprint_hw_path_checker);
2934         install_keyword("checker", &hw_path_checker_handler, NULL);
2935         install_keyword("alias_prefix", &hw_alias_prefix_handler, &snprint_hw_alias_prefix);
2936         install_keyword("features", &hw_features_handler, &snprint_hw_features);
2937         install_keyword("hardware_handler", &hw_handler_handler, &snprint_hw_hardware_handler);
2938         install_keyword("prio", &hw_prio_handler, &snprint_hw_prio);
2939         install_keyword("prio_args", &hw_prio_args_handler, &snprint_hw_prio_args);
2940         install_keyword("failback", &hw_failback_handler, &snprint_hw_failback);
2941         install_keyword("rr_weight", &hw_weight_handler, &snprint_hw_rr_weight);
2942         install_keyword("no_path_retry", &hw_no_path_retry_handler, &snprint_hw_no_path_retry);
2943         install_keyword("rr_min_io", &hw_minio_handler, &snprint_hw_rr_min_io);
2944         install_keyword("rr_min_io_rq", &hw_minio_rq_handler, &snprint_hw_rr_min_io_rq);
2945         install_keyword("pg_timeout", &hw_pg_timeout_handler, &snprint_hw_pg_timeout);
2946         install_keyword("flush_on_last_del", &hw_flush_on_last_del_handler, &snprint_hw_flush_on_last_del);
2947         install_keyword("fast_io_fail_tmo", &hw_fast_io_fail_handler, &snprint_hw_fast_io_fail);
2948         install_keyword("dev_loss_tmo", &hw_dev_loss_handler, &snprint_hw_dev_loss);
2949         install_keyword("user_friendly_names", &hw_names_handler, &snprint_hw_user_friendly_names);
2950         install_keyword("retain_attached_hw_handler", &hw_retain_hwhandler_handler, &snprint_hw_retain_hwhandler_handler);
2951         install_keyword("detect_prio", &hw_detect_prio_handler, &snprint_detect_prio);
2952         install_sublevel_end();
2953
2954         install_keyword_root("multipaths", &multipaths_handler);
2955         install_keyword_multi("multipath", &multipath_handler, NULL);
2956         install_sublevel();
2957         install_keyword("wwid", &wwid_handler, &snprint_mp_wwid);
2958         install_keyword("alias", &alias_handler, &snprint_mp_alias);
2959         install_keyword("path_grouping_policy", &mp_pgpolicy_handler, &snprint_mp_path_grouping_policy);
2960         install_keyword("path_selector", &mp_selector_handler, &snprint_mp_selector);
2961         install_keyword("prio", &mp_prio_handler, &snprint_mp_prio);
2962         install_keyword("prio_args", &mp_prio_args_handler, &snprint_mp_prio_args);
2963         install_keyword("failback", &mp_failback_handler, &snprint_mp_failback);
2964         install_keyword("rr_weight", &mp_weight_handler, &snprint_mp_rr_weight);
2965         install_keyword("no_path_retry", &mp_no_path_retry_handler, &snprint_mp_no_path_retry);
2966         install_keyword("rr_min_io", &mp_minio_handler, &snprint_mp_rr_min_io);
2967         install_keyword("rr_min_io_rq", &mp_minio_rq_handler, &snprint_mp_rr_min_io_rq);
2968         install_keyword("pg_timeout", &mp_pg_timeout_handler, &snprint_mp_pg_timeout);
2969         install_keyword("flush_on_last_del", &mp_flush_on_last_del_handler, &snprint_mp_flush_on_last_del);
2970         install_keyword("features", &mp_features_handler, &snprint_mp_features);
2971         install_keyword("mode", &mp_mode_handler, &snprint_mp_mode);
2972         install_keyword("uid", &mp_uid_handler, &snprint_mp_uid);
2973         install_keyword("gid", &mp_gid_handler, &snprint_mp_gid);
2974         install_keyword("reservation_key", &mp_reservation_key_handler, &snprint_mp_reservation_key);
2975         install_keyword("user_friendly_names", &mp_names_handler, &snprint_mp_user_friendly_names);
2976         install_sublevel_end();
2977 }