[dm-devel] [PATCH v2 1/1] add display of map information in JSON format

Germano Percossi germano.percossi at citrix.com
Thu May 12 14:28:06 UTC 2016


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 at redhat.com
> <mailto:tgill at 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 at redhat.com <mailto:tgill at 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 at redhat.com <mailto:dm-devel at redhat.com>
>     https://www.redhat.com/mailman/listinfo/dm-devel
>
>
>
>
> --
> dm-devel mailing list
> dm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
>




More information about the dm-devel mailing list