From: Germano Percossi <germano.percossi@citrix.com>
To: dm-devel@redhat.com
Subject: Re: [PATCH v2 1/1] add display of map information in JSON format
Date: Thu, 12 May 2016 15:28:06 +0100 [thread overview]
Message-ID: <573492F6.5060202@citrix.com> (raw)
In-Reply-To: <CABr-Gnd1+P8No_7E-ThXwPTUiS-cq0jqTQfh3M3ThOcXbkAd5w@mail.gmail.com>
Hi,
If there are not specific reasons to have them
merged, I would rather have vendor and product split.
By the way, JSON is already a great improvement over
the custom parsing we are already doing so I do not want
to nitpick.
Cheers,
Germano
On 05/11/2016 06:35 PM, Christophe Varoqui wrote:
> Hi,
>
> the json choice over xml is fine for me, so I'm ready to merge.
>
> Before I do so, is there a second round of review pending ?
>
> Are wannabe users of this new output happy with some fields being merged
> (like vendor/product/rev) ?
>
> Best regards,
> Christophe Varoqui
> OpenSVC
>
>
> On Tue, May 10, 2016 at 9:05 PM, Todd Gill <tgill@redhat.com
> <mailto:tgill@redhat.com>> wrote:
>
> The patch add these commands:
>
> multipathd show maps json
> multipathd show map $map json
>
> Each command will output the requested map(s) in JSON.
>
> For the "show maps json" command, the patch pre-allocates
> INITIAL_REPLY_LEN * PRINT_JSON_MULTIPLIER(5). The JSON text
> is about 5x the size of the "show maps topology" text.
>
> Signed-off-by: Todd Gill <tgill@redhat.com <mailto:tgill@redhat.com>>
> ---
> libmultipath/print.c | 163
> ++++++++++++++++++++++++++++++++++++++++++++++
> libmultipath/print.h | 63 ++++++++++++++++++
> multipathd/cli.c | 3 +
> multipathd/cli.h | 2 +
> multipathd/cli_handlers.c | 93 ++++++++++++++++++++++++++
> multipathd/cli_handlers.h | 2 +
> multipathd/main.c | 2 +
> 7 files changed, 328 insertions(+)
>
> diff --git a/libmultipath/print.c b/libmultipath/print.c
> index 7fec6e9..e92b534 100644
> --- a/libmultipath/print.c
> +++ b/libmultipath/print.c
> @@ -1000,6 +1000,169 @@ snprint_multipath_topology (char * buff, int
> len, struct multipath * mpp,
> }
>
> static int
> +snprint_json (char * line, int len, int indent, char *json_str)
> +{
> + int fwd = 0, i;
> +
> + for (i = 0; i < indent; i++) {
> + fwd += snprintf(line + fwd, len - fwd,
> PRINT_JSON_INDENT);
> + if (fwd > len)
> + return fwd;
> + }
> +
> + fwd += snprintf(line + fwd, len - fwd, "%s", json_str);
> + return fwd;
> +}
> +
> +static int
> +snprint_json_header (char * line, int len)
> +{
> + int fwd = 0;
> +
> + fwd += snprint_json(line + fwd, len, 0, PRINT_JSON_START_ELEM);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprintf(line + fwd, len - fwd,
> PRINT_JSON_START_VERSION,
> + PRINT_JSON_MAJOR_VERSION,
> PRINT_JSON_MINOR_VERSION);
> + return fwd;
> +}
> +
> +static int
> +snprint_json_elem_footer (char * line, int len, int indent, int last)
> +{
> + int fwd = 0, i;
> +
> + for (i = 0; i < indent; i++) {
> + fwd += snprintf(line + fwd, len - fwd,
> PRINT_JSON_INDENT);
> + if (fwd > len)
> + return fwd;
> + }
> +
> + if (last == 1)
> + fwd += snprintf(line + fwd, len - fwd, "%s",
> + PRINT_JSON_END_LAST);
> + else
> + fwd += snprintf(line + fwd, len - fwd, "%s",
> + PRINT_JSON_END_ELEM);
> + return fwd;
> +}
> +
> +static int
> +snprint_multipath_fields_json (char * buff, int len,
> + struct multipath * mpp, int last)
> +{
> + int i, j, fwd = 0;
> + struct path *pp;
> + struct pathgroup *pgp;
> +
> + fwd += snprint_multipath(buff + fwd, len - fwd,
> PRINT_JSON_MAP, mpp, 0);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 2,
> PRINT_JSON_START_GROUPS);
> + if (fwd > len)
> + return fwd;
> +
> + vector_foreach_slot (mpp->pg, pgp, i) {
> +
> + pgp->selector = mpp->selector;
> + fwd += snprint_pathgroup(buff + fwd, len - fwd,
> PRINT_JSON_GROUP, pgp);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 3,
> PRINT_JSON_START_PATHS);
> + if (fwd > len)
> + return fwd;
> +
> + vector_foreach_slot (pgp->paths, pp, j) {
> +
> + fwd += snprint_path(buff + fwd,
> + len - fwd, PRINT_JSON_PATH,
> pp, 0);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprint_json_elem_footer(buff + fwd,
> + len - fwd, 3, j + 1 ==
> VECTOR_SIZE(pgp->paths));
> + if (fwd > len)
> + return fwd;
> + }
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> PRINT_JSON_END_ARRAY);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprint_json_elem_footer(buff + fwd,
> + len - fwd, 2, i + 1 == VECTOR_SIZE(mpp->pg));
> + if (fwd > len)
> + return fwd;
> + }
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> PRINT_JSON_END_ARRAY);
> + if (fwd > len)
> + return fwd;
> +
> + fwd += snprint_json_elem_footer(buff + fwd, len - fwd, 1, last);
> + return fwd;
> +}
> +
> +int
> +snprint_multipath_map_json (char * buff, int len,
> + struct multipath * mpp, int last){
> + int fwd = 0;
> +
> + memset(buff, 0, len);
> + fwd += snprint_json_header(buff + fwd, len);
> + if (fwd > len)
> + return len;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> PRINT_JSON_START_MAP);
> + if (fwd > len)
> + return len;
> +
> + fwd += snprint_multipath_fields_json(buff + fwd, len - fwd,
> mpp, 1);
> + if (fwd > len)
> + return len;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> "\n"PRINT_JSON_END_LAST);
> + if (fwd > len)
> + return len;
> + return fwd;
> +}
> +
> +int
> +snprint_multipath_topology_json (char * buff, int len, struct
> vectors * vecs)
> +{
> + int i, fwd = 0;
> + struct multipath * mpp;
> +
> + memset(buff, 0, len);
> + fwd += snprint_json_header(buff + fwd, len);
> + if (fwd > len)
> + return len;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 1,
> PRINT_JSON_START_MAPS);
> + if (fwd > len)
> + return len;
> +
> + vector_foreach_slot(vecs->mpvec, mpp, i) {
> + fwd += snprint_multipath_fields_json(buff + fwd, len
> - fwd,
> + mpp, i + 1 == VECTOR_SIZE(vecs->mpvec));
> + if (fwd > len)
> + return len;
> + }
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> PRINT_JSON_END_ARRAY);
> + if (fwd > len)
> + return len;
> +
> + fwd += snprint_json(buff + fwd, len - fwd, 0,
> PRINT_JSON_END_LAST);
> + if (fwd > len)
> + return len;
> + return fwd;
> +}
> +
> +static int
> snprint_hwentry (char * buff, int len, struct hwentry * hwe)
> {
> int i;
> diff --git a/libmultipath/print.h b/libmultipath/print.h
> index 8bd0bbc..f8a383d 100644
> --- a/libmultipath/print.h
> +++ b/libmultipath/print.h
> @@ -7,6 +7,65 @@
> #define PRINT_MAP_PROPS "size=%S features='%f' hwhandler='%h'
> wp=%r"
> #define PRINT_PG_INDENT "policy='%s' prio=%p status=%t"
>
> +#define PRINT_JSON_MULTIPLIER 5
> +#define PRINT_JSON_MAJOR_VERSION 0
> +#define PRINT_JSON_MINOR_VERSION 1
> +#define PRINT_JSON_START_VERSION " \"major_version \": %d,\n" \
> + " \"minor_version \": %d,\n"
> +#define PRINT_JSON_START_ELEM "{\n"
> +#define PRINT_JSON_START_MAP " \"map\":"
> +#define PRINT_JSON_START_MAPS "\"maps\": ["
> +#define PRINT_JSON_START_PATHS "\"paths\": ["
> +#define PRINT_JSON_START_GROUPS "\"path_groups\": ["
> +#define PRINT_JSON_END_ELEM "},"
> +#define PRINT_JSON_END_LAST "}"
> +#define PRINT_JSON_END_ARRAY "]\n"
> +#define PRINT_JSON_INDENT " "
> +#define PRINT_JSON_MAP "{\n" \
> + " \"name\" : \"%n\",\n" \
> + " \"uuid\" : \"%w\",\n" \
> + " \"sysfs\" : \"%d\",\n" \
> + " \"failback\" : \"%F\",\n" \
> + " \"queueing\" : \"%Q\",\n" \
> + " \"paths\" : %N,\n" \
> + " \"write_prot\" : \"%r\",\n" \
> + " \"dm-st\" : \"%t\",\n" \
> + " \"size\" : \"%S\",\n" \
> + " \"features\" : \"%f\",\n" \
> + " \"hwhandler\" : \"%h\",\n" \
> + " \"action\" : \"%A\",\n" \
> + " \"path_faults\" : %0,\n" \
> + " \"vend/prod/rev\" : \"%s\",\n" \
> + " \"switch_grp\" : %1,\n" \
> + " \"map_loads\" : %2,\n" \
> + " \"total_q_time\" : %3,\n" \
> + " \"q_timeouts\" : %4,"
> +
> +#define PRINT_JSON_GROUP "{\n" \
> + " \"selector\" : \"%s\",\n" \
> + " \"pri\" : %p,\n" \
> + " \"dm_st\" : \"%t\","
> +
> +#define PRINT_JSON_PATH "{\n" \
> + " \"uuid\" : \"%w\",\n" \
> + " \"hcil\" : \"%i\",\n" \
> + " \"dev\" : \"%d\",\n"\
> + " \"dev_t\" : \"%D\",\n" \
> + " \"dm_st\" : \"%t\",\n" \
> + " \"dev_st\" : \"%o\",\n" \
> + " \"chk_st\" : \"%T\",\n" \
> + " \"vend/prod/rev\" :
> \"%s\",\n" \
> + " \"checker\" : \"%c\",\n" \
> + " \"next_check\" : \"%C\",\n" \
> + " \"pri\" : %p,\n" \
> + " \"size\" : \"%S\",\n" \
> + " \"serial\" : \"%z\",\n" \
> + " \"host WWNN\" : \"%N\",\n" \
> + " \"target WWNN\" :
> \"%n\",\n" \
> + " \"host WWPN\" : \"%R\",\n" \
> + " \"target WWPN\" :
> \"%r\",\n" \
> + " \"host adapter\" : \"%a\""
> +
> #define MAX_LINE_LEN 80
> #define MAX_LINES 64
> #define MAX_FIELD_LEN 64
> @@ -41,6 +100,10 @@ int snprint_path (char *, int, char *, struct
> path *, int);
> int snprint_multipath (char *, int, char *, struct multipath *, int);
> int snprint_multipath_topology (char *, int, struct multipath * mpp,
> int verbosity);
> +int snprint_multipath_topology_json (char * buff, int len,
> + struct vectors * vecs);
> +int snprint_multipath_map_json (char * buff, int len,
> + struct multipath * mpp, int last);
> int snprint_defaults (char *, int);
> int snprint_blacklist (char *, int);
> int snprint_blacklist_except (char *, int);
> diff --git a/multipathd/cli.c b/multipathd/cli.c
> index d991cd0..20ee3db 100644
> --- a/multipathd/cli.c
> +++ b/multipathd/cli.c
> @@ -207,6 +207,7 @@ load_keys (void)
> r += add_key(keys, "setprstatus", SETPRSTATUS, 0);
> r += add_key(keys, "unsetprstatus", UNSETPRSTATUS, 0);
> r += add_key(keys, "format", FMT, 1);
> + r += add_key(keys, "json", JSON, 0);
>
> if (r) {
> free_keys(keys);
> @@ -537,8 +538,10 @@ cli_init (void) {
> add_handler(LIST+MAPS+FMT, NULL);
> add_handler(LIST+MAPS+RAW+FMT, NULL);
> add_handler(LIST+MAPS+TOPOLOGY, NULL);
> + add_handler(LIST+MAPS+JSON, NULL);
> add_handler(LIST+TOPOLOGY, NULL);
> add_handler(LIST+MAP+TOPOLOGY, NULL);
> + add_handler(LIST+MAP+JSON, NULL);
> add_handler(LIST+MAP+FMT, NULL);
> add_handler(LIST+MAP+RAW+FMT, NULL);
> add_handler(LIST+CONFIG, NULL);
> diff --git a/multipathd/cli.h b/multipathd/cli.h
> index 84ca40f..92cb41b 100644
> --- a/multipathd/cli.h
> +++ b/multipathd/cli.h
> @@ -36,6 +36,7 @@ enum {
> __SETPRSTATUS,
> __UNSETPRSTATUS,
> __FMT,
> + __JSON,
> };
>
> #define LIST (1 << __LIST)
> @@ -74,6 +75,7 @@ enum {
> #define SETPRSTATUS (1ULL << __SETPRSTATUS)
> #define UNSETPRSTATUS (1ULL << __UNSETPRSTATUS)
> #define FMT (1ULL << __FMT)
> +#define JSON (1ULL << __JSON)
>
> #define INITIAL_REPLY_LEN 1200
>
> diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
> index 8b3cb9d..19cf2ff 100644
> --- a/multipathd/cli_handlers.c
> +++ b/multipathd/cli_handlers.c
> @@ -156,6 +156,70 @@ show_maps_topology (char ** r, int * len,
> struct vectors * vecs)
> }
>
> int
> +show_maps_json (char ** r, int * len, struct vectors * vecs)
> +{
> + int i;
> + struct multipath * mpp;
> + char * c;
> + char * reply;
> + unsigned int maxlen = INITIAL_REPLY_LEN * PRINT_JSON_MULTIPLIER;
> + int again = 1;
> +
> + vector_foreach_slot(vecs->mpvec, mpp, i) {
> + if (update_multipath(vecs, mpp->alias, 0)) {
> + return 1;
> + }
> + }
> +
> + reply = MALLOC(maxlen);
> +
> + while (again) {
> + if (!reply)
> + return 1;
> +
> + c = reply;
> +
> + c += snprint_multipath_topology_json(c, reply +
> maxlen - c,
> + vecs);
> + again = ((c - reply) == maxlen);
> +
> + REALLOC_REPLY(reply, again, maxlen);
> + }
> + *r = reply;
> + *len = (int)(c - reply + 1);
> + return 0;
> +}
> +
> +int
> +show_map_json (char ** r, int * len, struct multipath * mpp,
> + struct vectors * vecs)
> +{
> + char * c;
> + char * reply;
> + unsigned int maxlen = INITIAL_REPLY_LEN;
> + int again = 1;
> +
> + if (update_multipath(vecs, mpp->alias, 0))
> + return 1;
> + reply = MALLOC(maxlen);
> +
> + while (again) {
> + if (!reply)
> + return 1;
> +
> + c = reply;
> +
> + c += snprint_multipath_map_json(c, reply + maxlen -
> c, mpp, 1);
> + again = ((c - reply) == maxlen);
> +
> + REALLOC_REPLY(reply, again, maxlen);
> + }
> + *r = reply;
> + *len = (int)(c - reply + 1);
> + return 0;
> +}
> +
> +int
> show_config (char ** r, int * len)
> {
> char * c;
> @@ -291,6 +355,35 @@ cli_list_maps_topology (void * v, char **
> reply, int * len, void * data)
> }
>
> int
> +cli_list_map_json (void * v, char ** reply, int * len, void * data)
> +{
> + struct multipath * mpp;
> + struct vectors * vecs = (struct vectors *)data;
> + char * param = get_keyparam(v, MAP);
> +
> + param = convert_dev(param, 0);
> + get_path_layout(vecs->pathvec, 0);
> + mpp = find_mp_by_str(vecs->mpvec, param);
> +
> + if (!mpp)
> + return 1;
> +
> + condlog(3, "list multipath json %s (operator)", param);
> +
> + return show_map_json(reply, len, mpp, vecs);
> +}
> +
> +int
> +cli_list_maps_json (void * v, char ** reply, int * len, void * data)
> +{
> + struct vectors * vecs = (struct vectors *)data;
> +
> + condlog(3, "list multipaths json (operator)");
> +
> + return show_maps_json(reply, len, vecs);
> +}
> +
> +int
> cli_list_wildcards (void * v, char ** reply, int * len, void * data)
> {
> char * c;
> diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h
> index 5d51018..e838f19 100644
> --- a/multipathd/cli_handlers.h
> +++ b/multipathd/cli_handlers.h
> @@ -13,6 +13,8 @@ int cli_list_maps_status (void * v, char ** reply,
> int * len, void * data);
> int cli_list_maps_stats (void * v, char ** reply, int * len, void
> * data);
> int cli_list_map_topology (void * v, char ** reply, int * len,
> void * data);
> int cli_list_maps_topology (void * v, char ** reply, int * len,
> void * data);
> +int cli_list_map_json (void * v, char ** reply, int * len, void *
> data);
> +int cli_list_maps_json (void * v, char ** reply, int * len, void *
> data);
> int cli_list_config (void * v, char ** reply, int * len, void * data);
> int cli_list_blacklist (void * v, char ** reply, int * len, void *
> data);
> int cli_list_devices (void * v, char ** reply, int * len, void *
> data);
> diff --git a/multipathd/main.c b/multipathd/main.c
> index 58e8854..33f38cd 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -1120,9 +1120,11 @@ uxlsnrloop (void * ap)
> set_handler_callback(LIST+MAPS+RAW+FMT, cli_list_maps_raw);
> set_handler_callback(LIST+MAPS+TOPOLOGY,
> cli_list_maps_topology);
> set_handler_callback(LIST+TOPOLOGY, cli_list_maps_topology);
> + set_handler_callback(LIST+MAPS+JSON, cli_list_maps_json);
> set_handler_callback(LIST+MAP+TOPOLOGY, cli_list_map_topology);
> set_handler_callback(LIST+MAP+FMT, cli_list_map_fmt);
> set_handler_callback(LIST+MAP+RAW+FMT, cli_list_map_fmt);
> + set_handler_callback(LIST+MAP+JSON, cli_list_map_json);
> set_unlocked_handler_callback(LIST+CONFIG, cli_list_config);
> set_unlocked_handler_callback(LIST+BLACKLIST,
> cli_list_blacklist);
> set_handler_callback(LIST+DEVICES, cli_list_devices);
> --
> 2.5.5
>
> --
> dm-devel mailing list
> dm-devel@redhat.com <mailto:dm-devel@redhat.com>
> https://www.redhat.com/mailman/listinfo/dm-devel
>
>
>
>
> --
> dm-devel mailing list
> dm-devel@redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
>
next prev parent reply other threads:[~2016-05-12 14:28 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-10 19:05 [PATCH v2 0/1] add option to output JSON for multipathd command Todd Gill
2016-05-10 19:05 ` [PATCH v2 1/1] add display of map information in JSON format Todd Gill
2016-05-11 17:35 ` Christophe Varoqui
2016-05-12 14:28 ` Germano Percossi [this message]
2016-05-12 19:07 ` Todd Gill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=573492F6.5060202@citrix.com \
--to=germano.percossi@citrix.com \
--cc=dm-devel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.