2 * Copyright (c) 2005 Christophe Varoqui
6 #include <libdevmapper.h>
15 #include "structs_vec.h"
19 #include "configure.h"
20 #include "pgpolicies.h"
23 #include "blacklist.h"
24 #include "switchgroup.h"
25 #include "devmapper.h"
28 #define MAX(x,y) (x > y) ? x : y
29 #define TAIL (line + len - 1 - c)
31 #define PAD(x) while ((int)(c - s) < (x) && (c < (line + len - 1))) \
35 line[c - line - 1] = '\n'
36 #define PRINT(var, size, format, args...) \
37 fwd = snprintf(var, size, format, ##args); \
38 c += (fwd >= size) ? size : fwd;
41 * information printing helpers
44 snprint_str (char * buff, size_t len, char * str)
46 return snprintf(buff, len, "%s", str);
50 snprint_int (char * buff, size_t len, int val)
52 return snprintf(buff, len, "%i", val);
56 snprint_uint (char * buff, size_t len, unsigned int val)
58 return snprintf(buff, len, "%u", val);
62 snprint_size (char * buff, size_t len, unsigned long long size)
64 float s = (float)(size >> 1); /* start with KB */
66 char units[] = {'K','M','G','T','P'};
69 while (s >= 1024 && *u != 'P') {
74 snprintf(fmt, 6, "%%.1f%c", *u);
76 snprintf(fmt, 6, "%%.0f%c", *u);
78 return snprintf(buff, len, fmt, s);
82 * multipath info printing functions
85 snprint_name (char * buff, size_t len, struct multipath * mpp)
88 return snprintf(buff, len, "%s", mpp->alias);
90 return snprintf(buff, len, "%s", mpp->wwid);
94 snprint_sysfs (char * buff, size_t len, struct multipath * mpp)
97 return snprintf(buff, len, "dm-%i", mpp->dmi->minor);
99 return snprintf(buff, len, "undef");
103 snprint_ro (char * buff, size_t len, struct multipath * mpp)
106 return snprintf(buff, len, "undef");
107 if (mpp->dmi->read_only)
108 return snprintf(buff, len, "ro");
110 return snprintf(buff, len, "rw");
114 snprint_progress (char * buff, size_t len, int cur, int total)
117 char * end = buff + len;
120 int i = PROGRESS_LEN * cur / total;
121 int j = PROGRESS_LEN - i;
124 c += snprintf(c, len, "X");
125 if ((len = (end - c)) <= 1) goto out;
129 c += snprintf(c, len, ".");
130 if ((len = (end - c)) <= 1) goto out;
134 c += snprintf(c, len, " %i/%i", cur, total);
137 buff[c - buff + 1] = '\0';
138 return (c - buff + 1);
142 snprint_failback (char * buff, size_t len, struct multipath * mpp)
144 if (mpp->pgfailback == -FAILBACK_IMMEDIATE)
145 return snprintf(buff, len, "immediate");
147 if (!mpp->failback_tick)
148 return snprintf(buff, len, "-");
150 return snprint_progress(buff, len, mpp->failback_tick,
155 snprint_queueing (char * buff, size_t len, struct multipath * mpp)
157 if (mpp->no_path_retry == NO_PATH_RETRY_FAIL)
158 return snprintf(buff, len, "off");
159 else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE)
160 return snprintf(buff, len, "on");
161 else if (mpp->no_path_retry == NO_PATH_RETRY_UNDEF)
162 return snprintf(buff, len, "-");
163 else if (mpp->no_path_retry > 0) {
165 return snprintf(buff, len, "%i sec",
168 return snprintf(buff, len, "%i chk",
175 snprint_nb_paths (char * buff, size_t len, struct multipath * mpp)
177 return snprint_int(buff, len, mpp->nr_active);
181 snprint_dm_map_state (char * buff, size_t len, struct multipath * mpp)
183 if (mpp->dmi && mpp->dmi->suspended)
184 return snprintf(buff, len, "suspend");
186 return snprintf(buff, len, "active");
190 snprint_multipath_size (char * buff, size_t len, struct multipath * mpp)
192 return snprint_size(buff, len, mpp->size);
196 snprint_features (char * buff, size_t len, struct multipath * mpp)
198 return snprint_str(buff, len, mpp->features);
202 snprint_hwhandler (char * buff, size_t len, struct multipath * mpp)
204 return snprint_str(buff, len, mpp->hwhandler);
208 snprint_path_faults (char * buff, size_t len, struct multipath * mpp)
210 return snprint_uint(buff, len, mpp->stat_path_failures);
214 snprint_switch_grp (char * buff, size_t len, struct multipath * mpp)
216 return snprint_uint(buff, len, mpp->stat_switchgroup);
220 snprint_map_loads (char * buff, size_t len, struct multipath * mpp)
222 return snprint_uint(buff, len, mpp->stat_map_loads);
226 snprint_total_q_time (char * buff, size_t len, struct multipath * mpp)
228 return snprint_uint(buff, len, mpp->stat_total_queueing_time);
232 snprint_q_timeouts (char * buff, size_t len, struct multipath * mpp)
234 return snprint_uint(buff, len, mpp->stat_queueing_timeouts);
238 snprint_multipath_uuid (char * buff, size_t len, struct multipath * mpp)
240 return snprint_str(buff, len, mpp->wwid);
244 snprint_multipath_vpr (char * buff, size_t len, struct multipath * mpp)
246 struct path * pp = first_path(mpp);
249 return snprintf(buff, len, "%s,%s",
250 pp->vendor_id, pp->product_id);
254 snprint_action (char * buff, size_t len, struct multipath * mpp)
256 switch (mpp->action) {
258 return snprint_str(buff, len, ACT_REJECT_STR);
260 return snprint_str(buff, len, ACT_RENAME_STR);
262 return snprint_str(buff, len, ACT_RELOAD_STR);
264 return snprint_str(buff, len, ACT_CREATE_STR);
266 return snprint_str(buff, len, ACT_SWITCHPG_STR);
273 * path info printing functions
276 snprint_path_uuid (char * buff, size_t len, struct path * pp)
278 return snprint_str(buff, len, pp->wwid);
282 snprint_hcil (char * buff, size_t len, struct path * pp)
284 if (pp->sg_id.host_no < 0)
285 return snprintf(buff, len, "#:#:#:#");
287 return snprintf(buff, len, "%i:%i:%i:%i",
295 snprint_dev (char * buff, size_t len, struct path * pp)
297 if (!strlen(pp->dev))
298 return snprintf(buff, len, "-");
300 return snprint_str(buff, len, pp->dev);
304 snprint_dev_t (char * buff, size_t len, struct path * pp)
306 if (!strlen(pp->dev))
307 return snprintf(buff, len, "#:#");
309 return snprint_str(buff, len, pp->dev_t);
313 snprint_offline (char * buff, size_t len, struct path * pp)
316 return snprintf(buff, len, "offline");
318 return snprintf(buff, len, "running");
322 snprint_chk_state (char * buff, size_t len, struct path * pp)
326 return snprintf(buff, len, "ready");
328 return snprintf(buff, len, "faulty");
330 return snprintf(buff, len, "shaky");
332 return snprintf(buff, len, "ghost");
334 return snprintf(buff, len, "undef");
339 snprint_dm_path_state (char * buff, size_t len, struct path * pp)
341 switch (pp->dmstate) {
343 return snprintf(buff, len, "active");
345 return snprintf(buff, len, "failed");
347 return snprintf(buff, len, "undef");
352 snprint_vpr (char * buff, size_t len, struct path * pp)
354 return snprintf(buff, len, "%s,%s",
355 pp->vendor_id, pp->product_id);
359 snprint_next_check (char * buff, size_t len, struct path * pp)
362 return snprintf(buff, len, "orphan");
364 return snprint_progress(buff, len, pp->tick, pp->checkint);
368 snprint_pri (char * buff, size_t len, struct path * pp)
370 return snprint_int(buff, len, pp->priority);
374 snprint_pg_selector (char * buff, size_t len, struct pathgroup * pgp)
376 return snprint_str(buff, len, pgp->selector);
380 snprint_pg_pri (char * buff, size_t len, struct pathgroup * pgp)
382 int avg_priority = 0;
384 * path group priority is not updated for every path prio change,
385 * but only on switch group code path.
387 * Printing is another reason to update.
389 path_group_prio_update(pgp);
390 if (pgp->enabled_paths)
391 avg_priority = pgp->priority / pgp->enabled_paths;
392 return snprint_int(buff, len, avg_priority);
396 snprint_pg_state (char * buff, size_t len, struct pathgroup * pgp)
398 switch (pgp->status) {
399 case PGSTATE_ENABLED:
400 return snprintf(buff, len, "enabled");
401 case PGSTATE_DISABLED:
402 return snprintf(buff, len, "disabled");
404 return snprintf(buff, len, "active");
406 return snprintf(buff, len, "undef");
411 snprint_path_size (char * buff, size_t len, struct path * pp)
413 return snprint_size(buff, len, pp->size);
417 snprint_path_serial (char * buff, size_t len, struct path * pp)
419 return snprint_str(buff, len, pp->serial);
423 snprint_path_checker (char * buff, size_t len, struct path * pp)
425 struct checker * c = &pp->checker;
426 return snprint_str(buff, len, c->name);
429 struct multipath_data mpd[] = {
430 {'n', "name", 0, snprint_name},
431 {'w', "uuid", 0, snprint_multipath_uuid},
432 {'d', "sysfs", 0, snprint_sysfs},
433 {'F', "failback", 0, snprint_failback},
434 {'Q', "queueing", 0, snprint_queueing},
435 {'N', "paths", 0, snprint_nb_paths},
436 {'r', "write_prot", 0, snprint_ro},
437 {'t', "dm-st", 0, snprint_dm_map_state},
438 {'S', "size", 0, snprint_multipath_size},
439 {'f', "features", 0, snprint_features},
440 {'h', "hwhandler", 0, snprint_hwhandler},
441 {'A', "action", 0, snprint_action},
442 {'0', "path_faults", 0, snprint_path_faults},
443 {'1', "switch_grp", 0, snprint_switch_grp},
444 {'2', "map_loads", 0, snprint_map_loads},
445 {'3', "total_q_time", 0, snprint_total_q_time},
446 {'4', "q_timeouts", 0, snprint_q_timeouts},
447 {'s', "vend/prod/rev", 0, snprint_multipath_vpr},
451 struct path_data pd[] = {
452 {'w', "uuid", 0, snprint_path_uuid},
453 {'i', "hcil", 0, snprint_hcil},
454 {'d', "dev", 0, snprint_dev},
455 {'D', "dev_t", 0, snprint_dev_t},
456 {'t', "dm_st", 0, snprint_dm_path_state},
457 {'o', "dev_st", 0, snprint_offline},
458 {'T', "chk_st", 0, snprint_chk_state},
459 {'s', "vend/prod/rev", 0, snprint_vpr},
460 {'c', "checker", 0, snprint_path_checker},
461 {'C', "next_check", 0, snprint_next_check},
462 {'p', "pri", 0, snprint_pri},
463 {'S', "size", 0, snprint_path_size},
464 {'z', "serial", 0, snprint_path_serial},
468 struct pathgroup_data pgd[] = {
469 {'s', "selector", 0, snprint_pg_selector},
470 {'p', "pri", 0, snprint_pg_pri},
471 {'t', "dm_st", 0, snprint_pg_state},
476 snprint_wildcards (char * buff, int len)
480 fwd += snprintf(buff + fwd, len - fwd, "multipath format wildcards:\n");
481 for (i = 0; mpd[i].header; i++)
482 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
483 mpd[i].wildcard, mpd[i].header);
484 fwd += snprintf(buff + fwd, len - fwd, "\npath format wildcards:\n");
485 for (i = 0; pd[i].header; i++)
486 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
487 pd[i].wildcard, pd[i].header);
488 fwd += snprintf(buff + fwd, len - fwd, "\npathgroup format wildcards:\n");
489 for (i = 0; pgd[i].header; i++)
490 fwd += snprintf(buff + fwd, len - fwd, "%%%c %s\n",
491 pgd[i].wildcard, pgd[i].header);
496 get_path_layout (vector pathvec, int header)
499 char buff[MAX_FIELD_LEN];
502 for (j = 0; pd[j].header; j++) {
504 pd[j].width = strlen(pd[j].header);
508 vector_foreach_slot (pathvec, pp, i) {
509 pd[j].snprint(buff, MAX_FIELD_LEN, pp);
510 pd[j].width = MAX(pd[j].width, strlen(buff));
516 reset_multipath_layout (void)
520 for (i = 0; mpd[i].header; i++)
525 get_multipath_layout (vector mpvec, int header)
528 char buff[MAX_FIELD_LEN];
529 struct multipath * mpp;
531 for (j = 0; mpd[j].header; j++) {
533 mpd[j].width = strlen(mpd[j].header);
537 vector_foreach_slot (mpvec, mpp, i) {
538 mpd[j].snprint(buff, MAX_FIELD_LEN, mpp);
539 mpd[j].width = MAX(mpd[j].width, strlen(buff));
544 static struct multipath_data *
545 mpd_lookup(char wildcard)
549 for (i = 0; mpd[i].header; i++)
550 if (mpd[i].wildcard == wildcard)
556 static struct path_data *
557 pd_lookup(char wildcard)
561 for (i = 0; pd[i].header; i++)
562 if (pd[i].wildcard == wildcard)
568 static struct pathgroup_data *
569 pgd_lookup(char wildcard)
573 for (i = 0; pgd[i].header; i++)
574 if (pgd[i].wildcard == wildcard)
581 snprint_multipath_header (char * line, int len, char * format)
583 char * c = line; /* line cursor */
584 char * s = line; /* for padding */
585 char * f = format; /* format string cursor */
587 struct multipath_data * data;
589 memset(line, 0, len);
602 if (!(data = mpd_lookup(*f)))
603 continue; /* unknown wildcard */
605 PRINT(c, TAIL, "%s", data->header);
614 snprint_multipath (char * line, int len, char * format,
615 struct multipath * mpp)
617 char * c = line; /* line cursor */
618 char * s = line; /* for padding */
619 char * f = format; /* format string cursor */
621 struct multipath_data * data;
622 char buff[MAX_FIELD_LEN] = {};
624 memset(line, 0, len);
637 if (!(data = mpd_lookup(*f)))
640 data->snprint(buff, MAX_FIELD_LEN, mpp);
641 PRINT(c, TAIL, "%s", buff);
651 snprint_path_header (char * line, int len, char * format)
653 char * c = line; /* line cursor */
654 char * s = line; /* for padding */
655 char * f = format; /* format string cursor */
657 struct path_data * data;
659 memset(line, 0, len);
672 if (!(data = pd_lookup(*f)))
673 continue; /* unknown wildcard */
675 PRINT(c, TAIL, "%s", data->header);
684 snprint_path (char * line, int len, char * format,
687 char * c = line; /* line cursor */
688 char * s = line; /* for padding */
689 char * f = format; /* format string cursor */
691 struct path_data * data;
692 char buff[MAX_FIELD_LEN];
694 memset(line, 0, len);
707 if (!(data = pd_lookup(*f)))
710 data->snprint(buff, MAX_FIELD_LEN, pp);
711 PRINT(c, TAIL, "%s", buff);
720 snprint_pathgroup (char * line, int len, char * format,
721 struct pathgroup * pgp)
723 char * c = line; /* line cursor */
724 char * s = line; /* for padding */
725 char * f = format; /* format string cursor */
727 struct pathgroup_data * data;
728 char buff[MAX_FIELD_LEN];
730 memset(line, 0, len);
743 if (!(data = pgd_lookup(*f)))
746 data->snprint(buff, MAX_FIELD_LEN, pgp);
747 PRINT(c, TAIL, "%s", buff);
756 print_multipath_topology (struct multipath * mpp, int verbosity)
758 char buff[MAX_LINE_LEN * MAX_LINES] = {};
760 memset(&buff[0], 0, MAX_LINE_LEN * MAX_LINES);
761 snprint_multipath_topology(&buff[0], MAX_LINE_LEN * MAX_LINES,
767 snprint_multipath_topology (char * buff, int len, struct multipath * mpp,
771 struct path * pp = NULL;
772 struct pathgroup * pgp = NULL;
781 reset_multipath_layout();
784 return snprint_multipath(buff, len, "%n", mpp);
787 c += sprintf(c, "%c[%dm", 0x1B, 1); /* bold on */
790 mpp->action != ACT_NOTHING &&
791 mpp->action != ACT_UNDEF)
792 c += sprintf(c, "%%A: ");
794 c += sprintf(c, "%%n");
796 if (strncmp(mpp->alias, mpp->wwid, WWID_SIZE))
797 c += sprintf(c, " (%%w)");
799 c += sprintf(c, " %%d %%s");
801 c += sprintf(c, "%c[%dm", 0x1B, 0); /* bold off */
803 fwd += snprint_multipath(buff + fwd, len - fwd, style, mpp);
806 fwd += snprint_multipath(buff + fwd, len - fwd, PRINT_MAP_PROPS, mpp);
813 vector_foreach_slot (mpp->pg, pgp, j) {
815 pgp->selector = mpp->selector; /* hack */
816 if (j + 1 < VECTOR_SIZE(mpp->pg)) {
817 strcpy(f, "|-+- " PRINT_PG_INDENT);
819 strcpy(f, "`-+- " PRINT_PG_INDENT);
820 fwd += snprint_pathgroup(buff + fwd, len - fwd, fmt, pgp);
824 vector_foreach_slot (pgp->paths, pp, i) {
829 if (i + 1 < VECTOR_SIZE(pgp->paths))
830 strcpy(f, " |- " PRINT_PATH_INDENT);
832 strcpy(f, " `- " PRINT_PATH_INDENT);
833 fwd += snprint_path(buff + fwd, len - fwd, fmt, pp);
842 snprint_hwentry (char * buff, int len, struct hwentry * hwe)
847 struct keyword * rootkw;
849 rootkw = find_keyword(NULL, "devices");
851 if (!rootkw || !rootkw->sub)
854 rootkw = find_keyword(rootkw->sub, "device");
859 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
862 iterate_sub_keywords(rootkw, kw, i) {
863 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
868 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
875 snprint_hwtable (char * buff, int len, vector hwtable)
879 struct hwentry * hwe;
880 struct keyword * rootkw;
882 rootkw = find_keyword(NULL, "devices");
886 fwd += snprintf(buff + fwd, len - fwd, "devices {\n");
889 vector_foreach_slot (hwtable, hwe, i) {
890 fwd += snprint_hwentry(buff + fwd, len - fwd, hwe);
894 fwd += snprintf(buff + fwd, len - fwd, "}\n");
901 snprint_mpentry (char * buff, int len, struct mpentry * mpe)
906 struct keyword * rootkw;
908 rootkw = find_keyword(NULL, "multipath");
912 fwd += snprintf(buff + fwd, len - fwd, "\tmultipath {\n");
915 iterate_sub_keywords(rootkw, kw, i) {
916 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
921 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
928 snprint_mptable (char * buff, int len, vector mptable)
932 struct mpentry * mpe;
933 struct keyword * rootkw;
935 rootkw = find_keyword(NULL, "multipaths");
939 fwd += snprintf(buff + fwd, len - fwd, "multipaths {\n");
942 vector_foreach_slot (mptable, mpe, i) {
943 fwd += snprint_mpentry(buff + fwd, len - fwd, mpe);
947 fwd += snprintf(buff + fwd, len - fwd, "}\n");
954 snprint_defaults (char * buff, int len)
958 struct keyword *rootkw;
961 rootkw = find_keyword(NULL, "defaults");
965 fwd += snprintf(buff + fwd, len - fwd, "defaults {\n");
969 iterate_sub_keywords(rootkw, kw, i) {
970 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
975 fwd += snprintf(buff + fwd, len - fwd, "}\n");
982 snprint_blacklist_group (char *buff, int len, int *fwd, vector *vec)
984 int threshold = MAX_LINE_LEN;
985 struct blentry * ble;
990 if (!VECTOR_SIZE(*vec)) {
991 if ((len - pos - threshold) <= 0)
993 pos += snprintf(buff + pos, len - pos, " <empty>\n");
994 } else vector_foreach_slot (*vec, ble, i) {
995 if ((len - pos - threshold) <= 0)
997 if (ble->origin == ORIGIN_CONFIG)
998 pos += snprintf(buff + pos, len - pos, " (config file rule) ");
999 else if (ble->origin == ORIGIN_DEFAULT)
1000 pos += snprintf(buff + pos, len - pos, " (default rule) ");
1001 pos += snprintf(buff + pos, len - pos, "%s\n", ble->str);
1009 snprint_blacklist_devgroup (char *buff, int len, int *fwd, vector *vec)
1011 int threshold = MAX_LINE_LEN;
1012 struct blentry_device * bled;
1017 if (!VECTOR_SIZE(*vec)) {
1018 if ((len - pos - threshold) <= 0)
1020 pos += snprintf(buff + pos, len - pos, " <empty>\n");
1021 } else vector_foreach_slot (*vec, bled, i) {
1022 if ((len - pos - threshold) <= 0)
1024 if (bled->origin == ORIGIN_CONFIG)
1025 pos += snprintf(buff + pos, len - pos, " (config file rule) ");
1026 else if (bled->origin == ORIGIN_DEFAULT)
1027 pos += snprintf(buff + pos, len - pos, " (default rule) ");
1028 pos += snprintf(buff + pos, len - pos, "%s:%s\n", bled->vendor, bled->product);
1036 snprint_blacklist_report (char * buff, int len)
1038 int threshold = MAX_LINE_LEN;
1041 if ((len - fwd - threshold) <= 0)
1043 fwd += snprintf(buff + fwd, len - fwd, "device node rules:\n"
1045 if (!snprint_blacklist_group(buff, len, &fwd, &conf->blist_devnode))
1048 if ((len - fwd - threshold) <= 0)
1050 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1051 if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_devnode) == 0)
1054 if ((len - fwd - threshold) <= 0)
1056 fwd += snprintf(buff + fwd, len - fwd, "wwid rules:\n"
1058 if (snprint_blacklist_group(buff, len, &fwd, &conf->blist_wwid) == 0)
1061 if ((len - fwd - threshold) <= 0)
1063 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1064 if (snprint_blacklist_group(buff, len, &fwd, &conf->elist_wwid) == 0)
1067 if ((len - fwd - threshold) <= 0)
1069 fwd += snprintf(buff + fwd, len - fwd, "device rules:\n"
1071 if (snprint_blacklist_devgroup(buff, len, &fwd, &conf->blist_device) == 0)
1074 if ((len - fwd - threshold) <= 0)
1076 fwd += snprintf(buff + fwd, len - fwd, "- exceptions:\n");
1077 if (snprint_blacklist_devgroup(buff, len, &fwd, &conf->elist_device) == 0)
1086 snprint_blacklist (char * buff, int len)
1089 struct blentry * ble;
1090 struct blentry_device * bled;
1092 struct keyword *rootkw;
1095 rootkw = find_keyword(NULL, "blacklist");
1099 fwd += snprintf(buff + fwd, len - fwd, "blacklist {\n");
1103 vector_foreach_slot (conf->blist_devnode, ble, i) {
1104 kw = find_keyword(rootkw->sub, "devnode");
1107 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1112 vector_foreach_slot (conf->blist_wwid, ble, i) {
1113 kw = find_keyword(rootkw->sub, "wwid");
1116 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1121 rootkw = find_keyword(rootkw->sub, "device");
1125 vector_foreach_slot (conf->blist_device, bled, i) {
1126 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
1129 kw = find_keyword(rootkw->sub, "vendor");
1132 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1136 kw = find_keyword(rootkw->sub, "product");
1139 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1143 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
1147 fwd += snprintf(buff + fwd, len - fwd, "}\n");
1154 snprint_blacklist_except (char * buff, int len)
1157 struct blentry * ele;
1158 struct blentry_device * eled;
1160 struct keyword *rootkw;
1163 rootkw = find_keyword(NULL, "blacklist_exceptions");
1167 fwd += snprintf(buff + fwd, len - fwd, "blacklist_exceptions {\n");
1171 vector_foreach_slot (conf->elist_devnode, ele, i) {
1172 kw = find_keyword(rootkw->sub, "devnode");
1175 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1180 vector_foreach_slot (conf->elist_wwid, ele, i) {
1181 kw = find_keyword(rootkw->sub, "wwid");
1184 fwd += snprint_keyword(buff + fwd, len - fwd, "\t%k %v\n",
1189 rootkw = find_keyword(rootkw->sub, "device");
1193 vector_foreach_slot (conf->elist_device, eled, i) {
1194 fwd += snprintf(buff + fwd, len - fwd, "\tdevice {\n");
1197 kw = find_keyword(rootkw->sub, "vendor");
1200 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1204 kw = find_keyword(rootkw->sub, "product");
1207 fwd += snprint_keyword(buff + fwd, len - fwd, "\t\t%k %v\n",
1211 fwd += snprintf(buff + fwd, len - fwd, "\t}\n");
1215 fwd += snprintf(buff + fwd, len - fwd, "}\n");
1222 snprint_status (char * buff, int len, struct vectors *vecs)
1226 unsigned int count[PATH_MAX_STATE] = {0};
1229 vector_foreach_slot (vecs->pathvec, pp, i) {
1232 fwd += snprintf(buff + fwd, len - fwd, "path checker states:\n");
1233 for (i=0; i<PATH_MAX_STATE; i++) {
1236 fwd += snprintf(buff + fwd, len - fwd, "%-20s%u\n",
1237 checker_state_name(i), count[i]);
1240 int monitored_count = 0;
1242 vector_foreach_slot(vecs->pathvec, pp, i)
1245 fwd += snprintf(buff + fwd, len - fwd, "\npaths: %d\nbusy: %s\n",
1246 monitored_count, is_uevent_busy()? "True" : "False");
1254 snprint_devices (char * buff, int len, struct vectors *vecs)
1257 struct dirent *blkdev;
1258 struct stat statbuf;
1259 char devpath[PATH_MAX];
1261 int threshold = MAX_LINE_LEN;
1267 if (!(blkdir = opendir("/sys/block")))
1270 if ((len - fwd - threshold) <= 0)
1272 fwd += snprintf(buff + fwd, len - fwd, "available block devices:\n");
1274 strcpy(devpath,"/sys/block/");
1275 while ((blkdev = readdir(blkdir)) != NULL) {
1276 if ((strcmp(blkdev->d_name,".") == 0) ||
1277 (strcmp(blkdev->d_name,"..") == 0))
1280 devptr = devpath + 11;
1282 strncat(devptr, blkdev->d_name, PATH_MAX-12);
1283 if (stat(devpath, &statbuf) < 0)
1286 if (S_ISDIR(statbuf.st_mode) == 0)
1289 if ((len - fwd - threshold) <= 0)
1292 fwd += snprintf(buff + fwd, len - fwd, " %s", devptr);
1293 pp = find_path_by_dev(vecs->pathvec, devptr);
1295 r = filter_devnode(conf->blist_devnode,
1296 conf->elist_devnode, devptr);
1298 fwd += snprintf(buff + fwd, len - fwd,
1299 " devnode blacklisted, unmonitored");
1301 fwd += snprintf(buff + fwd, len - fwd,
1302 " devnode whitelisted, unmonitored");
1304 fwd += snprintf(buff + fwd, len - fwd,
1305 " devnode whitelisted, monitored");
1306 fwd += snprintf(buff + fwd, len - fwd, "\n");
1316 snprint_config (char * buff, int len)
1322 * stdout printing helpers
1325 print_path (struct path * pp, char * style)
1327 char line[MAX_LINE_LEN];
1329 memset(&line[0], 0, MAX_LINE_LEN);
1330 snprint_path(&line[0], MAX_LINE_LEN, style, pp);
1335 print_multipath (struct multipath * mpp, char * style)
1337 char line[MAX_LINE_LEN];
1339 memset(&line[0], 0, MAX_LINE_LEN);
1340 snprint_multipath(&line[0], MAX_LINE_LEN, style, mpp);
1345 print_pathgroup (struct pathgroup * pgp, char * style)
1347 char line[MAX_LINE_LEN];
1349 memset(&line[0], 0, MAX_LINE_LEN);
1350 snprint_pathgroup(&line[0], MAX_LINE_LEN, style, pgp);
1355 print_map (struct multipath * mpp, char * params)
1357 if (mpp->size && params)
1358 printf("0 %llu %s %s\n",
1359 mpp->size, TGT_MPATH, params);
1364 print_all_paths (vector pathvec, int banner)
1366 print_all_paths_custo(pathvec, banner, PRINT_PATH_LONG);
1370 print_all_paths_custo (vector pathvec, int banner, char *fmt)
1374 char line[MAX_LINE_LEN];
1376 if (!VECTOR_SIZE(pathvec)) {
1378 fprintf(stdout, "===== no paths =====\n");
1383 fprintf(stdout, "===== paths list =====\n");
1385 get_path_layout(pathvec, 1);
1386 snprint_path_header(line, MAX_LINE_LEN, fmt);
1387 fprintf(stdout, "%s", line);
1389 vector_foreach_slot (pathvec, pp, i)
1390 print_path(pp, fmt);