From a3a74340e01fab8a0458e4baf6ce12dadc65d021 Mon Sep 17 00:00:00 2001 From: Brandon Paupore Date: Tue, 14 Dec 2021 11:49:15 -0600 Subject: [PATCH] Fix JSON report zones output Previously multiple JSON objects would be in the output of zns-report-zones if there were more than 1024 zones requested because of the chunked requests sent by nvme-cli. Fix this to output a single JSON object with one zone_list. This is done by passing around and appending to the zone_list, then outputting all of it once after receiving all the reports. Signed-off-by: Brandon Paupore --- nvme-print.c | 33 +++++++++++++++++---------------- nvme-print.h | 5 ++++- plugins/zns/zns.c | 13 ++++++++++--- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/nvme-print.c b/nvme-print.c index 4f7433b4..aa9578f8 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -4619,22 +4619,27 @@ static char *zone_state_to_string(__u8 state) } } +void json_nvme_finish_zone_list(__u64 nr_zones, + struct json_object *zone_list) +{ + struct json_object *root = json_create_object(); + json_object_add_value_uint(root, "nr_zones", nr_zones); + json_object_add_value_array(root, "zone_list", zone_list); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); +} + static void json_nvme_zns_report_zones(void *report, __u32 descs, - __u8 ext_size, __u32 report_size, __u64 nr_zones) { - struct json_object *root; - struct json_object *zone_list; + __u8 ext_size, __u32 report_size, + struct json_object *zone_list) +{ struct json_object *zone; struct json_object *ext_data; struct nvme_zone_report *r = report; struct nvme_zns_desc *desc; int i; - root = json_create_object(); - zone_list = json_create_array(); - - - json_object_add_value_uint(root, "nr_zones", nr_zones); - for (i = 0; i < descs; i++) { desc = (struct nvme_zns_desc *) (report + sizeof(*r) + i * (sizeof(*desc) + ext_size)); @@ -4667,11 +4672,6 @@ static void json_nvme_zns_report_zones(void *report, __u32 descs, json_array_add_value_object(zone_list, zone); } - - json_object_add_value_array(root, "zone_list", zone_list); - json_print_object(root, NULL); - printf("\n"); - json_free_object(root); } static void nvme_show_zns_report_zone_attributes(__u8 za, __u8 zai) @@ -4693,7 +4693,8 @@ static void nvme_show_zns_report_zone_attributes(__u8 za, __u8 zai) } void nvme_show_zns_report_zones(void *report, __u32 descs, - __u8 ext_size, __u32 report_size, unsigned long flags) + __u8 ext_size, __u32 report_size, unsigned long flags, + struct json_object *zone_list) { struct nvme_zone_report *r = report; struct nvme_zns_desc *desc; @@ -4707,7 +4708,7 @@ void nvme_show_zns_report_zones(void *report, __u32 descs, return d_raw((unsigned char *)report, report_size); else if (flags & JSON) return json_nvme_zns_report_zones(report, descs, - ext_size, report_size, nr_zones); + ext_size, report_size, zone_list); for (i = 0; i < descs; i++) { desc = (struct nvme_zns_desc *) diff --git a/nvme-print.h b/nvme-print.h index 261d6479..92cb7f20 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -115,7 +115,10 @@ void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns, void nvme_show_zns_changed( struct nvme_zns_changed_zone_log *log, unsigned long flags); void nvme_show_zns_report_zones(void *report, __u32 descs, - __u8 ext_size, __u32 report_size, unsigned long flags); + __u8 ext_size, __u32 report_size, unsigned long flags, + struct json_object *zone_list); +void json_nvme_finish_zone_list(__u64 nr_zones, + struct json_object *zone_list); void nvme_show_list_item(nvme_ns_t n); const char *nvme_cmd_to_string(int admin, __u8 opcode); diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c index e5797f1b..01af5b57 100644 --- a/plugins/zns/zns.c +++ b/plugins/zns/zns.c @@ -780,6 +780,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi struct nvme_id_ns id_ns; uint8_t lbaf; __le64 zsze; + struct json_object *zone_list = 0; struct config { char *output_format; @@ -893,7 +894,10 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } offset = cfg.zslba; - printf("nr_zones: %"PRIu64"\n", (uint64_t)le64_to_cpu(total_nr_zones)); + if (flags & JSON) + zone_list = json_create_array(); + else + printf("nr_zones: %"PRIu64"\n", (uint64_t)le64_to_cpu(total_nr_zones)); while (nr_zones_retrieved < nr_zones) { if (nr_zones_retrieved >= nr_zones) @@ -914,13 +918,16 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi } if (!err) - nvme_show_zns_report_zones(report, nr_zones_chunks, zdes, - log_len, flags); + nvme_show_zns_report_zones(report, nr_zones_chunks, + zdes, log_len, flags, zone_list); nr_zones_retrieved += nr_zones_chunks; offset = (nr_zones_retrieved * zsze); } + if (flags & JSON) + json_nvme_finish_zone_list(total_nr_zones, zone_list); + nvme_free(report, huge); free_buff: -- 2.50.1