From 0705e81d4d1b92a49dcf6d597e5064cd2785f4e9 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Fri, 3 Nov 2023 22:03:46 +0900 Subject: [PATCH] nvme-print-json: Add show_init/finish calls to report features in array Note: Still error and data reported separately so will be fixed later. Signed-off-by: Tokunori Ikegami --- nvme-print-binary.c | 4 + nvme-print-json.c | 335 +++++++++++++++++--------------------------- nvme-print-stdout.c | 4 +- nvme-print.c | 69 +++++---- nvme-print.h | 7 +- nvme.c | 6 +- 6 files changed, 179 insertions(+), 246 deletions(-) diff --git a/nvme-print-binary.c b/nvme-print-binary.c index bbca9737..e9371e52 100644 --- a/nvme-print-binary.c +++ b/nvme-print-binary.c @@ -360,6 +360,9 @@ static struct print_ops binary_print_ops = { .id_ctrl_rpmbs = NULL, .lba_range = NULL, .lba_status_info = NULL, + .d = NULL, + .show_init = NULL, + .show_finish = NULL, /* libnvme tree print functions */ .list_item = NULL, @@ -373,6 +376,7 @@ static struct print_ops binary_print_ops = { .show_message = NULL, .show_perror = NULL, .show_status = NULL, + .show_error_status = NULL, }; struct print_ops *nvme_get_binary_print_ops(enum nvme_print_flags flags) diff --git a/nvme-print-json.c b/nvme-print-json.c index 1525a1ec..075a1703 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -34,6 +34,7 @@ static const uint8_t zero_uuid[16] = { 0 }; static struct print_ops json_print_ops; +static struct json_object *json_r = NULL; static void obj_add_uint_x(struct json_object *o, const char *k, __u32 v) { @@ -136,6 +137,20 @@ static struct json_object *obj_create_array_obj(struct json_object *o, const cha return obj; } +static struct json_object *obj_create(const char *k) +{ + struct json_object *array; + struct json_object *obj = json_create_object(); + + if (json_r) { + array = json_create_array(); + obj_add_array(json_r, k, array); + array_add_obj(array, obj); + } + + return obj; +} + static void json_print(struct json_object *r) { json_print_object(r, NULL); @@ -143,6 +158,12 @@ static void json_print(struct json_object *r) json_free_object(r); } +static void obj_print(struct json_object *o) +{ + if (!json_r) + json_print(o); +} + static bool human(void) { return json_print_ops.flags & VERBOSE; @@ -2955,9 +2976,8 @@ static void json_nvme_zns_report_zones(void *report, __u32 descs, } } -static void json_feature_show_fields_arbitration(unsigned int result) +static void json_feature_show_fields_arbitration(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); char json_str[STR_LEN]; obj_add_uint(r, "High Priority Weight (HPW)", ((result & 0xff000000) >> 24) + 1); @@ -2970,20 +2990,15 @@ static void json_feature_show_fields_arbitration(unsigned int result) sprintf(json_str, "%u", 1 << (result & 7)); obj_add_str(r, "Arbitration Burst (AB)", json_str); - - json_print(r); } -static void json_feature_show_fields_power_mgmt(unsigned int result) +static void json_feature_show_fields_power_mgmt(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); __u8 field = (result & 0xe0) >> 5; obj_add_uint(r, "Workload Hint (WH)", field); obj_add_str(r, "WH description", nvme_feature_wl_hints_to_string(field)); obj_add_uint(r, "Power State (PS)", result & 0x1f); - - json_print(r); } static void json_lba_range_entry(struct nvme_lba_range_type *lbrt, int nr_ranges, @@ -3028,21 +3043,17 @@ static void json_lba_range_entry(struct nvme_lba_range_type *lbrt, int nr_ranges } } -static void json_feature_show_fields_lba_range(__u8 field, unsigned char *buf) +static void json_feature_show_fields_lba_range(struct json_object *r, __u8 field, + unsigned char *buf) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Number of LBA Ranges (NUM)", field + 1); if (buf) json_lba_range_entry((struct nvme_lba_range_type *)buf, field, r); - - json_print(r); } -static void json_feature_show_fields_temp_thresh(unsigned int result) +static void json_feature_show_fields_temp_thresh(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); __u8 field = (result & 0x300000) >> 20; char json_str[STR_LEN]; @@ -3059,13 +3070,10 @@ static void json_feature_show_fields_temp_thresh(unsigned int result) sprintf(json_str, "%u K", result & 0xffff); obj_add_str(r, "TMPTH kelvin", json_str); - - json_print(r); } -static void json_feature_show_fields_err_recovery(unsigned int result) +static void json_feature_show_fields_err_recovery(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); char json_str[STR_LEN]; obj_add_str(r, "Deallocated or Unwritten Logical Block Error Enable (DULBE)", @@ -3073,68 +3081,43 @@ static void json_feature_show_fields_err_recovery(unsigned int result) sprintf(json_str, "%u ms", (result & 0xffff) * 100); obj_add_str(r, "Time Limited Error Recovery (TLER)", json_str); - - json_print(r); } -static void json_feature_show_fields_volatile_wc(unsigned int result) +static void json_feature_show_fields_volatile_wc(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Volatile Write Cache Enable (WCE)", result & 1 ? "Enabled" : "Disabled"); - - json_print(r); } -static void json_feature_show_fields_num_queues(unsigned int result) +static void json_feature_show_fields_num_queues(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Number of IO Completion Queues Allocated (NCQA)", - ((result & 0xffff0000) >> 16) + 1); - + ((result & 0xffff0000) >> 16) + 1); obj_add_uint(r, "Number of IO Submission Queues Allocated (NSQA)", (result & 0xffff) + 1); - - json_print(r); } -static void json_feature_show_fields_irq_coalesce(unsigned int result) +static void json_feature_show_fields_irq_coalesce(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); char json_str[STR_LEN]; sprintf(json_str, "%u usec", ((result & 0xff00) >> 8) * 100); obj_add_str(r, "Aggregation Time (TIME)", json_str); obj_add_uint(r, "Aggregation Threshold (THR)", (result & 0xff) + 1); - - json_print(r); } -static void json_feature_show_fields_irq_config(unsigned int result) +static void json_feature_show_fields_irq_config(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Coalescing Disable (CD)", (result & 0x10000) >> 16 ? "True" : "False"); - obj_add_uint(r, "Interrupt Vector (IV)", result & 0xffff); - - json_print(r); } -static void json_feature_show_fields_write_atomic(unsigned int result) +static void json_feature_show_fields_write_atomic(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Disable Normal (DN)", result & 1 ? "True" : "False"); - - json_print(r); } -static void json_feature_show_fields_async_event(unsigned int result) +static void json_feature_show_fields_async_event(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Discovery Log Page Change Notices", (result & 0x80000000) >> 31 ? "Send async event" : "Do not send async event"); obj_add_str(r, "Endurance Group Event Aggregate Log Change Notices", (result & 0x4000) >> 14 ? @@ -3153,8 +3136,6 @@ static void json_feature_show_fields_async_event(unsigned int result) "Do not send async event"); obj_add_str(r, "SMART / Health Critical Warnings", result & 0xff ? "Send async event" : "Do not send async event"); - - json_print(r); } static void json_auto_pst(struct nvme_feat_auto_pst *apst, struct json_object *r) @@ -3180,17 +3161,14 @@ static void json_auto_pst(struct nvme_feat_auto_pst *apst, struct json_object *r } } -static void json_feature_show_fields_auto_pst(unsigned int result, unsigned char *buf) +static void json_feature_show_fields_auto_pst(struct json_object *r, unsigned int result, + unsigned char *buf) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Autonomous Power State Transition Enable (APSTE)", result & 1 ? "Enabled" : "Disabled"); if (buf) json_auto_pst((struct nvme_feat_auto_pst *)buf, r); - - json_print(r); } static void json_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb, struct json_object *r) @@ -3208,21 +3186,17 @@ static void json_host_mem_buffer(struct nvme_host_mem_buf_attrs *hmb, struct jso obj_add_uint(r, "Host Memory Buffer Size (HSIZE)", le32_to_cpu(hmb->hsize)); } -static void json_feature_show_fields_host_mem_buf(unsigned int result, unsigned char *buf) +static void json_feature_show_fields_host_mem_buf(struct json_object *r, unsigned int result, + unsigned char *buf) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Enable Host Memory (EHM)", result & 1 ? "Enabled" : "Disabled"); if (buf) json_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf, r); - - json_print(r); } -static void json_timestamp(struct nvme_timestamp *ts) +static void json_timestamp(struct json_object *r, struct nvme_timestamp *ts) { - struct json_object *r = json_create_object(); char buffer[BUF_LEN]; time_t timestamp = int48_to_long(ts->timestamp) / 1000; struct tm *tm = localtime(×tamp); @@ -3241,28 +3215,21 @@ static void json_timestamp(struct nvme_timestamp *ts) obj_add_str(r, "synch", ts->attr & 1 ? "The controller may have stopped counting during vendor specific intervals after the Timestamp value was initialized." : "The controller counted time in milliseconds continuously since the Timestamp value was initialized."); - - json_print(r); } -static void json_feature_show_fields_timestamp(unsigned char *buf) +static void json_feature_show_fields_timestamp(struct json_object *r, unsigned char *buf) { if (buf) - json_timestamp((struct nvme_timestamp *)buf); + json_timestamp(r, (struct nvme_timestamp *)buf); } -static void json_feature_show_fields_kato(unsigned int result) +static void json_feature_show_fields_kato(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Keep Alive Timeout (KATO) in milliseconds", result); - - json_print(r); } -static void json_feature_show_fields_hctm(unsigned int result) +static void json_feature_show_fields_hctm(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); char json_str[STR_LEN]; sprintf(json_str, "%u K", result >> 16); @@ -3276,27 +3243,17 @@ static void json_feature_show_fields_hctm(unsigned int result) sprintf(json_str, "%ld Celsius", kelvin_to_celsius(result & 0xffff)); obj_add_str(r, "TMT2 celsius", json_str); - - json_print(r); } -static void json_feature_show_fields_nopsc(unsigned int result) +static void json_feature_show_fields_nopsc(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Non-Operational Power State Permissive Mode Enable (NOPPME)", result & 1 ? - "True" : "False"); - - json_print(r); + "True" : "False"); } -static void json_feature_show_fields_rrl(unsigned int result) +static void json_feature_show_fields_rrl(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Read Recovery Level (RRL)", result & 0xf); - - json_print(r); } static void json_plm_config(struct nvme_plm_config *plmcfg, struct json_object *r) @@ -3311,87 +3268,56 @@ static void json_plm_config(struct nvme_plm_config *plmcfg, struct json_object * obj_add_uint64(r, "DTWIN Time Threshold", le64_to_cpu(plmcfg->dtwintt)); } -static void json_feature_show_fields_plm_config(unsigned int result, unsigned char *buf) +static void json_feature_show_fields_plm_config(struct json_object *r, unsigned int result, + unsigned char *buf) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Predictable Latency Window Enabled", result & 1 ? "True" : "False"); if (buf) json_plm_config((struct nvme_plm_config *)buf, r); - - json_print(r); } -static void json_feature_show_fields_plm_window(unsigned int result) +static void json_feature_show_fields_plm_window(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Window Select", nvme_plm_window_to_string(result)); - - json_print(r); } -static void json_feature_show_fields_lba_sts_interval(unsigned int result) +static void json_feature_show_fields_lba_sts_interval(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "LBA Status Information Poll Interval (LSIPI)", result >> 16); obj_add_uint(r, "LBA Status Information Report Interval (LSIRI)", result & 0xffff); - - json_print(r); } -static void json_feature_show_fields_host_behavior(unsigned char *buf) +static void json_feature_show_fields_host_behavior(struct json_object *r, unsigned char *buf) { - struct json_object *r = json_create_object(); - if (buf) obj_add_str(r, "Host Behavior Support", buf[0] & 0x1 ? "True" : "False"); - - json_print(r); } -static void json_feature_show_fields_sanitize(unsigned int result) +static void json_feature_show_fields_sanitize(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "No-Deallocate Response Mode (NODRM)", result & 1); - - json_print(r); } -static void json_feature_show_fields_endurance_evt_cfg(unsigned int result) +static void json_feature_show_fields_endurance_evt_cfg(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Endurance Group Identifier (ENDGID)", result & 0xffff); obj_add_uint(r, "Endurance Group Critical Warnings", result >> 16 & 0xff); - - json_print(r); } -static void json_feature_show_fields_iocs_profile(unsigned int result) +static void json_feature_show_fields_iocs_profile(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "I/O Command Set Profile", result & 0x1 ? "True" : "False"); - - json_print(r); } -static void json_feature_show_fields_spinup_control(unsigned int result) +static void json_feature_show_fields_spinup_control(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Spinup control feature Enabled", result & 1 ? "True" : "False"); - - json_print(r); } -static void json_host_metadata(enum nvme_features_id fid, struct nvme_host_metadata *data) +static void json_host_metadata(struct json_object *r, enum nvme_features_id fid, + struct nvme_host_metadata *data) { - struct json_object *r = json_create_object(); struct nvme_metadata_element_desc *desc = &data->descs[0]; int i; char val[VAL_LEN]; @@ -3426,28 +3352,22 @@ static void json_host_metadata(enum nvme_features_id fid, struct nvme_host_metad desc = (struct nvme_metadata_element_desc *)&desc->val[desc->len]; } - - json_print(r); } -static void json_feature_show_fields_ns_metadata(enum nvme_features_id fid, unsigned char *buf) +static void json_feature_show_fields_ns_metadata(struct json_object *r, enum nvme_features_id fid, + unsigned char *buf) { if (buf) - json_host_metadata(fid, (struct nvme_host_metadata *)buf); + json_host_metadata(r, fid, (struct nvme_host_metadata *)buf); } -static void json_feature_show_fields_sw_progress(unsigned int result) +static void json_feature_show_fields_sw_progress(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_uint(r, "Pre-boot Software Load Count (PBSLC)", result & 0xff); - - json_print(r); } -static void json_feature_show_fields_host_id(unsigned char *buf) +static void json_feature_show_fields_host_id(struct json_object *r, unsigned char *buf) { - struct json_object *r = json_create_object(); uint64_t ull = 0; int i; @@ -3459,55 +3379,37 @@ static void json_feature_show_fields_host_id(unsigned char *buf) } obj_add_uint64(r, "Host Identifier (HOSTID)", ull); } - - json_print(r); } -static void json_feature_show_fields_resv_mask(unsigned int result) +static void json_feature_show_fields_resv_mask(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Mask Reservation Preempted Notification (RESPRE)", (result & 8) >> 3 ? "True" : "False"); obj_add_str(r, "Mask Reservation Released Notification (RESREL)", (result & 4) >> 2 ? "True" : "False"); obj_add_str(r, "Mask Registration Preempted Notification (REGPRE)", (result & 2) >> 1 ? "True" : "False"); - - json_print(r); } -static void json_feature_show_fields_resv_persist(unsigned int result) +static void json_feature_show_fields_resv_persist(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Persist Through Power Loss (PTPL)", result & 1 ? "True" : "False"); - - json_print(r); } -static void json_feature_show_fields_write_protect(unsigned int result) +static void json_feature_show_fields_write_protect(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Namespace Write Protect", nvme_ns_wp_cfg_to_string(result)); - - json_print(r); } -static void json_feature_show_fields_fdp(unsigned int result) +static void json_feature_show_fields_fdp(struct json_object *r, unsigned int result) { - struct json_object *r = json_create_object(); - obj_add_str(r, "Flexible Direct Placement Enable (FDPE)", result & 1 ? "Yes" : "No"); obj_add_uint(r, "Flexible Direct Placement Configuration Index", result >> 8 & 0xf); - - json_print(r); } -static void json_feature_show_fields_fdp_events(unsigned int result, unsigned char *buf) +static void json_feature_show_fields_fdp_events(struct json_object *r, unsigned int result, + unsigned char *buf) { - struct json_object *r = json_create_object(); unsigned int i; struct nvme_fdp_supported_event_desc *d; char json_str[STR_LEN]; @@ -3517,139 +3419,145 @@ static void json_feature_show_fields_fdp_events(unsigned int result, unsigned ch sprintf(json_str, "%s", d->evta & 0x1 ? "Enabled" : "Not enabled"); obj_add_str(r, nvme_fdp_event_to_string(d->evt), json_str); } - - json_print(r); } static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int result) { - struct json_object *r = json_create_object(); + struct json_object *r; char json_str[STR_LEN]; - sprintf(json_str, "%#0*x", fid ? 4 : 2, fid); - obj_add_str(r, "Feature", json_str); + sprintf(json_str, "Feature: %#0*x", fid ? 4 : 2, fid); + r = obj_create(json_str); obj_add_str(r, "Name", nvme_feature_to_string(fid)); sprintf(json_str, "%#0*x", result ? 10 : 8, result); obj_add_str(r, nvme_select_to_string(sel), json_str); - json_print(r); + obj_print(r); } static void json_feature_show_fields(enum nvme_features_id fid, unsigned int result, unsigned char *buf) { + struct json_object *r; + char json_str[STR_LEN]; + + sprintf(json_str, "Feature: %#0*x", fid ? 4 : 2, fid); + r = obj_create(json_str); + switch (fid) { case NVME_FEAT_FID_ARBITRATION: - json_feature_show_fields_arbitration(result); + json_feature_show_fields_arbitration(r, result); break; case NVME_FEAT_FID_POWER_MGMT: - json_feature_show_fields_power_mgmt(result); + json_feature_show_fields_power_mgmt(r, result); break; case NVME_FEAT_FID_LBA_RANGE: - json_feature_show_fields_lba_range(result & 0x3f, buf); + json_feature_show_fields_lba_range(r, result & 0x3f, buf); break; case NVME_FEAT_FID_TEMP_THRESH: - json_feature_show_fields_temp_thresh(result); + json_feature_show_fields_temp_thresh(r, result); break; case NVME_FEAT_FID_ERR_RECOVERY: - json_feature_show_fields_err_recovery(result); + json_feature_show_fields_err_recovery(r, result); break; case NVME_FEAT_FID_VOLATILE_WC: - json_feature_show_fields_volatile_wc(result); + json_feature_show_fields_volatile_wc(r, result); break; case NVME_FEAT_FID_NUM_QUEUES: - json_feature_show_fields_num_queues(result); + json_feature_show_fields_num_queues(r, result); break; case NVME_FEAT_FID_IRQ_COALESCE: - json_feature_show_fields_irq_coalesce(result); + json_feature_show_fields_irq_coalesce(r, result); break; case NVME_FEAT_FID_IRQ_CONFIG: - json_feature_show_fields_irq_config(result); + json_feature_show_fields_irq_config(r, result); break; case NVME_FEAT_FID_WRITE_ATOMIC: - json_feature_show_fields_write_atomic(result); + json_feature_show_fields_write_atomic(r, result); break; case NVME_FEAT_FID_ASYNC_EVENT: - json_feature_show_fields_async_event(result); + json_feature_show_fields_async_event(r, result); break; case NVME_FEAT_FID_AUTO_PST: - json_feature_show_fields_auto_pst(result, buf); + json_feature_show_fields_auto_pst(r, result, buf); break; case NVME_FEAT_FID_HOST_MEM_BUF: - json_feature_show_fields_host_mem_buf(result, buf); + json_feature_show_fields_host_mem_buf(r, result, buf); break; case NVME_FEAT_FID_TIMESTAMP: - json_feature_show_fields_timestamp(buf); + json_feature_show_fields_timestamp(r, buf); break; case NVME_FEAT_FID_KATO: - json_feature_show_fields_kato(result); + json_feature_show_fields_kato(r, result); break; case NVME_FEAT_FID_HCTM: - json_feature_show_fields_hctm(result); + json_feature_show_fields_hctm(r, result); break; case NVME_FEAT_FID_NOPSC: - json_feature_show_fields_nopsc(result); + json_feature_show_fields_nopsc(r, result); break; case NVME_FEAT_FID_RRL: - json_feature_show_fields_rrl(result); + json_feature_show_fields_rrl(r, result); break; case NVME_FEAT_FID_PLM_CONFIG: - json_feature_show_fields_plm_config(result, buf); + json_feature_show_fields_plm_config(r, result, buf); break; case NVME_FEAT_FID_PLM_WINDOW: - json_feature_show_fields_plm_window(result); + json_feature_show_fields_plm_window(r, result); break; case NVME_FEAT_FID_LBA_STS_INTERVAL: - json_feature_show_fields_lba_sts_interval(result); + json_feature_show_fields_lba_sts_interval(r, result); break; case NVME_FEAT_FID_HOST_BEHAVIOR: - json_feature_show_fields_host_behavior(buf); + json_feature_show_fields_host_behavior(r, buf); break; case NVME_FEAT_FID_SANITIZE: - json_feature_show_fields_sanitize(result); + json_feature_show_fields_sanitize(r, result); break; case NVME_FEAT_FID_ENDURANCE_EVT_CFG: - json_feature_show_fields_endurance_evt_cfg(result); + json_feature_show_fields_endurance_evt_cfg(r, result); break; case NVME_FEAT_FID_IOCS_PROFILE: - json_feature_show_fields_iocs_profile(result); + json_feature_show_fields_iocs_profile(r, result); break; case NVME_FEAT_FID_SPINUP_CONTROL: - json_feature_show_fields_spinup_control(result); + json_feature_show_fields_spinup_control(r, result); break; case NVME_FEAT_FID_ENH_CTRL_METADATA: fallthrough; case NVME_FEAT_FID_CTRL_METADATA: fallthrough; case NVME_FEAT_FID_NS_METADATA: - json_feature_show_fields_ns_metadata(fid, buf); + json_feature_show_fields_ns_metadata(r, fid, buf); break; case NVME_FEAT_FID_SW_PROGRESS: - json_feature_show_fields_sw_progress(result); + json_feature_show_fields_sw_progress(r, result); break; case NVME_FEAT_FID_HOST_ID: - json_feature_show_fields_host_id(buf); + json_feature_show_fields_host_id(r, buf); break; case NVME_FEAT_FID_RESV_MASK: - json_feature_show_fields_resv_mask(result); + json_feature_show_fields_resv_mask(r, result); break; case NVME_FEAT_FID_RESV_PERSIST: - json_feature_show_fields_resv_persist(result); + json_feature_show_fields_resv_persist(r, result); break; case NVME_FEAT_FID_WRITE_PROTECT: - json_feature_show_fields_write_protect(result); + json_feature_show_fields_write_protect(r, result); break; case NVME_FEAT_FID_FDP: - json_feature_show_fields_fdp(result); + json_feature_show_fields_fdp(r, result); break; case NVME_FEAT_FID_FDP_EVENTS: - json_feature_show_fields_fdp_events(result, buf); + json_feature_show_fields_fdp_events(r, result, buf); break; default: break; } + + obj_print(r); } void json_id_ctrl_rpmbs(__le32 ctrl_rpmbs) @@ -4505,6 +4413,19 @@ static void json_output_perror(const char *msg) free(error); } +void json_show_init(void) +{ + json_r = json_create_object(); +} + +void json_show_finish(void) +{ + if (json_r) + json_output_object(json_r); + + json_r = NULL; +} + static struct print_ops json_print_ops = { /* libnvme types.h print functions */ .ana_log = json_ana_log, @@ -4569,6 +4490,8 @@ static struct print_ops json_print_ops = { .lba_range = json_lba_range, .lba_status_info = json_lba_status_info, .d = json_d, + .show_init = json_show_init, + .show_finish = json_show_finish, /* libnvme tree print functions */ .list_item = json_list_item, diff --git a/nvme-print-stdout.c b/nvme-print-stdout.c index 40d17cbf..1b51edb4 100644 --- a/nvme-print-stdout.c +++ b/nvme-print-stdout.c @@ -1668,7 +1668,7 @@ static void stdout_status(int status) static void stdout_error_status(int status, const char *msg, va_list ap) { vfprintf(stderr, msg, ap); - + fprintf(stderr, ": "); stdout_status(status); } @@ -5149,6 +5149,8 @@ static struct print_ops stdout_print_ops = { .lba_range = stdout_lba_range, .lba_status_info = stdout_lba_status_info, .d = stdout_d, + .show_init = NULL, + .show_finish = NULL, /* libnvme tree print functions */ .list_item = stdout_list_item, diff --git a/nvme-print.c b/nvme-print.c index 920929eb..e1efe496 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -15,15 +15,15 @@ #include "util/types.h" #include "common.h" -#define nvme_print(name, flags, ...) \ -do { \ - struct print_ops *ops = nvme_print_ops(flags); \ - if (ops) { \ - if (ops->name) \ - ops->name(__VA_ARGS__); \ - return; \ - } \ -} while(0); +#define nvme_print(name, flags, ...) \ + do { \ + struct print_ops *ops = nvme_print_ops(flags); \ + if (ops && ops->name) \ + ops->name(__VA_ARGS__); \ + } while (false) + +#define nvme_print_output_format(name, ...) \ + nvme_print(name, nvme_is_output_format_json() ? JSON : NORMAL, ##__VA_ARGS__); static struct print_ops *nvme_print_ops(enum nvme_print_flags flags) { @@ -135,7 +135,6 @@ void nvme_show_predictable_latency_per_nvmset( __u16 nvmset_id, const char *devname, enum nvme_print_flags flags) { - nvme_print(predictable_latency_per_nvmset, flags, plpns_log, nvmset_id, devname); } @@ -279,7 +278,6 @@ void nvme_show_fdp_configs(struct nvme_fdp_config_log *log, size_t len, void nvme_show_fdp_usage(struct nvme_fdp_ruhu_log *log, size_t len, enum nvme_print_flags flags) { - nvme_print(fdp_usage_log, flags,log, len); } @@ -312,7 +310,6 @@ void nvme_show_fdp_events(struct nvme_fdp_events_log *log, void nvme_show_fdp_ruh_status(struct nvme_fdp_ruh_status *status, size_t len, enum nvme_print_flags flags) { - nvme_print(fdp_ruh_status, flags, status, len); } @@ -394,20 +391,18 @@ void d_raw(unsigned char *buf, unsigned len) void nvme_show_status(int status) { - struct print_ops *ops = nvme_print_ops(0); + struct print_ops *ops = nvme_print_ops(NORMAL); if (nvme_is_output_format_json()) ops = nvme_print_ops(JSON); - if (!ops || !ops->show_status) - return; - - ops->show_status(status); + if (ops && ops->show_status) + ops->show_status(status); } void nvme_show_error_status(int status, const char *msg, ...) { - struct print_ops *ops = nvme_print_ops(0); + struct print_ops *ops = nvme_print_ops(NORMAL); va_list ap; va_start(ap, msg); @@ -612,13 +607,13 @@ const char *nvme_trtype_to_string(__u8 trtype) } void nvme_show_error_log(struct nvme_error_log_page *err_log, int entries, - const char *devname, enum nvme_print_flags flags) + const char *devname, enum nvme_print_flags flags) { nvme_print(error_log, flags, err_log, entries, devname); } void nvme_show_resv_report(struct nvme_resv_status *status, int bytes, - bool eds, enum nvme_print_flags flags) + bool eds, enum nvme_print_flags flags) { nvme_print(resv_report, flags, status, bytes, eds); } @@ -873,9 +868,8 @@ const char *nvme_ns_wp_cfg_to_string(enum nvme_ns_write_protect_cfg state) } void nvme_directive_show(__u8 type, __u8 oper, __u16 spec, __u32 nsid, __u32 result, - void *buf, __u32 len, enum nvme_print_flags flags) + void *buf, __u32 len, enum nvme_print_flags flags) { - nvme_print(directive, flags, type, oper, spec, nsid, result, buf, len); } @@ -967,7 +961,7 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un } void nvme_show_lba_status(struct nvme_lba_status *list, unsigned long len, - enum nvme_print_flags flags) + enum nvme_print_flags flags) { nvme_print(lba_status, flags, list, len); } @@ -1027,16 +1021,15 @@ void nvme_show_topology(nvme_root_t r, enum nvme_cli_topo_ranking ranking, enum nvme_print_flags flags) { - if (ranking == NVME_CLI_TOPO_NAMESPACE) { + if (ranking == NVME_CLI_TOPO_NAMESPACE) nvme_print(topology_namespace, flags, r); - } else { + else nvme_print(topology_ctrl, flags, r); - } } void nvme_show_message(bool error, const char *msg, ...) { - struct print_ops *ops = nvme_print_ops(0); + struct print_ops *ops = nvme_print_ops(NORMAL); va_list ap; va_start(ap, msg); @@ -1052,19 +1045,13 @@ void nvme_show_message(bool error, const char *msg, ...) void nvme_show_perror(const char *msg) { - struct print_ops *ops; + struct print_ops *ops = nvme_print_ops(NORMAL); if (nvme_is_output_format_json()) ops = nvme_print_ops(JSON); - else - ops = nvme_print_ops(0); - - if (!ops) - return; - if (!ops->show_perror) - return; - ops->show_perror(msg); + if (ops && ops->show_perror) + ops->show_perror(msg); } void nvme_show_discovery_log(struct nvmf_discovery_log *log, uint64_t numrec, @@ -1077,3 +1064,13 @@ void nvme_show_connect_msg(nvme_ctrl_t c, enum nvme_print_flags flags) { nvme_print(connect_msg, flags, c); } + +void nvme_show_init(void) +{ + nvme_print_output_format(show_init); +} + +void nvme_show_finish(void) +{ + nvme_print_output_format(show_finish); +} diff --git a/nvme-print.h b/nvme-print.h index 6961a31f..73bd07d3 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -83,6 +83,8 @@ struct print_ops { void (*lba_range)(struct nvme_lba_range_type *lbrt, int nr_ranges); void (*lba_status_info)(__u32 result); void (*d)(unsigned char *buf, int len, int width, int group); + void (*show_init)(void); + void (*show_finish)(void); /* libnvme tree print functions */ void (*list_item)(nvme_ns_t n); @@ -306,5 +308,6 @@ void nvme_generic_full_path(nvme_ns_t n, char *path, size_t len); void nvme_show_message(bool error, const char *msg, ...); void nvme_show_perror(const char *msg); void nvme_show_error_status(int status, const char *msg, ...); - -#endif +void nvme_show_init(void); +void nvme_show_finish(void); +#endif /* NVME_PRINT_H */ diff --git a/nvme.c b/nvme.c index c270fcd0..cfc701bb 100644 --- a/nvme.c +++ b/nvme.c @@ -4649,7 +4649,7 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg) continue; if (!nvme_status_equals(status, type, NVME_SC_INVALID_NS)) break; - nvme_show_error_status(err, "get-feature:%#0*x (%s): ", cfg.feature_id ? 4 : 2, + nvme_show_error_status(err, "get-feature:%#0*x (%s)", cfg.feature_id ? 4 : 2, cfg.feature_id, nvme_feature_to_string(cfg.feature_id)); } @@ -4726,8 +4726,12 @@ static int get_feature(int argc, char **argv, struct command *cmd, return -1; } + nvme_show_init(); + err = get_feature_ids(dev, cfg); + nvme_show_finish(); + return err; } -- 2.50.1