2 * Copyright (c) 2005 Christophe Varoqui
6 #include <libdevmapper.h>
14 #include "structs_vec.h"
18 #include "configure.h"
19 #include "pgpolicies.h"
22 #include "blacklist.h"
23 #include "switchgroup.h"
24 #include "devmapper.h"
26 #define MAX(x,y) (x > y) ? x : y
27 #define TAIL (line + len - 1 - c)
29 #define PAD(x) while ((int)(c - s) < (x) && (c < (line + len - 1))) \
33 line[c - line - 1] = '\n'
34 #define PRINT(var, size, format, args...) \
35 fwd = snprintf(var, size, format, ##args); \
36 c += (fwd >= size) ? size : fwd;
39 * information printing helpers
42 snprint_str (char * buff, size_t len, char * str)
44 return snprintf(buff, len, "%s", str);
48 snprint_int (char * buff, size_t len, int val)
50 return snprintf(buff, len, "%i", val);
54 snprint_uint (char * buff, size_t len, unsigned int val)
56 return snprintf(buff, len, "%u", val);
60 snprint_size (char * buff, size_t len, unsigned long long size)
62 float s = (float)(size >> 1); /* start with KB */
64 char units[] = {'K','M','G','T','P'};
67 while (s >= 1024 && *u != 'P') {
72 snprintf(fmt, 6, "%%.1f%c", *u);
74 snprintf(fmt, 6, "%%.0f%c", *u);
76 return snprintf(buff, len, fmt, s);
80 * multipath info printing functions
83 snprint_name (char * buff, size_t len, struct multipath * mpp)
86 return snprintf(buff, len, "%s", mpp->alias);
88 return snprintf(buff, len, "%s", mpp->wwid);
92 snprint_sysfs (char * buff, size_t len, struct multipath * mpp)
95 return snprintf(buff, len, "dm-%i", mpp->dmi->minor);
97 return snprintf(buff, len, "undef");
101 snprint_ro (char * buff, size_t len, struct multipath * mpp)
104 return snprintf(buff, len, "undef");
105 if (mpp->dmi->read_only)
106 return snprintf(buff, len, "ro");
108 return snprintf(buff, len, "rw");
112 snprint_progress (char * buff, size_t len, int cur, int total)
114 int i = PROGRESS_LEN * cur / total;
115 int j = PROGRESS_LEN - i;
117 char * end = buff + len;
120 c += snprintf(c, len, "X");
121 if ((len = (end - c)) <= 1) goto out;
125 c += snprintf(c, len, ".");
126 if ((len = (end - c)) <= 1) goto out;
129 c += snprintf(c, len, " %i/%i", cur, total);
132 buff[c - buff + 1] = '\0';
133 return (c - buff + 1);
137 snprint_failback (char * buff, size_t len, struct multipath * mpp)
139 if (mpp->pgfailback == -FAILBACK_IMMEDIATE)
140 return snprintf(buff, len, "immediate");
142 if (!mpp->failback_tick)
143 return snprintf(buff, len, "-");
145 return snprint_progress(buff, len, mpp->failback_tick,
150 snprint_queueing (char * buff, size_t len, struct multipath * mpp)
152 if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
153 return snprintf(buff, len, "off");
154 else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE)
155 return snprintf(buff, len, "on");
156 else if (mpp->no_path_retry == NO_PATH_RETRY_UNDEF)
157 return snprintf(buff, len, "-");
158 else if (mpp->no_path_retry > 0) {
160 return snprintf(buff, len, "%i sec",
163 return snprintf(buff, len, "%i chk",
170 snprint_nb_paths (char * buff, size_t len, struct multipath * mpp)
172 return snprint_int(buff, len, mpp->nr_active);
176 snprint_dm_map_state (char * buff, size_t len, struct multipath * mpp)
178 if (mpp->dmi && mpp->dmi->suspended)
179 return snprintf(buff, len, "suspend");
181 return snprintf(buff, len, "active");
185 snprint_multipath_size (char * buff, size_t len, struct multipath * mpp)
187 return snprint_size(buff, len, mpp->size);
191 snprint_features (char * buff, size_t len, struct multipath * mpp)
193 return snprint_str(buff, len, mpp->features);
197 snprint_hwhandler (char * buff, size_t len, struct multipath * mpp)
199 return snprint_str(buff, len, mpp->hwhandler);
203 snprint_path_faults (char * buff, size_t len, struct multipath * mpp)
205 return snprint_uint(buff, len, mpp->stat_path_failures);
209 snprint_switch_grp (char * buff, size_t len, struct multipath * mpp)
211 return snprint_uint(buff, len, mpp->stat_switchgroup);
215 snprint_map_loads (char * buff, size_t len, struct multipath * mpp)
217 return snprint_uint(buff, len, mpp->stat_map_loads);
221 snprint_total_q_time (char * buff, size_t len, struct multipath * mpp)
223 return snprint_uint(buff, len, mpp->stat_total_queueing_time);
227 snprint_q_timeouts (char * buff, size_t len, struct multipath * mpp)
229 return snprint_uint(buff, len, mpp->stat_queueing_timeouts);
233 snprint_multipath_uuid (char * buff, size_t len, struct multipath * mpp)
235 return snprint_str(buff, len, mpp->wwid);
239 snprint_multipath_vpr (char * buff, size_t len, struct multipath * mpp)
241 struct path * pp = first_path(mpp);
244 return snprintf(buff, len, "%s,%s",
245 pp->vendor_id, pp->product_id);
249 snprint_action (char * buff, size_t len, struct multipath * mpp)
251 switch (mpp->action) {
253 return snprint_str(buff, len, ACT_REJECT_STR);
255 return snprint_str(buff, len, ACT_RENAME_STR);
257 return snprint_str(buff, len, ACT_RELOAD_STR);
259 return snprint_str(buff, len, ACT_CREATE_STR);
261 return snprint_str(buff, len, ACT_SWITCHPG_STR);
268 * path info printing functions
271 snprint_path_uuid (char * buff, size_t len, struct path * pp)
273 return snprint_str(buff, len, pp->wwid);
277 snprint_hcil (char * buff, size_t len, struct path * pp)
279 if (pp->sg_id.host_no < 0)
280 return snprintf(buff, len, "#:#:#:#");
282 return snprintf(buff, len, "%i:%i:%i:%i",
290 snprint_dev (char * buff, size_t len, struct path * pp)
292 if (!strlen(pp->dev))
293 return snprintf(buff, len, "-");
295 return snprint_str(buff, len, pp->dev);
299 snprint_dev_t (char * buff, size_t len, struct path * pp)
301 if (!strlen(pp->dev))
302 return snprintf(buff, len, "#:#");
304 return snprint_str(buff, len, pp->dev_t);
308 snprint_offline (char * buff, size_t len, struct path * pp)
311 return snprintf(buff, len, "offline");
313 return snprintf(buff, len, "running");
317 snprint_chk_state (char * buff, size_t len, struct path * pp)
321 return snprintf(buff, len, "ready");
323 return snprintf(buff, len, "faulty");
325 return snprintf(buff, len, "shaky");
327 return snprintf(buff, len, "ghost");
329 return snprintf(buff, len, "undef");
334 snprint_dm_path_state (char * buff, size_t len, struct path * pp)
336 switch (pp->dmstate) {
338 return snprintf(buff, len, "active");
340 return snprintf(buff, len, "failed");
342 return snprintf(buff, len, "undef");
347 snprint_vpr (char * buff, size_t len, struct path * pp)
349 return snprintf(buff, len, "%s,%s",
350 pp->vendor_id, pp->product_id);
354 snprint_next_check (char * buff, size_t len, struct path * pp)
357 return snprintf(buff, len, "orphan");
359 return snprint_progress(buff, len, pp->tick, pp->checkint);
363 snprint_pri (char * buff, size_t len, struct path * pp)
365 return snprint_int(buff, len, pp->priority);
369 snprint_pg_selector (char * buff, size_t len, struct pathgroup * pgp)
371 return snprint_str(buff, len, pgp->selector);
375 snprint_pg_pri (char * buff, size_t len, struct pathgroup * pgp)
378 * path group priority is not updated for every path prio change,
379 * but only on switch group code path.
381 * Printing is another reason to update.
383 path_group_prio_update(pgp);
384 return snprint_int(buff, len, pgp->priority);
388 snprint_pg_state (char * buff, size_t len, struct pathgroup * pgp)
390 switch (pgp->status) {
391 case PGSTATE_ENABLED:
392 return snprintf(buff, len, "enabled");
393 case PGSTATE_DISABLED:
394 return snprintf(buff, len, "disabled");
396 return snprintf(buff, len, "active");
398 return snprintf(buff, len, "undef");
403 snprint_path_size (char * buff, size_t len, struct path * pp)
405 return snprint_size(buff, len, pp->size);
408 struct multipath_data mpd[] = {
409 {'n', "name", 0, snprint_name},
410 {'w', "uuid", 0, snprint_multipath_uuid},
411 {'d', "sysfs", 0, snprint_sysfs},
412 {'F', "failback", 0, snprint_failback},
413 {'Q', "queueing", 0, snprint_queueing},
414 {'N', "paths", 0, snprint_nb_paths},
415 {'r', "write_prot", 0, snprint_ro},
416 {'t', "dm-st", 0, snprint_dm_map_state},
417 {'S', "size", 0, snprint_multipath_size},
418 {'f', "features", 0, snprint_features},
419 {'h', "hwhandler", 0, snprint_hwhandler},
420 {'A', "action", 0, snprint_action},
421 {'0', "path_faults", 0, snprint_path_faults},
422 {'1', "switch_grp", 0, snprint_switch_grp},
423 {'2', "map_loads", 0, snprint_map_loads},
424 {'3', "total_q_time", 0, snprint_total_q_time},
425 {'4', "q_timeouts", 0, snprint_q_timeouts},
426 {'s', "vend/prod/rev", 0, snprint_multipath_vpr},
430 struct path_data pd[] = {
431 {'w', "uuid", 0, snprint_path_uuid},
432 {'i', "hcil", 0, snprint_hcil},
433 {'d', "dev", 0, snprint_dev},
434 {'D', "dev_t", 0, snprint_dev_t},
435 {'t', "dm_st", 0, snprint_dm_path_state},
436 {'o', "dev_st", 0, snprint_offline},
437 {'T', "chk_st", 0, snprint_chk_state},
438 {'s', "vend/prod/rev", 0, snprint_vpr},
439 {'C', "next_check", 0, snprint_next_check},
440 {'p', "pri", 0, snprint_pri},
441 {'S', "size", 0, snprint_path_size},
445 struct pathgroup_data pgd[] = {
446 {'s', "selector", 0, snprint_pg_selector},
447 {'p', "pri", 0, snprint_pg_pri},
448 {'t', "dm_st", 0, snprint_pg_state},
453 snprint_wildcards (char * buff, int len)
457 fwd += snprintf(buff + fwd, len - fwd, "multipath format wildcards:\n");
458 for (i = 0; mpd[i].header; i++)
459 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
460 mpd[i].wildcard, mpd[i].header);
461 fwd += snprintf(buff + fwd, len - fwd, "\npath format wildcards:\n");
462 for (i = 0; pd[i].header; i++)
463 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
464 pd[i].wildcard, pd[i].header);
465 fwd += snprintf(buff + fwd, len - fwd, "\npathgroup format wildcards:\n");
466 for (i = 0; pgd[i].header; i++)
467 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
468 pgd[i].wildcard, pgd[i].header);
473 get_path_layout (vector pathvec, int header)
476 char buff[MAX_FIELD_LEN];
479 for (j = 0; pd[j].header; j++) {
481 pd[j].width = strlen(pd[j].header);
485 vector_foreach_slot (pathvec, pp, i) {
486 pd[j].snprint(buff, MAX_FIELD_LEN, pp);
487 pd[j].width = MAX(pd[j].width, strlen(buff));
493 reset_multipath_layout (void)
497 for (i = 0; mpd[i].header; i++)
502 get_multipath_layout (vector mpvec, int header)
505 char buff[MAX_FIELD_LEN];
506 struct multipath * mpp;
508 for (j = 0; mpd[j].header; j++) {
510 mpd[j].width = strlen(mpd[j].header);
514 vector_foreach_slot (mpvec, mpp, i) {
515 mpd[j].snprint(buff, MAX_FIELD_LEN, mpp);
516 mpd[j].width = MAX(mpd[j].width, strlen(buff));
521 static struct multipath_data *
522 mpd_lookup(char wildcard)
526 for (i = 0; mpd[i].header; i++)
527 if (mpd[i].wildcard == wildcard)
533 static struct path_data *
534 pd_lookup(char wildcard)
538 for (i = 0; pd[i].header; i++)
539 if (pd[i].wildcard == wildcard)
545 static struct pathgroup_data *
546 pgd_lookup(char wildcard)
550 for (i = 0; pgd[i].header; i++)
551 if (pgd[i].wildcard == wildcard)
558 snprint_multipath_header (char * line, int len, char * format)
560 char * c = line; /* line cursor */
561 char * s = line; /* for padding */
562 char * f = format; /* format string cursor */
564 struct multipath_data * data;
566 memset(line, 0, len);
579 if (!(data = mpd_lookup(*f)))
580 continue; /* unknown wildcard */
582 PRINT(c, TAIL, "%s", data->header);
591 snprint_multipath (char * line, int len, char * format,
592 struct multipath * mpp)
594 char * c = line; /* line cursor */
595 char * s = line; /* for padding */
596 char * f = format; /* format string cursor */
598 struct multipath_data * data;
599 char buff[MAX_FIELD_LEN] = {};
601 memset(line, 0, len);
614 if (!(data = mpd_lookup(*f)))
617 data->snprint(buff, MAX_FIELD_LEN, mpp);
618 PRINT(c, TAIL, "%s", buff);
628 snprint_path_header (char * line, int len, char * format)
630 char * c = line; /* line cursor */
631 char * s = line; /* for padding */
632 char * f = format; /* format string cursor */
634 struct path_data * data;
636 memset(line, 0, len);
649 if (!(data = pd_lookup(*f)))
650 continue; /* unknown wildcard */
652 PRINT(c, TAIL, "%s", data->header);
661 snprint_path (char * line, int len, char * format,
664 char * c = line; /* line cursor */
665 char * s = line; /* for padding */
666 char * f = format; /* format string cursor */
668 struct path_data * data;
669 char buff[MAX_FIELD_LEN];
671 memset(line, 0, len);
684 if (!(data = pd_lookup(*f)))
687 data->snprint(buff, MAX_FIELD_LEN, pp);
688 PRINT(c, TAIL, "%s", buff);
697 snprint_pathgroup (char * line, int len, char * format,
698 struct pathgroup * pgp)
700 char * c = line; /* line cursor */
701 char * s = line; /* for padding */
702 char * f = format; /* format string cursor */
704 struct pathgroup_data * data;
705 char buff[MAX_FIELD_LEN];
707 memset(line, 0, len);
720 if (!(data = pgd_lookup(*f)))
723 data->snprint(buff, MAX_FIELD_LEN, pgp);
724 PRINT(c, TAIL, "%s", buff);
733 print_multipath_topology (struct multipath * mpp, int verbosity)
735 char buff[MAX_LINE_LEN * MAX_LINES] = {};
737 snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
743 snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
747 struct path * pp = NULL;
748 struct pathgroup * pgp = NULL;
757 reset_multipath_layout();
760 return snprint_multipath(buff, len, "%n", mpp);
762 c += sprintf(c, "%c[%dm", 0x1B, 1); /* bold on */
765 mpp->action != ACT_NOTHING &&
766 mpp->action != ACT_UNDEF)
767 c += sprintf(c, "%%A: ");
769 c += sprintf(c, "%%n");
771 if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE))
772 c += sprintf(c, " (%%w)");
774 c += sprintf(c, " %%d %%s");
775 c += sprintf(c, "%c[%dm", 0x1B, 0); /* bold off */
777 fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp);
780 fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp);
787 vector_foreach_slot (mpp->pg, pgp, j) {
789 pgp->selector = mpp->selector; /* hack */
790 if (j + 1 < VECTOR_SIZE(mpp->pg)) {
791 strcpy(f, "|-+- " PRINT_PG_INDENT);
793 strcpy(f, "`-+- " PRINT_PG_INDENT);
794 fwd += snprint_pathgroup(buff + fwd, len - fwd, fmt, pgp);
798 vector_foreach_slot (pgp->paths, pp, i) {
803 if (i + 1 < VECTOR_SIZE(pgp->paths))
804 strcpy(f, " |- " PRINT_PATH_INDENT);
806 strcpy(f, " `- " PRINT_PATH_INDENT);
807 fwd += snprint_path(buff + fwd, len - fwd, fmt, pp);
816 snprint_hwentry (char * buff, int len, struct hwentry * hwe)
821 struct keyword * rootkw;
823 rootkw = find_keyword(NULL, "devices");
825 if (!rootkw || !rootkw->sub)
828 rootkw = find_keyword(rootkw->sub, "device");
833 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
836 iterate_sub_keywords(rootkw, kw, i) {
837 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k \"%v\"\n",
842 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
849 snprint_hwtable (char * buff, int len, vector hwtable)
853 struct hwentry * hwe;
854 struct keyword * rootkw;
856 rootkw = find_keyword(NULL, "devices");
860 fwd += snprintf(buff + fwd, len - fwd, "devices {\n");
863 vector_foreach_slot (hwtable, hwe, i) {
864 fwd += snprint_hwentry(buff + fwd, len - fwd, hwe);
868 fwd += snprintf(buff + fwd, len - fwd, "}\n");
875 snprint_mpentry (char * buff, int len, struct mpentry * mpe)
880 struct keyword * rootkw;
882 rootkw = find_keyword(NULL, "multipath");
886 fwd += snprintf(buff + fwd, len - fwd, "\tmultipath {\n");
889 iterate_sub_keywords(rootkw, kw, i) {
890 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
895 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
902 snprint_mptable (char * buff, int len, vector mptable)
906 struct mpentry * mpe;
907 struct keyword * rootkw;
909 rootkw = find_keyword(NULL, "multipaths");
913 fwd += snprintf(buff + fwd, len - fwd, "multipaths {\n");
916 vector_foreach_slot (mptable, mpe, i) {
917 fwd += snprint_mpentry(buff + fwd, len - fwd, mpe);
921 fwd += snprintf(buff + fwd, len - fwd, "}\n");
928 snprint_defaults (char * buff, int len)
932 struct keyword *rootkw;
935 rootkw = find_keyword(NULL, "defaults");
939 fwd += snprintf(buff + fwd, len - fwd, "defaults {\n");
943 iterate_sub_keywords(rootkw, kw, i) {
944 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
949 fwd += snprintf(buff + fwd, len - fwd, "}\n");
956 snprint_blacklist_group (char *buff, int len, int *fwd, vector *vec)
958 int threshold = MAX_LINE_LEN;
959 struct blentry * ble;
964 if (!VECTOR_SIZE(*vec)) {
965 if ((len - pos - threshold) <= 0)
967 pos += snprintf(buff + pos, len - pos, " <empty>\n");
968 } else vector_foreach_slot (*vec, ble, i) {
969 if ((len - pos - threshold) <= 0)
971 if (ble->origin == ORIGIN_CONFIG)
972 pos += snprintf(buff + pos, len - pos, " (config file rule) ");
973 else if (ble->origin == ORIGIN_DEFAULT)
974 pos += snprintf(buff + pos, len - pos, " (default rule) ");
975 pos += snprintf(buff + pos, len - pos, "%s\n", ble->str);
983 snprint_blacklist_devgroup (char *buff, int len, int *fwd, vector *vec)
985 int threshold = MAX_LINE_LEN;
986 struct blentry_device * bled;
991 if (!VECTOR_SIZE(*vec)) {
992 if ((len - pos - threshold) <= 0)
994 pos += snprintf(buff + pos, len - pos, " <empty>\n");
995 } else vector_foreach_slot (*vec, bled, i) {
996 if ((len - pos - threshold) <= 0)
998 if (bled->origin == ORIGIN_CONFIG)
999 pos += snprintf(buff + pos, len - pos, " (config file rule) ");
1000 else if (bled->origin == ORIGIN_DEFAULT)
1001 pos += snprintf(buff + pos, len - pos, " (default rule) ");
1002 pos += snprintf(buff + pos, len - pos, "%s:%s\n", bled->vendor, bled->product);
1010 snprint_blacklist_report (char * buff, int len)
1012 int threshold = MAX_LINE_LEN;
1015 if ((len - fwd - threshold) <= 0)
1017 fwd += snprintf(buff + fwd, len - fwd, "device node rules:\n"
1019 if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_devnode))
1022 if ((len - fwd - threshold) <= 0)
1024 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1025 if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_devnode) == 0)
1028 if ((len - fwd - threshold) <= 0)
1030 fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n"
1032 if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0)
1035 if ((len - fwd - threshold) <= 0)
1037 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1038 if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_wwid) == 0)
1041 if ((len - fwd - threshold) <= 0)
1043 fwd += snprintf(buff + fwd, len - fwd, "device rules:\n"
1045 if (snprint_blacklist_devgroup(buff, len, &fwd, &conf->blist_device) == 0)
1048 if ((len - fwd - threshold) <= 0)
1050 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1051 if (snprint_blacklist_devgroup(buff, len, &fwd, &conf->elist_device) == 0)
1060 snprint_blacklist (char * buff, int len)
1063 struct blentry * ble;
1064 struct blentry_device * bled;
1066 struct keyword *rootkw;
1069 rootkw = find_keyword(NULL, "blacklist");
1073 fwd += snprintf(buff + fwd, len - fwd, "blacklist {\n");
1077 vector_foreach_slot (conf->blist_devnode, ble, i) {
1078 kw = find_keyword(rootkw->sub, "devnode");
1081 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1086 vector_foreach_slot (conf->blist_wwid, ble, i) {
1087 kw = find_keyword(rootkw->sub, "wwid");
1090 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1095 rootkw = find_keyword(rootkw->sub, "device");
1099 vector_foreach_slot (conf->blist_device, bled, i) {
1100 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
1103 kw = find_keyword(rootkw->sub, "vendor");
1106 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1110 kw = find_keyword(rootkw->sub, "product");
1113 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1117 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
1121 fwd += snprintf(buff + fwd, len - fwd, "}\n");
1128 snprint_blacklist_except (char * buff, int len)
1131 struct blentry * ele;
1132 struct blentry_device * eled;
1134 struct keyword *rootkw;
1137 rootkw = find_keyword(NULL, "blacklist_exceptions");
1141 fwd += snprintf(buff + fwd, len - fwd, "blacklist_exceptions {\n");
1145 vector_foreach_slot (conf->elist_devnode, ele, i) {
1146 kw = find_keyword(rootkw->sub, "devnode");
1149 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1154 vector_foreach_slot (conf->elist_wwid, ele, i) {
1155 kw = find_keyword(rootkw->sub, "wwid");
1158 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1163 rootkw = find_keyword(rootkw->sub, "device");
1167 vector_foreach_slot (conf->elist_device, eled, i) {
1168 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
1171 kw = find_keyword(rootkw->sub, "vendor");
1174 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1178 kw = find_keyword(rootkw->sub, "product");
1181 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1185 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
1189 fwd += snprintf(buff + fwd, len - fwd, "}\n");
1196 snprint_status (char * buff, int len, struct vectors *vecs)
1200 unsigned int count[PATH_MAX_STATE] = {0};
1203 vector_foreach_slot (vecs->pathvec, pp, i) {
1206 fwd += snprintf(buff + fwd, len - fwd, "path checker states:\n");
1207 for (i=0; i<PATH_MAX_STATE; i++) {
1210 fwd += snprintf(buff + fwd, len - fwd, "%-20s%u\n",
1211 checker_state_name(i), count[i]);
1220 snprint_devices (char * buff, int len, struct vectors *vecs)
1223 struct dirent *blkdev;
1224 struct stat statbuf;
1225 char devpath[PATH_MAX];
1227 int threshold = MAX_LINE_LEN;
1233 if (!(blkdir = opendir("/sys/block")))
1236 if ((len - fwd - threshold) <= 0)
1238 fwd += snprintf(buff + fwd, len - fwd, "available block devices:\n");
1240 strcpy(devpath,"/sys/block/");
1241 while ((blkdev = readdir(blkdir)) != NULL) {
1242 if ((strcmp(blkdev->d_name,".") == 0) ||
1243 (strcmp(blkdev->d_name,"..") == 0))
1246 devptr = devpath + 11;
1248 strncat(devptr, blkdev->d_name, PATH_MAX-12);
1249 if (stat(devpath, &statbuf) < 0)
1252 if (S_ISDIR(statbuf.st_mode) == 0)
1255 if ((len - fwd - threshold) <= 0)
1258 fwd += snprintf(buff + fwd, len - fwd, " %s", devptr);
1259 pp = find_path_by_dev(vecs->pathvec, devptr);
1261 r = filter_devnode(conf->blist_devnode,
1262 conf->elist_devnode, devptr);
1264 fwd += snprintf(buff + fwd, len - fwd,
1265 " devnode blacklisted, unmonitored");
1267 fwd += snprintf(buff + fwd, len - fwd,
1268 " devnode whitelisted, unmonitored");
1270 fwd += snprintf(buff + fwd, len - fwd,
1271 " devnode whitelisted, monitored");
1272 fwd += snprintf(buff + fwd, len - fwd, "\n");
1282 snprint_config (char * buff, int len)
1288 * stdout printing helpers
1291 print_path (struct path * pp, char * style)
1293 char line[MAX_LINE_LEN];
1295 snprint_path(&line[0], MAX_LINE_LEN, style, pp);
1300 print_multipath (struct multipath * mpp, char * style)
1302 char line[MAX_LINE_LEN];
1304 snprint_multipath(&line[0], MAX_LINE_LEN, style, mpp);
1309 print_pathgroup (struct pathgroup * pgp, char * style)
1311 char line[MAX_LINE_LEN];
1313 snprint_pathgroup(&line[0], MAX_LINE_LEN, style, pgp);
1318 print_map (struct multipath * mpp)
1320 if (mpp->size && mpp->params)
1321 printf("0 %llu %s %s\n",
1322 mpp->size, TGT_MPATH, mpp->params);
1327 print_all_paths (vector pathvec, int banner)
1329 print_all_paths_custo(pathvec, banner, PRINT_PATH_LONG);
1333 print_all_paths_custo (vector pathvec, int banner, char *fmt)
1337 char line[MAX_LINE_LEN];
1339 if (!VECTOR_SIZE(pathvec)) {
1341 fprintf(stdout, "===== no paths =====\n");
1346 fprintf(stdout, "===== paths list =====\n");
1348 get_path_layout(pathvec, 1);
1349 snprint_path_header(line, MAX_LINE_LEN, fmt);
1350 fprintf(stdout, "%s", line);
1352 vector_foreach_slot (pathvec, pp, i)
1353 print_path(pp, fmt);