Blame SOURCES/0169-UPBZ-1353357-json-output.patch

c896fb
---
c896fb
 libmultipath/print.c      |  222 ++++++++++++++++++++++++++++++++++++++++++++++
c896fb
 libmultipath/print.h      |   61 ++++++++++++
c896fb
 multipathd/cli.c          |    3 
c896fb
 multipathd/cli.h          |    2 
c896fb
 multipathd/cli_handlers.c |   93 +++++++++++++++++++
c896fb
 multipathd/cli_handlers.h |    2 
c896fb
 multipathd/main.c         |    2 
c896fb
 multipathd/multipathd.8   |    9 +
c896fb
 8 files changed, 393 insertions(+), 1 deletion(-)
c896fb
c896fb
Index: multipath-tools-130222/libmultipath/print.c
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/libmultipath/print.c
c896fb
+++ multipath-tools-130222/libmultipath/print.c
c896fb
@@ -269,6 +269,61 @@ snprint_multipath_vpr (char * buff, size
c896fb
 			pp->vendor_id, pp->product_id);
c896fb
 }
c896fb
 
c896fb
+
c896fb
+static int
c896fb
+snprint_multipath_vend (char * buff, size_t len, struct multipath * mpp)
c896fb
+{
c896fb
+	struct pathgroup * pgp;
c896fb
+	struct path * pp;
c896fb
+	int i, j;
c896fb
+
c896fb
+	vector_foreach_slot(mpp->pg, pgp, i) {
c896fb
+		if (!pgp)
c896fb
+			continue;
c896fb
+		vector_foreach_slot(pgp->paths, pp, j) {
c896fb
+			if (strlen(pp->vendor_id))
c896fb
+				return snprintf(buff, len, "%s", pp->vendor_id);
c896fb
+		}
c896fb
+	}
c896fb
+	return snprintf(buff, len, "##");
c896fb
+}
c896fb
+
c896fb
+static int
c896fb
+snprint_multipath_prod (char * buff, size_t len, struct multipath * mpp)
c896fb
+{
c896fb
+	struct pathgroup * pgp;
c896fb
+	struct path * pp;
c896fb
+	int i, j;
c896fb
+
c896fb
+	vector_foreach_slot(mpp->pg, pgp, i) {
c896fb
+		if (!pgp)
c896fb
+			continue;
c896fb
+		vector_foreach_slot(pgp->paths, pp, j) {
c896fb
+			if (strlen(pp->product_id))
c896fb
+				return snprintf(buff, len, "%s", pp->product_id);
c896fb
+		}
c896fb
+	}
c896fb
+	return snprintf(buff, len, "##");
c896fb
+}
c896fb
+
c896fb
+static int
c896fb
+snprint_multipath_rev (char * buff, size_t len, struct multipath * mpp)
c896fb
+{
c896fb
+	struct pathgroup * pgp;
c896fb
+	struct path * pp;
c896fb
+	int i, j;
c896fb
+
c896fb
+	vector_foreach_slot(mpp->pg, pgp, i) {
c896fb
+		if (!pgp)
c896fb
+			continue;
c896fb
+		vector_foreach_slot(pgp->paths, pp, j) {
c896fb
+			if (strlen(pp->rev))
c896fb
+				return snprintf(buff, len, "%s", pp->rev);
c896fb
+		}
c896fb
+	}
c896fb
+	return snprintf(buff, len, "##");
c896fb
+}
c896fb
+
c896fb
 static int
c896fb
 snprint_action (char * buff, size_t len, struct multipath * mpp)
c896fb
 {
c896fb
@@ -561,6 +616,9 @@ struct multipath_data mpd[] = {
c896fb
 	{'3', "total_q_time",  0, snprint_total_q_time},
c896fb
 	{'4', "q_timeouts",    0, snprint_q_timeouts},
c896fb
 	{'s', "vend/prod/rev", 0, snprint_multipath_vpr},
c896fb
+	{'v', "vend",          0, snprint_multipath_vend},
c896fb
+	{'p', "prod",          0, snprint_multipath_prod},
c896fb
+	{'e', "rev",           0, snprint_multipath_rev},
c896fb
 	{0, NULL, 0 , NULL}
c896fb
 };
c896fb
 
c896fb
@@ -983,6 +1041,170 @@ snprint_multipath_topology (char * buff,
c896fb
 	return fwd;
c896fb
 }
c896fb
 
c896fb
+static int
c896fb
+snprint_json (char * buff, int len, int indent, char *json_str)
c896fb
+{
c896fb
+	int fwd = 0, i;
c896fb
+
c896fb
+	for (i = 0; i < indent; i++) {
c896fb
+		fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+	}
c896fb
+
c896fb
+	fwd += snprintf(buff + fwd, len - fwd, "%s", json_str);
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
+static int
c896fb
+snprint_json_header (char * buff, int len)
c896fb
+{
c896fb
+	int fwd = 0;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff, len, 0, PRINT_JSON_START_ELEM);
c896fb
+	if (fwd > len)
c896fb
+		return fwd;
c896fb
+
c896fb
+	fwd +=  snprintf(buff + fwd, len  - fwd, PRINT_JSON_START_VERSION,
c896fb
+			PRINT_JSON_MAJOR_VERSION, PRINT_JSON_MINOR_VERSION);
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
+static int
c896fb
+snprint_json_elem_footer (char * buff, int len, int indent, int last)
c896fb
+{
c896fb
+	int fwd = 0, i;
c896fb
+
c896fb
+	for (i = 0; i < indent; i++) {
c896fb
+		fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_INDENT);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+	}
c896fb
+
c896fb
+	if (last == 1)
c896fb
+		fwd += snprintf(buff + fwd, len - fwd, "%s", PRINT_JSON_END_LAST_ELEM);
c896fb
+	else
c896fb
+		fwd += snprintf(buff + fwd, len - fwd, "%s", PRINT_JSON_END_ELEM);
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
+static int
c896fb
+snprint_multipath_fields_json (char * buff, int len,
c896fb
+		struct multipath * mpp, int last)
c896fb
+{
c896fb
+	int i, j, fwd = 0;
c896fb
+	struct path *pp;
c896fb
+	struct pathgroup *pgp;
c896fb
+
c896fb
+	fwd += snprint_multipath(buff, len, PRINT_JSON_MAP, mpp, 0);
c896fb
+	if (fwd > len)
c896fb
+		return fwd;
c896fb
+
c896fb
+	fwd += snprint_json(buff + fwd, len - fwd, 2, PRINT_JSON_START_GROUPS);
c896fb
+	if (fwd > len)
c896fb
+		return fwd;
c896fb
+
c896fb
+	vector_foreach_slot (mpp->pg, pgp, i) {
c896fb
+
c896fb
+		pgp->selector = mpp->selector;
c896fb
+		fwd += snprint_pathgroup(buff + fwd, len - fwd, PRINT_JSON_GROUP, pgp);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+
c896fb
+		fwd += snprintf(buff + fwd, len - fwd, PRINT_JSON_GROUP_NUM, i + 1);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+
c896fb
+		fwd += snprint_json(buff + fwd, len - fwd, 3, PRINT_JSON_START_PATHS);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+
c896fb
+		vector_foreach_slot (pgp->paths, pp, j) {
c896fb
+			fwd += snprint_path(buff + fwd, len - fwd, PRINT_JSON_PATH, pp, 0);
c896fb
+			if (fwd > len)
c896fb
+				return fwd;
c896fb
+
c896fb
+			fwd += snprint_json_elem_footer(buff + fwd,
c896fb
+					len - fwd, 3, j + 1 == VECTOR_SIZE(pgp->paths));
c896fb
+			if (fwd > len)
c896fb
+				return fwd;
c896fb
+		}
c896fb
+		fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY);
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+
c896fb
+		fwd +=  snprint_json_elem_footer(buff + fwd,
c896fb
+				len - fwd, 2, i + 1 == VECTOR_SIZE(mpp->pg));
c896fb
+		if (fwd > len)
c896fb
+			return fwd;
c896fb
+	}
c896fb
+
c896fb
+	fwd += snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY);
c896fb
+	if (fwd > len)
c896fb
+		return fwd;
c896fb
+
c896fb
+	fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 1, last);
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
+int
c896fb
+snprint_multipath_map_json (char * buff, int len,
c896fb
+		struct multipath * mpp, int last){
c896fb
+	int fwd = 0;
c896fb
+
c896fb
+	fwd +=  snprint_json_header(buff, len);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_START_MAP);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd += snprint_multipath_fields_json(buff + fwd, len - fwd, mpp, 1);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len - fwd, 0, "\n");
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
+int
c896fb
+snprint_multipath_topology_json (char * buff, int len, struct vectors * vecs)
c896fb
+{
c896fb
+	int i, fwd = 0;
c896fb
+	struct multipath * mpp;
c896fb
+
c896fb
+	fwd +=  snprint_json_header(buff, len);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len  - fwd, 1, PRINT_JSON_START_MAPS);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	vector_foreach_slot(vecs->mpvec, mpp, i) {
c896fb
+		fwd += snprint_multipath_fields_json(buff + fwd, len - fwd,
c896fb
+				mpp, i + 1 == VECTOR_SIZE(vecs->mpvec));
c896fb
+		if (fwd > len)
c896fb
+			return len;
c896fb
+	}
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_ARRAY);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+
c896fb
+	fwd +=  snprint_json(buff + fwd, len - fwd, 0, PRINT_JSON_END_LAST);
c896fb
+	if (fwd > len)
c896fb
+		return len;
c896fb
+	return fwd;
c896fb
+}
c896fb
+
c896fb
 static int
c896fb
 snprint_hwentry (char * buff, int len, struct hwentry * hwe)
c896fb
 {
c896fb
Index: multipath-tools-130222/libmultipath/print.h
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/libmultipath/print.h
c896fb
+++ multipath-tools-130222/libmultipath/print.h
c896fb
@@ -7,6 +7,63 @@
c896fb
 #define PRINT_MAP_PROPS      "size=%S features='%f' hwhandler='%h' wp=%r"
c896fb
 #define PRINT_PG_INDENT      "policy='%s' prio=%p status=%t"
c896fb
 
c896fb
+#define PRINT_JSON_MULTIPLIER     5
c896fb
+#define PRINT_JSON_MAJOR_VERSION  0
c896fb
+#define PRINT_JSON_MINOR_VERSION  1
c896fb
+#define PRINT_JSON_START_VERSION  "   \"major_version\": %d,\n" \
c896fb
+                                  "   \"minor_version\": %d,\n"
c896fb
+#define PRINT_JSON_START_ELEM     "{\n"
c896fb
+#define PRINT_JSON_START_MAP      "   \"map\":"
c896fb
+#define PRINT_JSON_START_MAPS     "\"maps\": ["
c896fb
+#define PRINT_JSON_START_PATHS    "\"paths\": ["
c896fb
+#define PRINT_JSON_START_GROUPS   "\"path_groups\": ["
c896fb
+#define PRINT_JSON_END_ELEM       "},"
c896fb
+#define PRINT_JSON_END_LAST_ELEM  "}"
c896fb
+#define PRINT_JSON_END_LAST       "}\n"
c896fb
+#define PRINT_JSON_END_ARRAY      "]\n"
c896fb
+#define PRINT_JSON_INDENT    "   "
c896fb
+#define PRINT_JSON_MAP       "{\n" \
c896fb
+                             "      \"name\" : \"%n\",\n" \
c896fb
+                             "      \"uuid\" : \"%w\",\n" \
c896fb
+                             "      \"sysfs\" : \"%d\",\n" \
c896fb
+                             "      \"failback\" : \"%F\",\n" \
c896fb
+                             "      \"queueing\" : \"%Q\",\n" \
c896fb
+                             "      \"paths\" : %N,\n" \
c896fb
+                             "      \"write_prot\" : \"%r\",\n" \
c896fb
+                             "      \"dm_st\" : \"%t\",\n" \
c896fb
+                             "      \"features\" : \"%f\",\n" \
c896fb
+                             "      \"hwhandler\" : \"%h\",\n" \
c896fb
+                             "      \"action\" : \"%A\",\n" \
c896fb
+                             "      \"path_faults\" : %0,\n" \
c896fb
+                             "      \"vend\" : \"%v\",\n" \
c896fb
+                             "      \"prod\" : \"%p\",\n" \
c896fb
+                             "      \"rev\" : \"%e\",\n" \
c896fb
+                             "      \"switch_grp\" : %1,\n" \
c896fb
+                             "      \"map_loads\" : %2,\n" \
c896fb
+                             "      \"total_q_time\" : %3,\n" \
c896fb
+                             "      \"q_timeouts\" : %4,"
c896fb
+
c896fb
+#define PRINT_JSON_GROUP     "{\n" \
c896fb
+                             "         \"selector\" : \"%s\",\n" \
c896fb
+                             "         \"pri\" : %p,\n" \
c896fb
+                             "         \"dm_st\" : \"%t\","
c896fb
+
c896fb
+#define PRINT_JSON_GROUP_NUM "         \"group\" : %d,\n"
c896fb
+
c896fb
+#define PRINT_JSON_PATH      "{\n" \
c896fb
+                             "            \"dev\" : \"%d\",\n"\
c896fb
+                             "            \"dev_t\" : \"%D\",\n" \
c896fb
+                             "            \"dm_st\" : \"%t\",\n" \
c896fb
+                             "            \"dev_st\" : \"%o\",\n" \
c896fb
+                             "            \"chk_st\" : \"%T\",\n" \
c896fb
+                             "            \"checker\" : \"%c\",\n" \
c896fb
+                             "            \"pri\" : %p,\n" \
c896fb
+                             "            \"host_wwnn\" : \"%N\",\n" \
c896fb
+                             "            \"target_wwnn\" : \"%n\",\n" \
c896fb
+                             "            \"host_wwpn\" : \"%R\",\n" \
c896fb
+                             "            \"target_wwpn\" : \"%r\",\n" \
c896fb
+                             "            \"host_adapter\" : \"%a\""
c896fb
+
c896fb
 #define MAX_LINE_LEN  80
c896fb
 #define MAX_LINES     64
c896fb
 #define MAX_FIELD_LEN 64
c896fb
@@ -41,6 +98,10 @@ int snprint_path (char *, int, char *, s
c896fb
 int snprint_multipath (char *, int, char *, struct multipath *, int);
c896fb
 int snprint_multipath_topology (char *, int, struct multipath * mpp,
c896fb
 				int verbosity);
c896fb
+int snprint_multipath_topology_json (char * buff, int len,
c896fb
+				struct vectors * vecs);
c896fb
+int snprint_multipath_map_json (char * buff, int len,
c896fb
+				struct multipath * mpp, int last);
c896fb
 int snprint_defaults (char *, int);
c896fb
 int snprint_blacklist (char *, int);
c896fb
 int snprint_blacklist_except (char *, int);
c896fb
Index: multipath-tools-130222/multipathd/cli.c
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/cli.c
c896fb
+++ multipath-tools-130222/multipathd/cli.c
c896fb
@@ -189,6 +189,7 @@ load_keys (void)
c896fb
 	r += add_key(keys, "setprstatus", SETPRSTATUS, 0);
c896fb
 	r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0);
c896fb
 	r += add_key(keys, "format", FMT, 1);
c896fb
+	r += add_key(keys, "json", JSON, 0);
c896fb
 
c896fb
 	if (r) {
c896fb
 		free_keys(keys);
c896fb
@@ -473,8 +474,10 @@ cli_init (void) {
c896fb
 	add_handler(LIST+MAPS+FMT, NULL);
c896fb
 	add_handler(LIST+MAPS+RAW+FMT, NULL);
c896fb
 	add_handler(LIST+MAPS+TOPOLOGY, NULL);
c896fb
+	add_handler(LIST+MAPS+JSON, NULL);
c896fb
 	add_handler(LIST+TOPOLOGY, NULL);
c896fb
 	add_handler(LIST+MAP+TOPOLOGY, NULL);
c896fb
+	add_handler(LIST+MAP+JSON, NULL);
c896fb
 	add_handler(LIST+CONFIG, NULL);
c896fb
 	add_handler(LIST+BLACKLIST, NULL);
c896fb
 	add_handler(LIST+DEVICES, NULL);
c896fb
Index: multipath-tools-130222/multipathd/cli.h
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/cli.h
c896fb
+++ multipath-tools-130222/multipathd/cli.h
c896fb
@@ -36,6 +36,7 @@ enum {
c896fb
 	__SETPRSTATUS,
c896fb
 	__UNSETPRSTATUS,
c896fb
 	__FMT,
c896fb
+	__JSON,
c896fb
 };
c896fb
 
c896fb
 #define LIST		(1 << __LIST)
c896fb
@@ -74,6 +75,7 @@ enum {
c896fb
 #define SETPRSTATUS	(1ULL << __SETPRSTATUS)
c896fb
 #define UNSETPRSTATUS	(1ULL << __UNSETPRSTATUS)
c896fb
 #define FMT		(1ULL << __FMT)
c896fb
+#define JSON		(1ULL << __JSON)
c896fb
 
c896fb
 #define INITIAL_REPLY_LEN	1200
c896fb
 
c896fb
Index: multipath-tools-130222/multipathd/cli_handlers.c
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/cli_handlers.c
c896fb
+++ multipath-tools-130222/multipathd/cli_handlers.c
c896fb
@@ -127,6 +127,70 @@ show_maps_topology (char ** r, int * len
c896fb
 }
c896fb
 
c896fb
 int
c896fb
+show_maps_json (char ** r, int * len, struct vectors * vecs)
c896fb
+{
c896fb
+	int i;
c896fb
+	struct multipath * mpp;
c896fb
+	char * c;
c896fb
+	char * reply;
c896fb
+	unsigned int maxlen = INITIAL_REPLY_LEN *
c896fb
+			PRINT_JSON_MULTIPLIER * VECTOR_SIZE(vecs->mpvec);
c896fb
+	int again = 1;
c896fb
+
c896fb
+	vector_foreach_slot(vecs->mpvec, mpp, i) {
c896fb
+		if (update_multipath(vecs, mpp->alias, 0)) {
c896fb
+			return 1;
c896fb
+		}
c896fb
+	}
c896fb
+
c896fb
+	reply = MALLOC(maxlen);
c896fb
+
c896fb
+	while (again) {
c896fb
+		if (!reply)
c896fb
+			return 1;
c896fb
+
c896fb
+		c = reply;
c896fb
+
c896fb
+		c += snprint_multipath_topology_json(c, maxlen, vecs);
c896fb
+		again = ((c - reply) == maxlen);
c896fb
+
c896fb
+		REALLOC_REPLY(reply, again, maxlen);
c896fb
+	}
c896fb
+	*r = reply;
c896fb
+	*len = (int)(c - reply);
c896fb
+	return 0;
c896fb
+}
c896fb
+
c896fb
+int
c896fb
+show_map_json (char ** r, int * len, struct multipath * mpp,
c896fb
+		   struct vectors * vecs)
c896fb
+{
c896fb
+	char * c;
c896fb
+	char * reply;
c896fb
+	unsigned int maxlen = INITIAL_REPLY_LEN;
c896fb
+	int again = 1;
c896fb
+
c896fb
+	if (update_multipath(vecs, mpp->alias, 0))
c896fb
+		return 1;
c896fb
+	reply = MALLOC(maxlen);
c896fb
+
c896fb
+	while (again) {
c896fb
+		if (!reply)
c896fb
+			return 1;
c896fb
+
c896fb
+		c = reply;
c896fb
+
c896fb
+		c += snprint_multipath_map_json(c, maxlen, mpp, 1);
c896fb
+		again = ((c - reply) == maxlen);
c896fb
+
c896fb
+		REALLOC_REPLY(reply, again, maxlen);
c896fb
+	}
c896fb
+	*r = reply;
c896fb
+	*len = (int)(c - reply);
c896fb
+	return 0;
c896fb
+}
c896fb
+
c896fb
+int
c896fb
 show_config (char ** r, int * len)
c896fb
 {
c896fb
 	char * c;
c896fb
@@ -239,6 +303,35 @@ cli_list_maps_topology (void * v, char *
c896fb
 }
c896fb
 
c896fb
 int
c896fb
+cli_list_map_json (void * v, char ** reply, int * len, void * data)
c896fb
+{
c896fb
+	struct multipath * mpp;
c896fb
+	struct vectors * vecs = (struct vectors *)data;
c896fb
+	char * param = get_keyparam(v, MAP);
c896fb
+
c896fb
+	param = convert_dev(param, 0);
c896fb
+	get_path_layout(vecs->pathvec, 0);
c896fb
+	mpp = find_mp_by_str(vecs->mpvec, param);
c896fb
+
c896fb
+	if (!mpp)
c896fb
+		return 1;
c896fb
+
c896fb
+	condlog(3, "list multipath json %s (operator)", param);
c896fb
+
c896fb
+	return show_map_json(reply, len, mpp, vecs);
c896fb
+}
c896fb
+
c896fb
+int
c896fb
+cli_list_maps_json (void * v, char ** reply, int * len, void * data)
c896fb
+{
c896fb
+	struct vectors * vecs = (struct vectors *)data;
c896fb
+
c896fb
+	condlog(3, "list multipaths json (operator)");
c896fb
+
c896fb
+	return show_maps_json(reply, len, vecs);
c896fb
+}
c896fb
+
c896fb
+int
c896fb
 cli_list_wildcards (void * v, char ** reply, int * len, void * data)
c896fb
 {
c896fb
 	char * c;
c896fb
Index: multipath-tools-130222/multipathd/cli_handlers.h
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/cli_handlers.h
c896fb
+++ multipath-tools-130222/multipathd/cli_handlers.h
c896fb
@@ -10,6 +10,8 @@ int cli_list_maps_status (void * v, char
c896fb
 int cli_list_maps_stats (void * v, char ** reply, int * len, void * data);
c896fb
 int cli_list_map_topology (void * v, char ** reply, int * len, void * data);
c896fb
 int cli_list_maps_topology (void * v, char ** reply, int * len, void * data);
c896fb
+int cli_list_map_json (void * v, char ** reply, int * len, void * data);
c896fb
+int cli_list_maps_json (void * v, char ** reply, int * len, void * data);
c896fb
 int cli_list_config (void * v, char ** reply, int * len, void * data);
c896fb
 int cli_list_blacklist (void * v, char ** reply, int * len, void * data);
c896fb
 int cli_list_devices (void * v, char ** reply, int * len, void * data);
c896fb
Index: multipath-tools-130222/multipathd/main.c
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/main.c
c896fb
+++ multipath-tools-130222/multipathd/main.c
c896fb
@@ -981,7 +981,9 @@ uxlsnrloop (void * ap)
c896fb
 	set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
c896fb
 	set_handler_callback(LIST+MAPS+TOPOLOGY, cli_list_maps_topology);
c896fb
 	set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
c896fb
+	set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
c896fb
 	set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
c896fb
+	set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
c896fb
 	set_handler_callback(LIST+CONFIG, cli_list_config);
c896fb
 	set_handler_callback(LIST+BLACKLIST, cli_list_blacklist);
c896fb
 	set_handler_callback(LIST+DEVICES, cli_list_devices);
c896fb
Index: multipath-tools-130222/multipathd/multipathd.8
c896fb
===================================================================
c896fb
--- multipath-tools-130222.orig/multipathd/multipathd.8
c896fb
+++ multipath-tools-130222/multipathd/multipathd.8
c896fb
@@ -53,11 +53,15 @@ using a format string with multipath for
c896fb
 Show the status of all multipath devices that the multipathd is monitoring.
c896fb
 .TP
c896fb
 .B list|show maps|multipaths stats
c896fb
-Show some statistics of all multipath devices that the multipathd is monitoring.
c896fb
+Show some statistics of all multipath devices that multipathd is monitoring.
c896fb
 .TP
c896fb
 .B list|show maps|multipaths topology
c896fb
 Show the current multipath topology. Same as "multipath \-ll".
c896fb
 .TP
c896fb
+.B list|show maps|multipaths json
c896fb
+Show the multipath devices that multipathd is monitoring, using JSON
c896fb
+formatted output.
c896fb
+.TP
c896fb
 .B list|show topology
c896fb
 Show the current multipath topology. Same as "multipath \-ll".
c896fb
 .TP
c896fb
@@ -65,6 +69,9 @@ Show the current multipath topology. Sam
c896fb
 Show topology of a single multipath device specified by $map, e.g. 36005076303ffc56200000000000010aa.
c896fb
 This map could be obtained from "list maps".
c896fb
 .TP
c896fb
+.B list|show map|multipath $map json
c896fb
+Show a single multipath device specified by $map, using JSON formatted output.
c896fb
+.TP
c896fb
 .B list|show wildcards
c896fb
 Show the format wildcards used in interactive commands taking $format
c896fb
 .TP