From patchwork Sat Jun 30 03:55:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ross Zwisler X-Patchwork-Id: 10497937 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 32E4960532 for ; Sat, 30 Jun 2018 03:56:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EAB1293EE for ; Sat, 30 Jun 2018 03:56:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 13359295A6; Sat, 30 Jun 2018 03:56:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8147829509 for ; Sat, 30 Jun 2018 03:56:29 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id BFE4C20336AAA; Fri, 29 Jun 2018 20:56:26 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: None (no SPF record) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=ross.zwisler@linux.intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id C575A202E540B for ; Fri, 29 Jun 2018 20:56:24 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 29 Jun 2018 20:56:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,288,1526367600"; d="scan'208";a="68522296" Received: from theros.lm.intel.com ([10.232.112.164]) by fmsmga001.fm.intel.com with ESMTP; 29 Jun 2018 20:56:08 -0700 From: Ross Zwisler To: "Elliott, Robert (Persistent Memory)" , "Kani, Toshi" , Vishal Verma , linux-nvdimm@lists.01.org Subject: [ndctl PATCH v2 2/2] ndctl list: always output array without --human Date: Fri, 29 Jun 2018 21:55:52 -0600 Message-Id: <20180630035552.27049-3-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180630035552.27049-1-ross.zwisler@linux.intel.com> References: <20180630035552.27049-1-ross.zwisler@linux.intel.com> X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP If "ndctl list" is only printing a single object it currently does not print it in an array. When printing multiple objects, though, an array is used. This simplifies the output for single objects when a human is looking at it but it creates complications for parsers like jq. jq wants to know whether it is trying to parse an object or an array of objects. For example, here's how you print just the mode of a single namespace: # ndctl list -n namespace1.0 | jq ".mode" "raw" This works on a single object. If you have multiple objects in a JSON array you do this: # ndctl list | jq -r '(.[]) | .mode' raw raw If you want to write a generic script that works in both cases you have to do something quite complicated like: # ndctl list | jq -r '((. | arrays | .[]), . | objects | .mode)' raw raw Instead of pushing the burden on the user, have ndctl output consistently be an array even if there is only one element. This allows the parsing code to be simpler and only worry about one case. If the user specifies the --human or -u flags we will assume that a person is looking at the output and not a script and will continue to output a single element which is not part of an array. Signed-off-by: Ross Zwisler --- daxctl/list.c | 11 +++++++---- ndctl/bus.c | 2 +- ndctl/dimm.c | 2 +- ndctl/inject-smart.c | 2 +- ndctl/list.c | 8 ++++---- util/json.c | 5 +++-- util/json.h | 3 ++- 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/daxctl/list.c b/daxctl/list.c index ed9e76c..58c35fa 100644 --- a/daxctl/list.c +++ b/daxctl/list.c @@ -83,6 +83,7 @@ int cmd_list(int argc, const char **argv, void *ctx) struct json_object *jregions = NULL; struct json_object *jdevs = NULL; struct daxctl_region *region; + unsigned long list_flags; int i; argc = parse_options(argc, argv, options, u, 0); @@ -100,6 +101,8 @@ int cmd_list(int argc, const char **argv, void *ctx) if (num_list_flags() == 0) list.devs = true; + list_flags = listopts_to_flags(); + daxctl_region_foreach(ctx, region) { struct json_object *jregion = NULL; @@ -117,7 +120,7 @@ int cmd_list(int argc, const char **argv, void *ctx) } jregion = util_daxctl_region_to_json(region, - param.dev, listopts_to_flags()); + param.dev, list_flags); if (!jregion) { fail("\n"); continue; @@ -125,13 +128,13 @@ int cmd_list(int argc, const char **argv, void *ctx) json_object_array_add(jregions, jregion); } else if (list.devs) jdevs = util_daxctl_devs_to_list(region, jdevs, - param.dev, listopts_to_flags()); + param.dev, list_flags); } if (jregions) - util_display_json_array(stdout, jregions); + util_display_json_array(stdout, jregions, list_flags); else if (jdevs) - util_display_json_array(stdout, jdevs); + util_display_json_array(stdout, jdevs, list_flags); if (did_fail) return -ENOMEM; diff --git a/ndctl/bus.c b/ndctl/bus.c index b7b7d65..bcb8c71 100644 --- a/ndctl/bus.c +++ b/ndctl/bus.c @@ -88,7 +88,7 @@ static int bus_action(int argc, const char **argv, const char *usage, } if (success) - util_display_json_array(stdout, jbuses); + util_display_json_array(stdout, jbuses, 0); else json_object_put(jbuses); diff --git a/ndctl/dimm.c b/ndctl/dimm.c index 6964c5e..97643a3 100644 --- a/ndctl/dimm.c +++ b/ndctl/dimm.c @@ -1081,7 +1081,7 @@ static int dimm_action(int argc, const char **argv, void *ctx, } if (actx.jdimms) - util_display_json_array(actx.f_out, actx.jdimms); + util_display_json_array(actx.f_out, actx.jdimms, 0); if (actx.f_out != stdout) fclose(actx.f_out); diff --git a/ndctl/inject-smart.c b/ndctl/inject-smart.c index 2e62c89..8da893c 100644 --- a/ndctl/inject-smart.c +++ b/ndctl/inject-smart.c @@ -375,7 +375,7 @@ static int dimm_inject_smart(struct ndctl_dimm *dimm) jhealth = util_dimm_health_to_json(dimm); if (jhealth) { json_object_object_add(jdimm, "health", jhealth); - util_display_json_array(stdout, jdimms); + util_display_json_array(stdout, jdimms, sctx.flags); } } out: diff --git a/ndctl/list.c b/ndctl/list.c index 030d73f..a06edc9 100644 --- a/ndctl/list.c +++ b/ndctl/list.c @@ -379,7 +379,7 @@ static int list_display(struct list_filter_arg *lfa) struct json_object *jbuses = lfa->jbuses; if (jbuses) - util_display_json_array(stdout, jbuses); + util_display_json_array(stdout, jbuses, lfa->flags); else if ((!!jdimms + !!jregions + !!jnamespaces) > 1) { struct json_object *jplatform = json_object_new_object(); @@ -399,11 +399,11 @@ static int list_display(struct list_filter_arg *lfa) JSON_C_TO_STRING_PRETTY)); json_object_put(jplatform); } else if (jdimms) - util_display_json_array(stdout, jdimms); + util_display_json_array(stdout, jdimms, lfa->flags); else if (jregions) - util_display_json_array(stdout, jregions); + util_display_json_array(stdout, jregions, lfa->flags); else if (jnamespaces) - util_display_json_array(stdout, jnamespaces); + util_display_json_array(stdout, jnamespaces, lfa->flags); return 0; } diff --git a/util/json.c b/util/json.c index ff894c7..1332458 100644 --- a/util/json.c +++ b/util/json.c @@ -105,12 +105,13 @@ struct json_object *util_json_object_hex(unsigned long long val, return jobj; } -void util_display_json_array(FILE *f_out, struct json_object *jarray) +void util_display_json_array(FILE *f_out, struct json_object *jarray, + unsigned long flags) { int len = json_object_array_length(jarray); int jflag = JSON_C_TO_STRING_PRETTY; - if (json_object_array_length(jarray) > 1) + if (json_object_array_length(jarray) > 1 || !(flags & UTIL_JSON_HUMAN)) fprintf(f_out, "%s\n", json_object_to_json_string_ext(jarray, jflag)); else if (len) { struct json_object *jobj; diff --git a/util/json.h b/util/json.h index d0167cf..aa2e976 100644 --- a/util/json.h +++ b/util/json.h @@ -26,7 +26,8 @@ enum util_json_flags { }; struct json_object; -void util_display_json_array(FILE *f_out, struct json_object *jarray); +void util_display_json_array(FILE *f_out, struct json_object *jarray, + unsigned long flags); struct json_object *util_bus_to_json(struct ndctl_bus *bus); struct json_object *util_dimm_to_json(struct ndctl_dimm *dimm, unsigned long flags);