Bug Summary

File:.build-ci/../plugins/ocp/ocp-nvme.c
Warning:line 969, column 4
Value stored to 'm_512_off' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ocp-nvme.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -fcoverage-compilation-dir=/__w/nvme-cli/nvme-cli/.build-ci -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /__w/nvme-cli/nvme-cli/.build-ci/nvme-config.h -I nvme.p -I . -I .. -I ccan -I ../ccan -I libnvme/src -I ../libnvme/src -I /usr/include/json-c -D _FILE_OFFSET_BITS=64 -D _GNU_SOURCE -U NDEBUG -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -std=gnu99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-opt-analyze-headers -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /__w/nvme-cli/nvme-cli/.build-ci/scan-results/2026-06-24-175442-590-1 -x c ../plugins/ocp/ocp-nvme.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2023 Meta Platforms, Inc.
4 *
5 * Authors: Arthur Shau <arthurshau@meta.com>,
6 * Wei Zhang <wzhang@meta.com>,
7 * Venkat Ramesh <venkatraghavan@meta.com>
8 */
9#include <stdio.h>
10#include <string.h>
11#include <stdlib.h>
12#include <inttypes.h>
13#include <errno(*__errno_location ()).h>
14#include <limits.h>
15#include <fcntl.h>
16#include <unistd.h>
17#include <time.h>
18
19#include <libnvme.h>
20
21#include "common.h"
22#include "logging.h"
23#include "nvme-cmds.h"
24#include "nvme-print.h"
25#include "nvme.h"
26#include "plugin.h"
27#include "util/types.h"
28
29#include "ocp-smart-extended-log.h"
30#include "ocp-clear-features.h"
31#include "ocp-fw-activation-history.h"
32#include "ocp-telemetry-decode.h"
33#include "ocp-hardware-component-log.h"
34#include "ocp-print.h"
35#include "ocp-types.h"
36
37#define CREATE_CMD
38#include "ocp-nvme.h"
39#include "ocp-utils.h"
40
41///////////////////////////////////////////////////////////////////////////////
42///////////////////////////////////////////////////////////////////////////////
43///////////////////////////////////////////////////////////////////////////////
44///////////////////////////////////////////////////////////////////////////////
45/// Latency Monitor Log
46
47#define C3_LATENCY_MON_LOG_BUF_LEN0x200 0x200
48
49static __u8 lat_mon_guid[GUID_LEN16] = {
50 0x92, 0x7a, 0xc0, 0x8c,
51 0xd0, 0x84, 0x6c, 0x9c,
52 0x70, 0x43, 0xe6, 0xd4,
53 0x58, 0x5e, 0xd4, 0x85
54};
55
56#define RESERVED0 0
57
58struct __packed__attribute__((__packed__)) feature_latency_monitor {
59 __le16 active_bucket_timer_threshold;
60 __u8 active_threshold_a;
61 __u8 active_threshold_b;
62 __u8 active_threshold_c;
63 __u8 active_threshold_d;
64 __le16 active_latency_config;
65 __u8 active_latency_minimum_window;
66 __le16 debug_log_trigger_enable;
67 __u8 discard_debug_log;
68 __u8 latency_monitor_feature_enable;
69 __u8 reserved[4083];
70};
71
72struct erri_entry {
73 union {
74 __u8 flags;
75 struct {
76 __u8 enable:1;
77 __u8 single:1;
78 __u8 rsvd2:6;
79 };
80 };
81 __u8 rsvd1;
82 __le16 type;
83 union {
84 __u8 specific[28];
85 struct {
86 __le16 nrtdp;
87 __u8 rsvd4[26];
88 };
89 };
90};
91
92#define ERRI_ENTRIES_MAX127 127
93
94enum erri_type {
95 ERRI_TYPE_CPU_CTRL_HANG = 1,
96 ERRI_TYPE_NAND_HANG,
97 ERRI_TYPE_PLP_DEFECT,
98 ERRI_TYPE_LOGICAL_FIRMWARE_ERROR,
99 ERRI_TYPE_DRAM_CORRUPT_CRIT,
100 ERRI_TYPE_DRAM_CORRUPT_NON_CRIT,
101 ERRI_TYPE_NAND_CORRUPT,
102 ERRI_TYPE_SRAM_CORRUPT,
103 ERRI_TYPE_HW_MALFUNCTION,
104 ERRI_TYPE_NO_MORE_NAND_SPARES,
105 ERRI_TYPE_INCOMPLETE_SHUTDOWN,
106 ERRI_TYPE_METADATA_CORRUPTION,
107 ERRI_TYPE_CRITICAL_GC,
108 ERRI_TYPE_LATENCY_SPIKE,
109 ERRI_TYPE_IO_CMD_FAILURE,
110 ERRI_TYPE_IO_CMD_TIMEOUT,
111 ERRI_TYPE_ADMIN_CMD_FAILURE,
112 ERRI_TYPE_ADMIN_CMD_TIMEOUT,
113 ERRI_TYPE_THERMAL_THROTTLE_ENGAGED,
114 ERRI_TYPE_THERMAL_THROTTLE_DISENGAGED,
115 ERRI_TYPE_CRITICAL_TEMPERATURE_EVENT,
116 ERRI_TYPE_DIE_OFFLINE,
117};
118
119const char *erri_type_to_string(__le16 type)
120{
121 switch (type) {
122 case ERRI_TYPE_CPU_CTRL_HANG:
123 return "CPU/controller hang";
124 case ERRI_TYPE_NAND_HANG:
125 return "NAND hang";
126 case ERRI_TYPE_PLP_DEFECT:
127 return "PLP defect";
128 case ERRI_TYPE_LOGICAL_FIRMWARE_ERROR:
129 return "logical firmware error";
130 case ERRI_TYPE_DRAM_CORRUPT_CRIT:
131 return "DRAM corruption critical path";
132 case ERRI_TYPE_DRAM_CORRUPT_NON_CRIT:
133 return "DRAM corruption non-critical path";
134 case ERRI_TYPE_NAND_CORRUPT:
135 return "NAND corruption";
136 case ERRI_TYPE_SRAM_CORRUPT:
137 return "SRAM corruption";
138 case ERRI_TYPE_HW_MALFUNCTION:
139 return "HW malfunction";
140 case ERRI_TYPE_NO_MORE_NAND_SPARES:
141 return "no more NAND spares available";
142 case ERRI_TYPE_INCOMPLETE_SHUTDOWN:
143 return "incomplete shutdown";
144 case ERRI_TYPE_METADATA_CORRUPTION:
145 return "Metadata Corruption";
146 case ERRI_TYPE_CRITICAL_GC:
147 return "Critical Garbage Collection";
148 case ERRI_TYPE_LATENCY_SPIKE:
149 return "Latency Spike";
150 case ERRI_TYPE_IO_CMD_FAILURE:
151 return "I/O command failure";
152 case ERRI_TYPE_IO_CMD_TIMEOUT:
153 return "I/O command timeout";
154 case ERRI_TYPE_ADMIN_CMD_FAILURE:
155 return "Admin command failure";
156 case ERRI_TYPE_ADMIN_CMD_TIMEOUT:
157 return "Admin command timeout";
158 case ERRI_TYPE_THERMAL_THROTTLE_ENGAGED:
159 return "Thermal Throttle Engaged";
160 case ERRI_TYPE_THERMAL_THROTTLE_DISENGAGED:
161 return "Thermal Throttle Disengaged";
162 case ERRI_TYPE_CRITICAL_TEMPERATURE_EVENT:
163 return "Critical Temperature Event";
164 case ERRI_TYPE_DIE_OFFLINE:
165 return "Die Offline";
166 default:
167 break;
168 }
169
170 return "unknown";
171}
172
173struct erri_get_cq_entry {
174 __u32 nume:7;
175 __u32 rsvd7:25;
176};
177
178struct erri_config {
179 char *file;
180 __u8 number;
181 __u16 type;
182 __u16 nrtdp;
183};
184
185struct ieee1667_get_cq_entry {
186 __u32 enabled:3;
187 __u32 rsvd3:29;
188};
189
190static const char *sel = "[0-3]: current/default/saved/supported";
191static const char *no_uuid = "Skip UUID index search (UUID index not required for OCP 1.0)";
192static const char *all_ns = "Apply to all namespaces";
193const char *data = "Error injection data structure entries";
194const char *number = "Number of valid error injection data entries";
195static const char *type = "Error injection type";
196static const char *nrtdp = "Number of reads to trigger device panic";
197static const char *save = "Specifies that the controller shall save the attribute";
198static const char *enable_ieee1667_silo = "enable IEEE1667 silo";
199static const char *raw_use = "use binary output";
200
201static int get_c3_log_page(struct libnvme_transport_handle *hdl, char *format)
202{
203 struct ssd_latency_monitor_log *log_data;
204 nvme_print_flags_t fmt;
205 int ret;
206 __u8 *data;
207 int i;
208
209 ret = validate_output_format(format, &fmt);
210 if (ret < 0) {
211 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
212 return ret;
213 }
214
215 data = malloc(sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN0x200);
216 if (!data) {
217 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
218 return -1;
219 }
220 memset(data, 0, sizeof(__u8) * C3_LATENCY_MON_LOG_BUF_LEN0x200);
221
222 ret = ocp_get_log_simple(hdl, OCP_LID_LMLOG, C3_LATENCY_MON_LOG_BUF_LEN0x200, data);
223
224 if (strcmp(format, "json"))
225 fprintf(stderrstderr, "NVMe Status:%s(%x)\n", libnvme_status_to_string(ret, false0), ret);
226
227 if (!ret) {
228 log_data = (struct ssd_latency_monitor_log *)data;
229
230 /*
231 * check log page guid
232 * Verify GUID matches
233 */
234 for (i = 0; i < 16; i++) {
235 if (lat_mon_guid[i] != log_data->log_page_guid[i]) {
236 int j;
237
238 fprintf(stderrstderr, "ERROR : OCP : Unknown GUID in C3 Log Page data\n");
239 fprintf(stderrstderr, "ERROR : OCP : Expected GUID: 0x");
240 for (j = 0; j < 16; j++)
241 fprintf(stderrstderr, "%02x", lat_mon_guid[j]);
242
243 fprintf(stderrstderr, "\nERROR : OCP : Actual GUID: 0x");
244 for (j = 0; j < 16; j++)
245 fprintf(stderrstderr, "%02x", log_data->log_page_guid[j]);
246 fprintf(stderrstderr, "\n");
247
248 ret = -1;
249 goto out;
250 }
251 }
252 ocp_c3_log(hdl, log_data, fmt);
253 } else {
254 fprintf(stderrstderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
255 }
256
257out:
258 free(data);
259 return ret;
260}
261
262static int ocp_latency_monitor_log(int argc, char **argv,
263 struct command *command,
264 struct plugin *plugin)
265{
266 const char *desc = "Retrieve latency monitor log data.";
267 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
268 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
269 int ret = 0;
270
271 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
272
273 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
274 if (ret)
275 return ret;
276
277 ret = get_c3_log_page(hdl, nvme_args.output_format);
278 if (ret)
279 fprintf(stderrstderr,
280 "ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n",
281 ret);
282
283 return ret;
284}
285
286int ocp_set_latency_monitor_feature(int argc, char **argv, struct command *acmd, struct plugin *plugin)
287{
288 int err = -1;
289 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
290 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
291 __u64 result;
292 struct feature_latency_monitor buf = { 0 };
293 __u32 nsid = NVME_NSID_ALL;
294 struct nvme_id_ctrl ctrl;
295
296 const char *desc = "Set Latency Monitor feature.";
297 const char *active_bucket_timer_threshold = "This is the value that loads the Active Bucket Timer Threshold.";
298 const char *active_threshold_a = "This is the value that loads into the Active Threshold A.";
299 const char *active_threshold_b = "This is the value that loads into the Active Threshold B.";
300 const char *active_threshold_c = "This is the value that loads into the Active Threshold C.";
301 const char *active_threshold_d = "This is the value that loads into the Active Threshold D.";
302 const char *active_latency_config = "This is the value that loads into the Active Latency Configuration.";
303 const char *active_latency_minimum_window = "This is the value that loads into the Active Latency Minimum Window.";
304 const char *debug_log_trigger_enable = "This is the value that loads into the Debug Log Trigger Enable.";
305 const char *discard_debug_log = "Discard Debug Log.";
306 const char *latency_monitor_feature_enable = "Latency Monitor Feature Enable.";
307
308 struct config {
309 __u16 active_bucket_timer_threshold;
310 __u8 active_threshold_a;
311 __u8 active_threshold_b;
312 __u8 active_threshold_c;
313 __u8 active_threshold_d;
314 __u16 active_latency_config;
315 __u8 active_latency_minimum_window;
316 __u16 debug_log_trigger_enable;
317 __u8 discard_debug_log;
318 __u8 latency_monitor_feature_enable;
319 };
320
321 struct config cfg = {
322 .active_bucket_timer_threshold = 0x7E0,
323 .active_threshold_a = 0x5,
324 .active_threshold_b = 0x13,
325 .active_threshold_c = 0x1E,
326 .active_threshold_d = 0x2E,
327 .active_latency_config = 0xFFF,
328 .active_latency_minimum_window = 0xA,
329 .debug_log_trigger_enable = 0,
330 .discard_debug_log = 0,
331 .latency_monitor_feature_enable = 0x1,
332 };
333
334 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
335 OPT_UINT("active_bucket_timer_threshold", 't', &cfg.active_bucket_timer_threshold, active_bucket_timer_threshold),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
336 OPT_UINT("active_threshold_a", 'a', &cfg.active_threshold_a, active_threshold_a),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
337 OPT_UINT("active_threshold_b", 'b', &cfg.active_threshold_b, active_threshold_b),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
338 OPT_UINT("active_threshold_c", 'c', &cfg.active_threshold_c, active_threshold_c),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
339 OPT_UINT("active_threshold_d", 'd', &cfg.active_threshold_d, active_threshold_d),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
340 OPT_UINT("active_latency_config", 'f', &cfg.active_latency_config, active_latency_config),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
341 OPT_UINT("active_latency_minimum_window", 'w', &cfg.active_latency_minimum_window, active_latency_minimum_window),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
342 OPT_UINT("debug_log_trigger_enable", 'r', &cfg.debug_log_trigger_enable, debug_log_trigger_enable),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
343 OPT_UINT("discard_debug_log", 'l', &cfg.discard_debug_log, discard_debug_log),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
344 OPT_UINT("latency_monitor_feature_enable", 'e', &cfg.latency_monitor_feature_enable, latency_monitor_feature_enable))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"active_bucket_timer_threshold", 't', "NUM", CFG_POSITIVE
, &cfg.active_bucket_timer_threshold, 1, active_bucket_timer_threshold
, 0, }, {"active_threshold_a", 'a', "NUM", CFG_POSITIVE, &
cfg.active_threshold_a, 1, active_threshold_a, 0, }, {"active_threshold_b"
, 'b', "NUM", CFG_POSITIVE, &cfg.active_threshold_b, 1, active_threshold_b
, 0, }, {"active_threshold_c", 'c', "NUM", CFG_POSITIVE, &
cfg.active_threshold_c, 1, active_threshold_c, 0, }, {"active_threshold_d"
, 'd', "NUM", CFG_POSITIVE, &cfg.active_threshold_d, 1, active_threshold_d
, 0, }, {"active_latency_config", 'f', "NUM", CFG_POSITIVE, &
cfg.active_latency_config, 1, active_latency_config, 0, }, {"active_latency_minimum_window"
, 'w', "NUM", CFG_POSITIVE, &cfg.active_latency_minimum_window
, 1, active_latency_minimum_window, 0, }, {"debug_log_trigger_enable"
, 'r', "NUM", CFG_POSITIVE, &cfg.debug_log_trigger_enable
, 1, debug_log_trigger_enable, 0, }, {"discard_debug_log", 'l'
, "NUM", CFG_POSITIVE, &cfg.discard_debug_log, 1, discard_debug_log
, 0, }, {"latency_monitor_feature_enable", 'e', "NUM", CFG_POSITIVE
, &cfg.latency_monitor_feature_enable, 1, latency_monitor_feature_enable
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
345
346 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
347 if (err)
348 return err;
349
350 if (libnvme_transport_handle_is_ns(hdl)) {
351 err = libnvme_get_nsid(hdl, &nsid);
352 if (err < 0) {
353 perror("invalid-namespace-id");
354 return err;
355 }
356 }
357
358 err = nvme_identify_ctrl(hdl, &ctrl);
359 if (err)
360 return err;
361
362 buf.active_bucket_timer_threshold = cpu_to_le16(cfg.active_bucket_timer_threshold);
363 buf.active_threshold_a = cfg.active_threshold_a;
364 buf.active_threshold_b = cfg.active_threshold_b;
365 buf.active_threshold_c = cfg.active_threshold_c;
366 buf.active_threshold_d = cfg.active_threshold_d;
367 buf.active_latency_config = cpu_to_le16(cfg.active_latency_config);
368 buf.active_latency_minimum_window = cfg.active_latency_minimum_window;
369 buf.debug_log_trigger_enable = cpu_to_le16(cfg.debug_log_trigger_enable);
370 buf.discard_debug_log = cfg.discard_debug_log;
371 buf.latency_monitor_feature_enable = cfg.latency_monitor_feature_enable;
372
373 err = nvme_set_features(hdl, 0, OCP_FID_LM, 1, 0, 0, 0, 0, 0, (void *)&buf,
374 sizeof(struct feature_latency_monitor), &result);
375 if (err < 0) {
376 perror("set-feature");
377 } else if (!err) {
378 printf("NVME_FEAT_OCP_LATENCY_MONITOR: 0x%02x\n", OCP_FID_LM);
379 printf("active bucket timer threshold: 0x%x\n",
380 le16_to_cpu(buf.active_bucket_timer_threshold));
381 printf("active threshold a: 0x%x\n", buf.active_threshold_a);
382 printf("active threshold b: 0x%x\n", buf.active_threshold_b);
383 printf("active threshold c: 0x%x\n", buf.active_threshold_c);
384 printf("active threshold d: 0x%x\n", buf.active_threshold_d);
385 printf("active latency config: 0x%x\n", le16_to_cpu(buf.active_latency_config));
386 printf("active latency minimum window: 0x%x\n", buf.active_latency_minimum_window);
387 printf("debug log trigger enable: 0x%x\n",
388 le16_to_cpu(buf.debug_log_trigger_enable));
389 printf("discard debug log: 0x%x\n", buf.discard_debug_log);
390 printf("latency monitor feature enable: 0x%x\n", buf.latency_monitor_feature_enable);
391 } else if (err > 0) {
392 fprintf(stderrstderr, "NVMe Status:%s(%x)\n", libnvme_status_to_string(err, false0), err);
393 }
394
395 return err;
396}
397
398static int ocp_get_latency_monitor_feature(int argc, char **argv, struct command *acmd,
399 struct plugin *plugin)
400{
401 const char *desc = "Issue Get Feature command (FID: 0xC5) Latency Monitor";
402 const char *sel = "[0-3]: current/default/saved/supported/";
403 const char *nsid = "Byte[04-07]: Namespace Identifier Valid/Invalid/Inactive";
404
405 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
406 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
407
408 __u64 result;
409 int err;
410 bool_Bool uuid;
411 __u8 uuid_index = 0;
412
413 struct config {
414 __u8 sel;
415 __u32 nsid;
416 };
417
418 struct config cfg = {
419 .sel = 0,
420 .nsid = 0,
421 };
422
423 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
424 OPT_BYTE("sel", 's', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
425 OPT_UINT("namespace-id", 'n', &cfg.nsid, nsid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
426 OPT_FLAG("no-uuid", 'u', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
427
428 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
429 if (err)
430 return err;
431
432 uuid = !argconfig_parse_seen(opts, "no-uuid");
433
434 if (uuid) {
435 /* OCP 2.0 requires UUID index support */
436 err = ocp_get_uuid_index(hdl, &uuid_index);
437 if (err || !uuid_index) {
438 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
439 return err;
440 }
441 }
442
443 err = nvme_get_features(hdl, cfg.nsid, OCP_FID_LM, cfg.sel, 0,
444 uuid_index, NULL((void*)0), 0, &result);
445 if (!err) {
446 printf("get-feature:0xC5 %s value: %#016"PRIx64"l" "x""\n",
447 nvme_select_to_string(cfg.sel), (uint64_t)result);
448
449 if (cfg.sel == NVME_GET_FEATURES_SEL_SUPPORTED)
450 nvme_show_select_result(0xC5, result);
451 } else {
452 nvme_show_error("Could not get feature: 0xC5")nvme_show_message(1, "Could not get feature: 0xC5");
453 }
454
455 return err;
456}
457
458///////////////////////////////////////////////////////////////////////////////
459///////////////////////////////////////////////////////////////////////////////
460///////////////////////////////////////////////////////////////////////////////
461///////////////////////////////////////////////////////////////////////////////
462/// EOL/PLP Failure Mode
463
464static const char *eol_plp_failure_mode_to_string(__u8 mode)
465{
466 switch (mode) {
467 case 1:
468 return "Read only mode (ROM)";
469 case 2:
470 return "Write through mode (WTM)";
471 case 3:
472 return "Normal mode";
473 default:
474 break;
475 }
476
477 return "Reserved";
478}
479
480static int eol_plp_failure_mode_get(struct libnvme_transport_handle *hdl, const __u32 nsid, const __u8 fid,
481 __u8 sel, bool_Bool uuid)
482{
483 __u8 uidx = 0;
484 __u64 result;
485 int err;
486
487 if (uuid) {
488 /* OCP 2.0 requires UUID index support */
489 err = ocp_get_uuid_index(hdl, &uidx);
490 if (err || !uidx) {
491 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
492 return err;
493 }
494 }
495
496 err = nvme_get_features(hdl, nsid, fid, sel, 0, uidx, NULL((void*)0), 0, &result);
497 if (!err) {
498 nvme_show_result("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)",nvme_show_message(0, "End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)"
, fid ? 4 : 2, fid, result ? 10 : 8, result, nvme_select_to_string
(sel), eol_plp_failure_mode_to_string(result))
499 fid ? 4 : 2, fid, result ? 10 : 8, result,nvme_show_message(0, "End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)"
, fid ? 4 : 2, fid, result ? 10 : 8, result, nvme_select_to_string
(sel), eol_plp_failure_mode_to_string(result))
500 nvme_select_to_string(sel),nvme_show_message(0, "End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)"
, fid ? 4 : 2, fid, result ? 10 : 8, result, nvme_select_to_string
(sel), eol_plp_failure_mode_to_string(result))
501 eol_plp_failure_mode_to_string(result))nvme_show_message(0, "End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)"
, fid ? 4 : 2, fid, result ? 10 : 8, result, nvme_select_to_string
(sel), eol_plp_failure_mode_to_string(result))
;
502 if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
503 nvme_show_select_result(fid, result);
504 } else {
505 nvme_show_error("Could not get feature: %#0*x.", fid ? 4 : 2, fid)nvme_show_message(1, "Could not get feature: %#0*x.", fid ? 4
: 2, fid)
;
506 }
507
508 return err;
509}
510
511static int eol_plp_failure_mode_set(struct libnvme_transport_handle *hdl, const __u32 nsid,
512 const __u8 fid, __u8 mode, bool_Bool sv,
513 bool_Bool uuid)
514{
515 __u64 result;
516 int err;
517 __u8 uidx = 0;
518
519 if (uuid) {
520 /* OCP 2.0 requires UUID index support */
521 err = ocp_get_uuid_index(hdl, &uidx);
522 if (err || !uidx) {
523 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
524 return err;
525 }
526 }
527
528 err = nvme_set_features(hdl, nsid, fid, sv, mode << 30, 0, 0, uidx, 0, NULL((void*)0),
529 0, &result);
530 if (err > 0) {
531 nvme_show_status(err);
532 } else if (err < 0) {
533 nvme_show_perror("Define EOL/PLP failure mode");
534 fprintf(stderrstderr, "Command failed while parsing.\n");
535 } else {
536 nvme_show_result("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).",nvme_show_message(0, "Successfully set mode (feature: %#0*x): %#0*x (%s: %s)."
, fid ? 4 : 2, fid, mode ? 10 : 8, mode, sv ? "Save" : "Not save"
, eol_plp_failure_mode_to_string(mode))
537 fid ? 4 : 2, fid, mode ? 10 : 8, mode,nvme_show_message(0, "Successfully set mode (feature: %#0*x): %#0*x (%s: %s)."
, fid ? 4 : 2, fid, mode ? 10 : 8, mode, sv ? "Save" : "Not save"
, eol_plp_failure_mode_to_string(mode))
538 sv ? "Save" : "Not save",nvme_show_message(0, "Successfully set mode (feature: %#0*x): %#0*x (%s: %s)."
, fid ? 4 : 2, fid, mode ? 10 : 8, mode, sv ? "Save" : "Not save"
, eol_plp_failure_mode_to_string(mode))
539 eol_plp_failure_mode_to_string(mode))nvme_show_message(0, "Successfully set mode (feature: %#0*x): %#0*x (%s: %s)."
, fid ? 4 : 2, fid, mode ? 10 : 8, mode, sv ? "Save" : "Not save"
, eol_plp_failure_mode_to_string(mode))
;
540 }
541
542 return err;
543}
544
545static int eol_plp_failure_mode(int argc, char **argv, struct command *acmd,
546 struct plugin *plugin)
547{
548 const char *desc = "Define EOL or PLP circuitry failure mode.\n"
549 "No argument prints current mode.";
550 const char *mode = "[0-3]: default/rom/wtm/normal";
551 const __u32 nsid = 0;
552 const __u8 fid = OCP_FID_ROWTM;
553 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
554 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
555 int err;
556
557 struct config {
558 __u8 mode;
559 bool_Bool save;
560 __u8 sel;
561 };
562
563 struct config cfg = {
564 .mode = 0,
565 .save = false0,
566 .sel = 0,
567 };
568
569 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"mode", 'm', "NUM", CFG_BYTE, &cfg.mode, 1, mode,
0, }, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save
, 0, }, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0
, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
570 OPT_BYTE("mode", 'm', &cfg.mode, mode),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"mode", 'm', "NUM", CFG_BYTE, &cfg.mode, 1, mode,
0, }, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save
, 0, }, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0
, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
571 OPT_FLAG("save", 's', &cfg.save, save),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"mode", 'm', "NUM", CFG_BYTE, &cfg.mode, 1, mode,
0, }, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save
, 0, }, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0
, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
572 OPT_BYTE("sel", 'S', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"mode", 'm', "NUM", CFG_BYTE, &cfg.mode, 1, mode,
0, }, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save
, 0, }, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0
, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
573 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"mode", 'm', "NUM", CFG_BYTE, &cfg.mode, 1, mode,
0, }, {"save", 's', ((void*)0), CFG_FLAG, &cfg.save, 0, save
, 0, }, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0
, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
574
575 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
576 if (err)
577 return err;
578
579 if (argconfig_parse_seen(opts, "mode"))
580 err = eol_plp_failure_mode_set(hdl, nsid, fid, cfg.mode,
581 cfg.save,
582 !argconfig_parse_seen(opts, "no-uuid"));
583 else
584 err = eol_plp_failure_mode_get(hdl, nsid, fid, cfg.sel,
585 !argconfig_parse_seen(opts, "no-uuid"));
586
587 return err;
588}
589
590///////////////////////////////////////////////////////////////////////////////
591///////////////////////////////////////////////////////////////////////////////
592///////////////////////////////////////////////////////////////////////////////
593///////////////////////////////////////////////////////////////////////////////
594/// Telemetry Log
595//global buffers
596static __le64 total_log_page_sz;
597static __u8 *header_data;
598static struct telemetry_str_log_format *log_data;
599
600__u8 *ptelemetry_buffer;
601__u8 *pstring_buffer;
602__u8 *pC9_string_buffer;
603
604static void get_serial_number(struct nvme_id_ctrl *ctrl, char *sn)
605{
606 int i;
607
608 /* Remove trailing spaces from the name */
609 for (i = 0; i < sizeof(ctrl->sn); i++) {
610 if (ctrl->sn[i] == ' ')
611 break;
612 sn[i] = ctrl->sn[i];
613 }
614}
615
616static void print_telemetry_header(struct telemetry_initiated_log *logheader, int tele_type)
617{
618 if (logheader) {
619 unsigned int i = 0, j = 0;
620 __u8 dataGenNum;
621
622 if (tele_type == TELEMETRY_TYPE_HOST) {
623 printf("============ Telemetry Host Header ============\n");
624 dataGenNum = logheader->DataHostGenerationNumber;
625 } else {
626 printf("========= Telemetry Controller Header =========\n");
627 dataGenNum = logheader->DataCtlrGenerationNumber;
628 }
629
630 printf("Log Identifier : 0x%02X\n", logheader->LogIdentifier);
631 printf("IEEE : 0x%02X%02X%02X\n",
632 logheader->IEEE[0], logheader->IEEE[1], logheader->IEEE[2]);
633 printf("Data Area 1 Last Block : 0x%04X\n",
634 le16_to_cpu(logheader->DataArea1LastBlock));
635 printf("Data Area 2 Last Block : 0x%04X\n",
636 le16_to_cpu(logheader->DataArea2LastBlock));
637 printf("Data Area 3 Last Block : 0x%04X\n",
638 le16_to_cpu(logheader->DataArea3LastBlock));
639 printf("Data Available : 0x%02X\n",
640 logheader->CtlrDataAvailable);
641 printf("Data Generation Number : 0x%02X\n",
642 dataGenNum);
643 printf("Reason Identifier :\n");
644
645 for (i = 0; i < 8; i++) {
646 for (j = 0; j < 16; j++)
647 printf("%02X ", logheader->ReasonIdentifier[127 - ((i * 16) + j)]);
648 printf("\n");
649 }
650 printf("===============================================\n\n");
651 }
652}
653
654static int get_telemetry_data(struct libnvme_transport_handle *hdl, __u32 ns, __u8 tele_type,
655 __u32 data_len, void *data, __u8 nLSP, __u8 nRAE,
656 __u64 offset)
657{
658 struct libnvme_passthru_cmd cmd = {
659 .opcode = nvme_admin_get_log_page,
660 .nsid = ns,
661 .addr = (__u64)(uintptr_t) data,
662 .data_len = data_len,
663 };
664 __u32 numd = (data_len >> 2) - 1;
665 __u16 numdu = numd >> 16;
666 __u16 numdl = numd & 0xffff;
667
668 cmd.cdw10 = tele_type | (nLSP & 0x0F) << 8 | (nRAE & 0x01) << 15 | (numdl & 0xFFFF) << 16;
669 cmd.cdw11 = numdu;
670 cmd.cdw12 = (__u32)(0x00000000FFFFFFFF & offset);
671 cmd.cdw13 = (__u32)((0xFFFFFFFF00000000 & offset) >> 8);
672 cmd.cdw14 = 0;
673 return libnvme_exec_admin_passthru(hdl, &cmd);
674}
675
676static void print_telemetry_data_area_1(struct telemetry_data_area_1 *da1,
677 int tele_type)
678{
679 if (da1) {
680 int i = 0;
681
682 if (tele_type == TELEMETRY_TYPE_HOST)
683 printf("============ Telemetry Host Data area 1 ============\n");
684 else
685 printf("========= Telemetry Controller Data area 1 =========\n");
686 printf("Major Version : 0x%x\n", le16_to_cpu(da1->major_version));
687 printf("Minor Version : 0x%x\n", le16_to_cpu(da1->minor_version));
688 printf("Timestamp : %"PRIu64"l" "u""\n", le64_to_cpu(da1->timestamp));
689 printf("Log Page GUID : 0x");
690 for (int j = 15; j >= 0; j--)
691 printf("%02x", da1->log_page_guid[j]);
692 printf("\n");
693 printf("Number Telemetry Profiles Supported : 0x%x\n",
694 da1->no_of_tps_supp);
695 printf("Telemetry Profile Selected (TPS) : 0x%x\n",
696 da1->tps);
697 printf("Telemetry String Log Size (SLS) : 0x%"PRIx64"l" "x""\n",
698 le64_to_cpu(da1->sls));
699 printf("Firmware Revision : ");
700 for (i = 0; i < 8; i++)
701 printf("%c", (char)da1->fw_revision[i]);
702 printf("\n");
703 printf("Data Area 1 Statistic Start : 0x%"PRIx64"l" "x""\n",
704 le64_to_cpu(da1->da1_stat_start));
705 printf("Data Area 1 Statistic Size : 0x%"PRIx64"l" "x""\n",
706 le64_to_cpu(da1->da1_stat_size));
707 printf("Data Area 2 Statistic Start : 0x%"PRIx64"l" "x""\n",
708 le64_to_cpu(da1->da2_stat_start));
709 printf("Data Area 2 Statistic Size : 0x%"PRIx64"l" "x""\n",
710 le64_to_cpu(da1->da2_stat_size));
711 for (i = 0; i < 16; i++) {
712 printf("Event FIFO %d Data Area : 0x%x\n",
713 i, da1->event_fifo_da[i]);
714 printf("Event FIFO %d Start : 0x%"PRIx64"l" "x""\n",
715 i, le64_to_cpu(da1->event_fifos[i].start));
716 printf("Event FIFO %d Size : 0x%"PRIx64"l" "x""\n",
717 i, le64_to_cpu(da1->event_fifos[i].size));
718 }
719 printf("SMART / Health Information :\n");
720 printf("0x");
721 for (i = 0; i < 512; i++)
722 printf("%02x", da1->smart_health_info[i]);
723 printf("\n");
724
725 printf("SMART / Health Information Extended :\n");
726 printf("0x");
727 for (i = 0; i < 512; i++)
728 printf("%02x", da1->smart_health_info_extended[i]);
729 printf("\n");
730
731 printf("===============================================\n\n");
732 }
733}
734
735static void print_telemetry_da_stat(struct telemetry_stats_desc *da_stat, int tele_type,
736 __u16 buf_size, __u8 data_area)
737{
738 if (da_stat) {
739 unsigned int i = 0;
740 struct telemetry_stats_desc *next_da_stat = da_stat;
741
742 if (tele_type == TELEMETRY_TYPE_HOST)
743 printf("============ Telemetry Host Data Area %d Statistics ============\n",
744 data_area);
745 else
746 printf("========= Telemetry Controller Data Area %d Statistics =========\n",
747 data_area);
748 while ((i + 8) < buf_size) {
749 print_stats_desc(next_da_stat);
750 i += 8 + ((next_da_stat->size) * 4);
751 next_da_stat = (struct telemetry_stats_desc *)((void *)da_stat + i);
752
753 if ((next_da_stat->id == 0) && (next_da_stat->size == 0))
754 break;
755 }
756 printf("===============================================\n\n");
757 }
758}
759static void print_telemetry_da_fifo(struct telemetry_event_desc *da_fifo,
760 __u64 buf_size,
761 int tele_type,
762 int da,
763 int index)
764{
765 if (da_fifo) {
766 __u64 i = 0;
767 struct telemetry_event_desc *next_da_fifo = da_fifo;
768
769 if (tele_type == TELEMETRY_TYPE_HOST)
770 printf("========= Telemetry Host Data area %d Event FIFO %d =========\n",
771 da, index);
772 else
773 printf("====== Telemetry Controller Data area %d Event FIFO %d ======\n",
774 da, index);
775
776 while ((i + 4) < buf_size) {
777 /* break if last entry */
778 if (next_da_fifo->class == 0)
779 break;
780
781 /* Print Event Data */
782 print_telemetry_fifo_event(next_da_fifo->class, /* Event class type */
783 next_da_fifo->id, /* Event ID */
784 next_da_fifo->size, /* Event data size */
785 (__u8 *)&next_da_fifo->data); /* Event data */
786
787 i += (4 + (next_da_fifo->size * 4));
788 next_da_fifo = (struct telemetry_event_desc *)((void *)da_fifo + i);
789 }
790 printf("===============================================\n\n");
791 }
792}
793static int extract_dump_get_log(struct libnvme_transport_handle *hdl, char *featurename, char *filename, char *sn,
794 int dumpsize, int transfersize, __u32 nsid, __u8 log_id,
795 __u8 lsp, __u64 offset, bool_Bool rae)
796{
797 int i = 0, err = 0;
798
799 char *data = calloc(transfersize, sizeof(char));
800 char filepath[FILE_NAME_SIZE2048] = {0,};
801 int output = 0;
802 int total_loop_cnt = dumpsize / transfersize;
803 int last_xfer_size = dumpsize % transfersize;
804 struct libnvme_passthru_cmd cmd;
805
806 if (last_xfer_size)
807 total_loop_cnt++;
808 else
809 last_xfer_size = transfersize;
810
811 if (filename == 0)
812 snprintf(filepath, FILE_NAME_SIZE2048, "%s_%s.bin", featurename, sn);
813 else
814 snprintf(filepath, FILE_NAME_SIZE2048, "%s%s_%s.bin", filename, featurename, sn);
815
816 for (i = 0; i < total_loop_cnt; i++) {
817 memset(data, 0, transfersize);
818
819 nvme_init_get_log(&cmd, nsid, log_id, NVME_CSI_NVM,
820 data, transfersize);
821 nvme_init_get_log_lpo(&cmd, offset);
822 err = libnvme_get_log(hdl, &cmd, rae, NVME_LOG_PAGE_PDU_SIZE4096);
823 if (err) {
824 if (i > 0)
825 goto close_output;
826 else
827 goto end;
828 }
829
830 if (i != total_loop_cnt - 1) {
831 if (!i) {
832 output = nvme_open_rawdata(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0666)open((filepath), (01 | 0100 | 01000), 0666);
833 if (output < 0) {
834 err = -13;
835 goto end;
836 }
837 }
838 if (write(output, data, transfersize) < 0) {
839 err = -10;
840 goto close_output;
841 }
842 } else {
843 if (write(output, data, last_xfer_size) < 0) {
844 err = -10;
845 goto close_output;
846 }
847 }
848 offset += transfersize;
849 printf("%d%%\r", (i + 1) * 100 / total_loop_cnt);
850 }
851 printf("100%%\nThe log file was saved at \"%s\"\n", filepath);
852
853close_output:
854 close(output);
855
856end:
857 free(data);
858 return err;
859}
860
861static int get_telemetry_dump(struct libnvme_transport_handle *hdl, char *filename, char *sn,
862 enum TELEMETRY_TYPE tele_type, int data_area, bool_Bool header_print)
863{
864 __u32 err = 0, nsid = 0;
865 __u64 da1_sz = 512, m_512_sz = 0, da1_off = 0, m_512_off = 0, diff = 0, temp_sz = 0,
866 temp_ofst = 0;
867 __u8 lsp = 0, rae = 0, flag = 0;
868 __u8 data[TELEMETRY_HEADER_SIZE512] = { 0 };
869 unsigned int i = 0;
870 char data1[TELEMETRY_DATA_SIZE1536] = { 0 };
871 char *featurename = 0;
872 struct telemetry_initiated_log *logheader = (struct telemetry_initiated_log *)data;
873 struct telemetry_data_area_1 *da1 = (struct telemetry_data_area_1 *)data1;
874 __u64 offset = 0, size = 0;
875 char dumpname[FILE_NAME_SIZE2048] = { 0 };
876
877 if (tele_type == TELEMETRY_TYPE_HOST_0) {
878 featurename = "Host(0)";
879 lsp = 0;
880 rae = 0;
881 tele_type = TELEMETRY_TYPE_HOST;
882 } else if (tele_type == TELEMETRY_TYPE_HOST_1) {
883 featurename = "Host(1)";
884 lsp = 1;
885 rae = 0;
886 tele_type = TELEMETRY_TYPE_HOST;
887 } else {
888 featurename = "Controller";
889 lsp = 0;
890 rae = 1;
891 }
892
893 /* Get the telemetry header */
894 err = get_telemetry_data(hdl, nsid, tele_type, TELEMETRY_HEADER_SIZE512, (void *)data, lsp,
895 rae, 0);
896 if (err) {
897 printf("get_telemetry_header failed, err: %d.\n", err);
898 return err;
899 }
900
901 if (header_print)
902 print_telemetry_header(logheader, tele_type);
903
904 /* Get the telemetry data */
905 err = get_telemetry_data(hdl, nsid, tele_type, TELEMETRY_DATA_SIZE1536, (void *)data1, lsp,
906 rae, 512);
907 if (err) {
908 printf("get_telemetry_data failed for type: 0x%x, err: %d.\n", tele_type, err);
909 return err;
910 }
911
912 print_telemetry_data_area_1(da1, tele_type);
913
914 /* Print the Data Area 1 Stats */
915 if (da1->da1_stat_size != 0) {
916 diff = 0;
917 da1_sz = le64_to_cpu(da1->da1_stat_size) * 4;
918 m_512_sz = le64_to_cpu(da1->da1_stat_size) * 4;
919 da1_off = le64_to_cpu(da1->da1_stat_start) * 4;
920 m_512_off = le64_to_cpu(da1->da1_stat_start) * 4;
921 temp_sz = le64_to_cpu(da1->da1_stat_size) * 4;
922 temp_ofst = le64_to_cpu(da1->da1_stat_start) * 4;
923 flag = 0;
924
925 if ((da1_off % 512) > 0) {
926 m_512_off = (da1_off / 512);
927 da1_off = m_512_off * 512;
928 diff = temp_ofst - da1_off;
929 flag = 1;
930 }
931
932 if (da1_sz < 512) {
933 da1_sz = 512;
934 } else if ((da1_sz % 512) > 0) {
935 if (flag == 0) {
936 m_512_sz = (da1_sz / 512) + 1;
937 da1_sz = m_512_sz * 512;
938 } else {
939 if (diff < 512)
940 diff = 1;
941 else
942 diff = (diff / 512) * 512;
943
944 m_512_sz = (da1_sz / 512) + 1 + diff + 1;
945 da1_sz = m_512_sz * 512;
946 }
947 }
948
949 char *da1_stat = calloc(da1_sz, sizeof(char));
950
951 err = get_telemetry_data(hdl, nsid, tele_type, da1_sz, (void *)da1_stat, lsp, rae,
952 da1_off);
953 if (err) {
954 printf("get_telemetry_data da1 stats failed, err: %d.\n", err);
955 return err;
956 }
957
958 print_telemetry_da_stat((void *)(da1_stat + (temp_ofst - da1_off)), tele_type,
959 le64_to_cpu(da1->da1_stat_size) * 4, 1);
960 }
961
962 /* Print the Data Area 1 Event FIFO's */
963 for (i = 0; i < 16 ; i++) {
964 if ((da1->event_fifo_da[i] == 1) && (da1->event_fifos[i].size != 0)) {
965 diff = 0;
966 da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
967 m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
968 da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
969 m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
Value stored to 'm_512_off' is never read
970 temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
971 temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
972 flag = 0;
973
974 if ((da1_off % 512) > 0) {
975 m_512_off = ((da1_off / 512));
976 da1_off = m_512_off * 512;
977 diff = temp_ofst - da1_off;
978 flag = 1;
979 }
980
981 if (da1_sz < 512) {
982 da1_sz = 512;
983 } else if ((da1_sz % 512) > 0) {
984 if (flag == 0) {
985 m_512_sz = (da1_sz / 512) + 1;
986 da1_sz = m_512_sz * 512;
987 } else {
988 if (diff < 512)
989 diff = 1;
990 else
991 diff = (diff / 512) * 512;
992
993 m_512_sz = (da1_sz / 512) + 1 + diff + 1;
994 da1_sz = m_512_sz * 512;
995 }
996 }
997
998 char *da1_fifo = calloc(da1_sz, sizeof(char));
999
1000 printf("Get DA 1 FIFO addr: %p, offset 0x%"PRIx64"l" "x""\n", da1_fifo,
1001 (uint64_t)da1_off);
1002 err = get_telemetry_data(hdl, nsid, tele_type,
1003 le64_to_cpu(da1->event_fifos[i].size) * 4,
1004 (void *)da1_fifo, lsp, rae, da1_off);
1005 if (err) {
1006 printf("get_telemetry_data da1 event fifos failed, err: %d.\n",
1007 err);
1008 return err;
1009 }
1010 print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)), temp_sz,
1011 tele_type, le64_to_cpu(da1->event_fifo_da[i]), i);
1012 }
1013 }
1014
1015 /* Print the Data Area 2 Stats */
1016 if (da1->da2_stat_size != 0) {
1017 da1_off = le64_to_cpu(da1->da2_stat_start) * 4;
1018 temp_ofst = le64_to_cpu(da1->da2_stat_start) * 4;
1019 da1_sz = le64_to_cpu(da1->da2_stat_size) * 4;
1020 diff = 0;
1021 flag = 0;
1022
1023 if (da1->da2_stat_start == 0) {
1024 da1_off = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
1025 temp_ofst = 512 + (le16_to_cpu(logheader->DataArea1LastBlock) * 512);
1026 if ((da1_off % 512) == 0) {
1027 m_512_off = ((da1_off) / 512);
1028 da1_off = m_512_off * 512;
1029 diff = temp_ofst - da1_off;
1030 flag = 1;
1031 }
1032 } else {
1033 if (((da1_off * 4) % 512) > 0) {
1034 m_512_off = ((le64_to_cpu(da1->da2_stat_start) * 4) / 512);
1035 da1_off = m_512_off * 512;
1036 diff = (le64_to_cpu(da1->da2_stat_start) * 4) - da1_off;
1037 flag = 1;
1038 }
1039 }
1040
1041 if (da1_sz < 512) {
1042 da1_sz = 512;
1043 } else if ((da1_sz % 512) > 0) {
1044 if (flag == 0) {
1045 m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1;
1046 da1_sz = m_512_sz * 512;
1047 } else {
1048 if (diff < 512)
1049 diff = 1;
1050 else
1051 diff = (diff / 512) * 512;
1052 m_512_sz = (le64_to_cpu(da1->da2_stat_size) / 512) + 1 + diff + 1;
1053 da1_sz = m_512_sz * 512;
1054 }
1055 }
1056
1057 char *da2_stat = calloc(da1_sz, sizeof(char));
1058
1059 err = get_telemetry_data(hdl, nsid, tele_type, da1_sz, (void *)da2_stat, lsp, rae,
1060 da1_off);
1061 if (err) {
1062 printf("get_telemetry_data da2 stats failed, err: %d.\n", err);
1063 return err;
1064 }
1065
1066 print_telemetry_da_stat((void *)(da2_stat + (temp_ofst - da1_off)), tele_type,
1067 le64_to_cpu(da1->da2_stat_size) * 4, 2);
1068 }
1069
1070 /* Print the Data Area 2 Event FIFO's */
1071 for (i = 0; i < 16 ; i++) {
1072 if ((da1->event_fifo_da[i] == 2) && (da1->event_fifos[i].size != 0)) {
1073 diff = 0;
1074 da1_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
1075 m_512_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
1076 da1_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
1077 m_512_off = le64_to_cpu(da1->event_fifos[i].start) * 4;
1078 temp_sz = le64_to_cpu(da1->event_fifos[i].size) * 4;
1079 temp_ofst = le64_to_cpu(da1->event_fifos[i].start) * 4;
1080 flag = 0;
1081
1082 if ((da1_off % 512) > 0) {
1083 m_512_off = ((da1_off / 512));
1084 da1_off = m_512_off * 512;
1085 diff = temp_ofst - da1_off;
1086 flag = 1;
1087 }
1088
1089 if (da1_sz < 512) {
1090 da1_sz = 512;
1091 } else if ((da1_sz % 512) > 0) {
1092 if (flag == 0) {
1093 m_512_sz = (da1_sz / 512) + 1;
1094 da1_sz = m_512_sz * 512;
1095 } else {
1096 if (diff < 512)
1097 diff = 1;
1098 else
1099 diff = (diff / 512) * 512;
1100
1101 m_512_sz = (da1_sz / 512) + 1 + diff + 1;
1102 da1_sz = m_512_sz * 512;
1103 }
1104 }
1105
1106 char *da1_fifo = calloc(da1_sz, sizeof(char));
1107
1108 err = get_telemetry_data(hdl, nsid, tele_type,
1109 le64_to_cpu(da1->event_fifos[i].size) * 4,
1110 (void *)da1_fifo, lsp, rae, da1_off);
1111 if (err) {
1112 printf("get_telemetry_data da2 event fifos failed, err: %d.\n",
1113 err);
1114 return err;
1115 }
1116 print_telemetry_da_fifo((void *)(da1_fifo + (temp_ofst - da1_off)), temp_sz,
1117 tele_type, le64_to_cpu(da1->event_fifo_da[i]), i);
1118 }
1119 }
1120
1121 printf("------------------------------FIFO End---------------------------\n");
1122
1123 switch (data_area) {
1124 case 1:
1125 offset = TELEMETRY_HEADER_SIZE512;
1126 size = le16_to_cpu(logheader->DataArea1LastBlock);
1127 break;
1128 case 2:
1129 offset = TELEMETRY_HEADER_SIZE512 +
1130 (le16_to_cpu(logheader->DataArea1LastBlock) * TELEMETRY_BYTE_PER_BLOCK512);
1131 size = le16_to_cpu(logheader->DataArea2LastBlock) -
1132 le16_to_cpu(logheader->DataArea1LastBlock);
1133 break;
1134 case 3:
1135 offset = TELEMETRY_HEADER_SIZE512 +
1136 (le16_to_cpu(logheader->DataArea2LastBlock) * TELEMETRY_BYTE_PER_BLOCK512);
1137 size = le16_to_cpu(logheader->DataArea3LastBlock) -
1138 le16_to_cpu(logheader->DataArea2LastBlock);
1139 break;
1140 case 4:
1141 offset = TELEMETRY_HEADER_SIZE512 +
1142 (le16_to_cpu(logheader->DataArea3LastBlock) * TELEMETRY_BYTE_PER_BLOCK512);
1143 size = le16_to_cpu(logheader->DataArea4LastBlock) -
1144 le16_to_cpu(logheader->DataArea3LastBlock);
1145 break;
1146 default:
1147 break;
1148 }
1149
1150 if (!size) {
1151 printf("Telemetry %s Area %d is empty.\n", featurename, data_area);
1152 return err;
1153 }
1154
1155 snprintf(dumpname, FILE_NAME_SIZE2048, "Telemetry_%s_Area_%d", featurename, data_area);
1156 err = extract_dump_get_log(hdl, dumpname, filename, sn, size * TELEMETRY_BYTE_PER_BLOCK512,
1157 TELEMETRY_TRANSFER_SIZE1024, nsid, tele_type, 0, offset, rae);
1158
1159 return err;
1160}
1161
1162static int get_telemetry_log_page_data(struct libnvme_transport_handle *hdl,
1163 int tele_type,
1164 int tele_area,
1165 const char *output_file)
1166{
1167 void *telemetry_log;
1168 const size_t bs = 512;
1169 struct nvme_telemetry_log *hdr;
1170 struct libnvme_passthru_cmd cmd;
1171 size_t full_size = 0, offset = bs;
1172 int err, fd;
1173
1174 if ((tele_type == TELEMETRY_TYPE_HOST_0) || (tele_type == TELEMETRY_TYPE_HOST_1))
1175 tele_type = TELEMETRY_TYPE_HOST;
1176
1177 int log_id = (tele_type == TELEMETRY_TYPE_HOST ? NVME_LOG_LID_TELEMETRY_HOST :
1178 NVME_LOG_LID_TELEMETRY_CTRL);
1179
1180 hdr = malloc(bs);
1181 telemetry_log = malloc(bs);
1182 if (!hdr || !telemetry_log) {
1183 fprintf(stderrstderr, "Failed to allocate %zu bytes for log: %s\n",
1184 bs, libnvme_strerror(errno(*__errno_location ())));
1185 err = -ENOMEM12;
1186 goto exit_status;
1187 }
1188 memset(hdr, 0, bs);
1189
1190 fd = nvme_open_rawdata(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666)open((output_file), (01 | 0100 | 01000), 0666);
1191 if (fd < 0) {
1192 fprintf(stderrstderr, "Failed to open output file %s: %s!\n",
1193 output_file, libnvme_strerror(errno(*__errno_location ())));
1194 err = fd;
1195 goto exit_status;
1196 }
1197
1198 nvme_init_get_log(&cmd, NVME_NSID_ALL, log_id, NVME_CSI_NVM, hdr, bs);
1199 cmd.cdw10 |= NVME_FIELD_ENCODE(NVME_LOG_TELEM_HOST_LSP_CREATE,(((__u32)(NVME_LOG_TELEM_HOST_LSP_CREATE) & (NVME_LOG_CDW10_LSP_MASK
)) << (NVME_LOG_CDW10_LSP_SHIFT))
1200 NVME_LOG_CDW10_LSP_SHIFT,(((__u32)(NVME_LOG_TELEM_HOST_LSP_CREATE) & (NVME_LOG_CDW10_LSP_MASK
)) << (NVME_LOG_CDW10_LSP_SHIFT))
1201 NVME_LOG_CDW10_LSP_MASK)(((__u32)(NVME_LOG_TELEM_HOST_LSP_CREATE) & (NVME_LOG_CDW10_LSP_MASK
)) << (NVME_LOG_CDW10_LSP_SHIFT))
;
1202 err = libnvme_get_log(hdl, &cmd, false0, NVME_LOG_PAGE_PDU_SIZE4096);
1203 if (err < 0)
1204 nvme_show_error("Failed to fetch the log from drive.\n")nvme_show_message(1, "Failed to fetch the log from drive.\n");
1205 else if (err > 0) {
1206 nvme_show_status(err);
1207 nvme_show_error("Failed to fetch telemetry-header. Error:%d.\n", err)nvme_show_message(1, "Failed to fetch telemetry-header. Error:%d.\n"
, err)
;
1208 goto close_fd;
1209 }
1210
1211 err = write(fd, (void *)hdr, bs);
1212 if (err != bs) {
1213 nvme_show_error("Failed to write data to file.\n")nvme_show_message(1, "Failed to write data to file.\n");
1214 goto close_fd;
1215 }
1216
1217 switch (tele_area) {
1218 case 1:
1219 full_size = (le16_to_cpu(hdr->dalb1) * bs) + offset;
1220 break;
1221 case 2:
1222 full_size = (le16_to_cpu(hdr->dalb2) * bs) + offset;
1223 break;
1224 case 3:
1225 full_size = (le16_to_cpu(hdr->dalb3) * bs) + offset;
1226 break;
1227 case 4:
1228 full_size = (le32_to_cpu(hdr->dalb4) * bs) + offset;
1229 break;
1230 default:
1231 full_size = offset;
1232 break;
1233 }
1234
1235 while (offset < full_size) {
1236 nvme_init_get_log(&cmd, NVME_NSID_ALL, log_id, NVME_CSI_NVM,
1237 telemetry_log, bs);
1238 nvme_init_get_log_lpo(&cmd, offset);
1239 err = libnvme_get_log(hdl, &cmd, false0, NVME_LOG_PAGE_PDU_SIZE4096);
1240 if (err < 0) {
1241 nvme_show_error("Failed to fetch the log from drive.\n")nvme_show_message(1, "Failed to fetch the log from drive.\n");
1242 break;
1243 } else if (err > 0) {
1244 nvme_show_error("Failed to fetch telemetry-log.\n")nvme_show_message(1, "Failed to fetch telemetry-log.\n");
1245 nvme_show_status(err);
1246 break;
1247 }
1248
1249 err = write(fd, (void *)telemetry_log, bs);
1250 if (err != bs) {
1251 nvme_show_error("Failed to write data to file.\n")nvme_show_message(1, "Failed to write data to file.\n");
1252 break;
1253 }
1254 err = 0;
1255 offset += bs;
1256 }
1257
1258close_fd:
1259 close(fd);
1260exit_status:
1261 free(hdr);
1262 free(telemetry_log);
1263
1264 return err;
1265}
1266
1267static int get_c9_log_page_data(struct libnvme_transport_handle *hdl,
1268 int print_data,
1269 int save_bin,
1270 const char *output_file)
1271{
1272 int ret = 0;
1273 __le64 stat_id_str_table_ofst = 0;
1274 __le64 event_str_table_ofst = 0;
1275 __le64 vu_event_str_table_ofst = 0;
1276 __le64 ascii_table_ofst = 0;
1277
1278 __cleanup_fd__attribute__((cleanup(cleanup_fd))) int fd = STDIN_FILENO0;
1279
1280 header_data = (__u8 *)malloc(sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN432);
1281 if (!header_data) {
1282 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
1283 return -1;
1284 }
1285 memset(header_data, 0, sizeof(__u8) * C9_TELEMETRY_STR_LOG_LEN432);
1286
1287 ret = ocp_get_log_simple(hdl, OCP_LID_TELSLG, C9_TELEMETRY_STR_LOG_LEN432, header_data);
1288
1289 if (!ret) {
1290 log_data = (struct telemetry_str_log_format *)header_data;
1291 if (print_data) {
1292 printf("Statistics Identifier String Table Size = %"PRIu64"l" "u""\n",
1293 le64_to_cpu(log_data->sitsz));
1294 printf("Event String Table Size = %"PRIu64"l" "u""\n",
1295 le64_to_cpu(log_data->estsz));
1296 printf("VU Event String Table Size = %"PRIu64"l" "u""\n",
1297 le64_to_cpu(log_data->vu_eve_st_sz));
1298 printf("ASCII Table Size = %"PRIu64"l" "u""\n", le64_to_cpu(log_data->asctsz));
1299 }
1300
1301 /* Calculating the offset for dynamic fields. */
1302
1303 stat_id_str_table_ofst = log_data->sits * 4;
1304 event_str_table_ofst = log_data->ests * 4;
1305 vu_event_str_table_ofst = log_data->vu_eve_sts * 4;
1306 ascii_table_ofst = log_data->ascts * 4;
1307 total_log_page_sz = C9_TELEMETRY_STR_LOG_LEN432 +
1308 (log_data->sitsz * 4) + (log_data->estsz * 4) +
1309 (log_data->vu_eve_st_sz * 4) + (log_data->asctsz * 4);
1310
1311 if (print_data) {
1312 printf("stat_id_str_table_ofst = %"PRIu64"l" "u""\n",
1313 le64_to_cpu(stat_id_str_table_ofst));
1314 printf("event_str_table_ofst = %"PRIu64"l" "u""\n",
1315 le64_to_cpu(event_str_table_ofst));
1316 printf("vu_event_str_table_ofst = %"PRIu64"l" "u""\n",
1317 le64_to_cpu(vu_event_str_table_ofst));
1318 printf("ascii_table_ofst = %"PRIu64"l" "u""\n", le64_to_cpu(ascii_table_ofst));
1319 printf("total_log_page_sz = %"PRIu64"l" "u""\n", le64_to_cpu(total_log_page_sz));
1320 }
1321
1322 pC9_string_buffer = (__u8 *)malloc(sizeof(__u8) * total_log_page_sz);
1323 if (!pC9_string_buffer) {
1324 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
1325 return -1;
1326 }
1327 memset(pC9_string_buffer, 0, sizeof(__u8) * total_log_page_sz);
1328
1329 ret = ocp_get_log_simple(hdl, OCP_LID_TELSLG, total_log_page_sz, pC9_string_buffer);
1330 } else {
1331 fprintf(stderrstderr, "ERROR : OCP : Unable to read C9 data, ret: %d.\n", ret);
1332 return ret;
1333 }
1334
1335 if (save_bin) {
1336 fd = nvme_open_rawdata(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666)open((output_file), (01 | 0100 | 01000), 0666);
1337 if (fd < 0) {
1338 fprintf(stderrstderr, "Failed to open output file %s: %s!\n", output_file,
1339 libnvme_strerror(errno(*__errno_location ())));
1340 ret = fd;
1341 goto free;
1342 }
1343
1344 ret = write(fd, (void *)pC9_string_buffer, total_log_page_sz);
1345 if (ret != total_log_page_sz)
1346 fprintf(stderrstderr, "Failed to flush all data to file! ret: %d\n", ret);
1347 else
1348 /* all data written, set ret = SUCCESS */
1349 ret = 0;
1350 }
1351
1352free:
1353 free(pC9_string_buffer);
1354 return ret;
1355}
1356
1357int parse_ocp_telemetry_log(struct ocp_telemetry_parse_options *options)
1358{
1359 int status = 0;
1360 long telemetry_buffer_size = 0;
1361 long string_buffer_size = 0;
1362 enum nvme_print_flags fmt;
1363 unsigned char log_id;
1364
1365 if (options->telemetry_log) {
1366 if (strstr((const char *)options->telemetry_log, "bin")) {
1367 /* Read the data from the telemetry binary file */
1368 ptelemetry_buffer =
1369 read_binary_file(NULL((void*)0), (const char *)options->telemetry_log,
1370 &telemetry_buffer_size, 1);
1371 if (ptelemetry_buffer == NULL((void*)0)) {
1372 nvme_show_error("Failed to read telemetry-log.\n")nvme_show_message(1, "Failed to read telemetry-log.\n");
1373 return -1;
1374 }
1375 }
1376 } else {
1377 nvme_show_error("telemetry-log is empty.\n")nvme_show_message(1, "telemetry-log is empty.\n");
1378 return -1;
1379 }
1380
1381 log_id = ptelemetry_buffer[0];
1382 if ((log_id != NVME_LOG_LID_TELEMETRY_HOST) && (log_id != NVME_LOG_LID_TELEMETRY_CTRL)) {
1383 nvme_show_error("Invalid LogPageId [0x%02X]\n", log_id)nvme_show_message(1, "Invalid LogPageId [0x%02X]\n", log_id);
1384 return -1;
1385 }
1386
1387 if (options->string_log) {
1388 /* Read the data from the string binary file */
1389 if (strstr((const char *)options->string_log, "bin")) {
1390 pstring_buffer = read_binary_file(NULL((void*)0), (const char *)options->string_log,
1391 &string_buffer_size, 1);
1392 if (pstring_buffer == NULL((void*)0)) {
1393 nvme_show_error("Failed to read string-log.\n")nvme_show_message(1, "Failed to read string-log.\n");
1394 return -1;
1395 }
1396 }
1397 } else {
1398 nvme_show_error("string-log is empty.\n")nvme_show_message(1, "string-log is empty.\n");
1399 return -1;
1400 }
1401
1402 status = validate_output_format(options->output_format, &fmt);
1403 if (status < 0) {
1404 nvme_show_error("Invalid output format\n")nvme_show_message(1, "Invalid output format\n");
1405 return status;
1406 }
1407
1408 ocp_show_telemetry_log(options, fmt);
1409
1410 return 0;
1411}
1412
1413static int ocp_telemetry_log(int argc, char **argv, struct command *acmd, struct plugin *plugin)
1414{
1415 const char *desc = "Retrieve and parse OCP Telemetry log.";
1416 const char *telemetry_log = "Telemetry log binary;\n 'host.bin' or 'controller.bin'";
1417 const char *string_log = "String log binary; 'C9.bin'";
1418 const char *output_file = "Output file name with path;\n"
1419 "e.g. '-f ./path/name'\n'-f ./path1/path2/';\n"
1420 "If requested path does not exist, the directory will be newly created.";
1421 const char *data_area = "Telemetry Data Area; 1, 2, 3, or 4;\n"
1422 "e.g. '-a 1 for Data Area 1.'\n"
1423 "e.g. '-a 2 for Data Areas 1 and 2.'\n"
1424 "e.g. '-a 3 for Data Areas 1, 2, and 3.'\n"
1425 "e.g. '-a 4 for Data Areas 1, 2, 3, and 4.';\n";
1426
1427 const char *telemetry_type = "Telemetry Type; 'host', 'host0', 'host1' or 'controller'";
1428
1429 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1430 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1431 int err = 0;
1432 __u32 nsid = NVME_NSID_ALL;
1433 char sn[21] = {0,};
1434 struct nvme_id_ctrl ctrl;
1435 bool_Bool is_support_telemetry_controller;
1436 struct ocp_telemetry_parse_options opt = {0};
1437 int tele_type = 0;
1438 int tele_area = 0;
1439 char file_path_telemetry[PATH_MAX4096], file_path_string[PATH_MAX4096];
1440 const char *string_suffix = "string.bin";
1441 const char *tele_log_suffix = "telemetry.bin";
1442 bool_Bool host_behavior_changed = false0;
1443
1444 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1445 OPT_STR("telemetry-log", 'l', &opt.telemetry_log, telemetry_log),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1446 OPT_STR("string-log", 's', &opt.string_log, string_log),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1447 OPT_FILE("output-file", 'f', &opt.output_file, output_file),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1448 OPT_INT("data-area", 'a', &opt.data_area, data_area),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1449 OPT_STR("telemetry-type", 't', &opt.telemetry_type, telemetry_type))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-log", 'l', "STRING", CFG_STRING, &opt.
telemetry_log, 1, telemetry_log, 0, }, {"string-log", 's', "STRING"
, CFG_STRING, &opt.string_log, 1, string_log, 0, }, {"output-file"
, 'f', "FILE", CFG_STRING, &opt.output_file, 1, output_file
, 0, }, {"data-area", 'a', "NUM", CFG_INT, &opt.data_area
, 1, data_area, 0, }, {"telemetry-type", 't', "STRING", CFG_STRING
, &opt.telemetry_type, 1, telemetry_type, 0, }, {"", 0, (
(void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
1450
1451 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
1452 if (err)
1453 return err;
1454
1455 if (opt.telemetry_type == 0)
1456 opt.telemetry_type = "host";
1457
1458 if (libnvme_transport_handle_is_ns(hdl)) {
1459 err = libnvme_get_nsid(hdl, &nsid);
1460 if (err < 0)
1461 return err;
1462 }
1463
1464 err = nvme_identify_ctrl(hdl, &ctrl);
1465 if (err)
1466 return err;
1467
1468 get_serial_number(&ctrl, sn);
1469
1470 is_support_telemetry_controller = ((ctrl.lpa & 0x8) >> 3);
1471
1472 if (opt.output_file == NULL((void*)0))
1473 opt.output_file = DEFAULT_TELEMETRY_LOG"telemetry-log";
1474
1475 if (!opt.data_area) {
1476 nvme_show_result("Missing data-area. Using default data area 1.\n")nvme_show_message(0, "Missing data-area. Using default data area 1.\n"
)
;
1477 opt.data_area = DATA_AREA_1;//Default data area 1
1478 } else if (opt.data_area != 1 && opt.data_area != 2 &&
1479 opt.data_area != 3 && opt.data_area != 4) {
1480 nvme_show_result("Invalid data-area specified. Please specify 1, 2, 3, or 4.\n")nvme_show_message(0, "Invalid data-area specified. Please specify 1, 2, 3, or 4.\n"
)
;
1481 goto out;
1482 }
1483
1484 tele_area = opt.data_area;
1485
1486 if (opt.telemetry_type) {
1487 if (!strcmp(opt.telemetry_type, "host0"))
1488 tele_type = TELEMETRY_TYPE_HOST_0;
1489 else if (!strcmp(opt.telemetry_type, "host1"))
1490 tele_type = TELEMETRY_TYPE_HOST_1;
1491 else if (!strcmp(opt.telemetry_type, "host"))
1492 tele_type = TELEMETRY_TYPE_HOST;
1493 else if (!strcmp(opt.telemetry_type, "controller"))
1494 tele_type = TELEMETRY_TYPE_CONTROLLER;
1495 else {
1496 nvme_show_error(nvme_show_message(1, "telemetry-type should be host, host0, host1 or controller.\n"
)
1497 "telemetry-type should be host, host0, host1 or controller.\n")nvme_show_message(1, "telemetry-type should be host, host0, host1 or controller.\n"
)
;
1498 goto out;
1499 }
1500 } else {
1501 tele_type = TELEMETRY_TYPE_HOST; //Default Type - Host
1502 opt.telemetry_type = "host";
1503 nvme_show_result("Missing telemetry-type. Using default - host.\n")nvme_show_message(0, "Missing telemetry-type. Using default - host.\n"
)
;
1504 }
1505
1506 if (!opt.telemetry_log) {
1507 nvme_show_result("\nMissing telemetry-log. Fetching from drive...\n")nvme_show_message(0, "\nMissing telemetry-log. Fetching from drive...\n"
)
;
1508
1509 if (tele_area == 4) {
1510 if (!(ctrl.lpa & 0x40)) {
1511 nvme_show_error("Telemetry data area 4 not supported by device.\n")nvme_show_message(1, "Telemetry data area 4 not supported by device.\n"
)
;
1512 goto out;
1513 }
1514
1515 err = libnvme_set_etdas(hdl, &host_behavior_changed);
1516 if (err) {
1517 fprintf(stderrstderr, "%s: Failed to set ETDAS bit\n", __func__);
1518 return err;
1519 }
1520 }
1521
1522 /* Pull the Telemetry log */
1523 sprintf(file_path_telemetry, "%s-%s", opt.output_file, tele_log_suffix);
1524 err = get_telemetry_log_page_data(hdl,
1525 tele_type,
1526 tele_area,
1527 (const char *)file_path_telemetry);
1528 if (err) {
1529 nvme_show_error("Failed to fetch telemetry-log from the drive.\n")nvme_show_message(1, "Failed to fetch telemetry-log from the drive.\n"
)
;
1530 goto out;
1531 }
1532 nvme_show_result("telemetry.bin generated. Proceeding with next steps.\n")nvme_show_message(0, "telemetry.bin generated. Proceeding with next steps.\n"
)
;
1533 opt.telemetry_log = file_path_telemetry;
1534
1535 if (host_behavior_changed) {
1536 host_behavior_changed = false0;
1537 err = libnvme_clear_etdas(hdl, &host_behavior_changed);
1538 if (err) {
1539 /* Continue on if this fails, it's not a fatal condition */
1540 nvme_show_error("Failed to clear ETDAS bit.\n")nvme_show_message(1, "Failed to clear ETDAS bit.\n");
1541 }
1542 }
1543 }
1544
1545 if (!opt.string_log) {
1546 nvme_show_result("Missing string-log. Fetching from drive...\n")nvme_show_message(0, "Missing string-log. Fetching from drive...\n"
)
;
1547
1548 /* Pull String log */
1549 sprintf(file_path_string, "%s-%s", opt.output_file, string_suffix);
1550 err = get_c9_log_page_data(hdl, 0, 1, (const char *)file_path_string);
1551 if (err) {
1552 nvme_show_error("Failed to fetch string-log from the drive.\n")nvme_show_message(1, "Failed to fetch string-log from the drive.\n"
)
;
1553 goto out;
1554 }
1555 nvme_show_result("string.bin generated. Proceeding with next steps.\n")nvme_show_message(0, "string.bin generated. Proceeding with next steps.\n"
)
;
1556 opt.string_log = file_path_string;
1557 }
1558
1559 if (argconfig_parse_seen(opts, "output-format"))
1560 opt.output_format = nvme_args.output_format;
1561
1562 if (!opt.output_format) {
1563 nvme_show_result("Missing output format. Using default format - JSON.\n")nvme_show_message(0, "Missing output format. Using default format - JSON.\n"
)
;
1564 opt.output_format = DEFAULT_OUTPUT_FORMAT_JSON"json";
1565 }
1566
1567 switch (tele_type) {
1568 case TELEMETRY_TYPE_HOST:
1569 printf("Extracting Telemetry Host Dump (Data Area %d)...\n", tele_area);
1570
1571 err = parse_ocp_telemetry_log(&opt);
1572 if (err)
1573 nvme_show_result("Status:(%x)\n", err)nvme_show_message(0, "Status:(%x)\n", err);
1574 break;
1575 case TELEMETRY_TYPE_CONTROLLER:
1576 printf("Extracting Telemetry Controller Dump (Data Area %d)...\n", tele_area);
1577 if (is_support_telemetry_controller == true1) {
1578 err = parse_ocp_telemetry_log(&opt);
1579 if (err)
1580 nvme_show_result("Status:(%x)\n", err)nvme_show_message(0, "Status:(%x)\n", err);
1581 }
1582 break;
1583 case TELEMETRY_TYPE_HOST_0:
1584 case TELEMETRY_TYPE_HOST_1:
1585 default:
1586 printf("Extracting Telemetry Host(%d) Dump (Data Area %d)...\n",
1587 (tele_type == TELEMETRY_TYPE_HOST_0) ? 0 : 1, tele_area);
1588
1589 err = get_telemetry_dump(hdl, opt.output_file, sn, tele_type, tele_area, true1);
1590 if (err)
1591 fprintf(stderrstderr, "NVMe Status: %s(%x)\n", libnvme_status_to_string(err, false0),
1592 err);
1593 break;
1594 }
1595
1596 printf("ocp internal-log command completed.\n");
1597out:
1598 return err;
1599}
1600
1601///////////////////////////////////////////////////////////////////////////////
1602///////////////////////////////////////////////////////////////////////////////
1603///////////////////////////////////////////////////////////////////////////////
1604///////////////////////////////////////////////////////////////////////////////
1605/// Unsupported Requirement Log Page (LID : C5h)
1606
1607/* C5 Unsupported Requirement Log Page */
1608#define C5_UNSUPPORTED_REQS_LEN4096 4096
1609
1610static __u8 unsupported_req_guid[GUID_LEN16] = {
1611 0x2F, 0x72, 0x9C, 0x0E,
1612 0x99, 0x23, 0x2C, 0xBB,
1613 0x63, 0x48, 0x32, 0xD0,
1614 0xB7, 0x98, 0xBB, 0xC7
1615};
1616
1617/* Function declaration for unsupported requirement log page (LID:C5h) */
1618static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *acmd,
1619 struct plugin *plugin);
1620
1621static int get_c5_log_page(struct libnvme_transport_handle *hdl, char *format)
1622{
1623 nvme_print_flags_t fmt;
1624 int ret;
1625 __u8 *data;
1626 int i;
1627 struct unsupported_requirement_log *log_data;
1628 int j;
1629
1630 ret = validate_output_format(format, &fmt);
1631 if (ret < 0) {
1632 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
1633 return ret;
1634 }
1635
1636 data = (__u8 *)malloc(sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN4096);
1637 if (!data) {
1638 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
1639 return -1;
1640 }
1641 memset(data, 0, sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN4096);
1642
1643 ret = ocp_get_log_simple(hdl, OCP_LID_URLP, C5_UNSUPPORTED_REQS_LEN4096, data);
1644 if (!ret) {
1645 log_data = (struct unsupported_requirement_log *)data;
1646
1647 /*
1648 * check log page guid
1649 * Verify GUID matches
1650 */
1651 for (i = 0; i < 16; i++) {
1652 if (unsupported_req_guid[i] != log_data->log_page_guid[i]) {
1653 fprintf(stderrstderr, "ERROR : OCP : Unknown GUID in C5 Log Page data\n");
1654 fprintf(stderrstderr, "ERROR : OCP : Expected GUID: 0x");
1655 for (j = 0; j < 16; j++)
1656 fprintf(stderrstderr, "%02x", unsupported_req_guid[j]);
1657 fprintf(stderrstderr, "\nERROR : OCP : Actual GUID: 0x");
1658 for (j = 0; j < 16; j++)
1659 fprintf(stderrstderr, "%02x", log_data->log_page_guid[j]);
1660 fprintf(stderrstderr, "\n");
1661
1662 ret = -1;
1663 goto out;
1664 }
1665 }
1666 ocp_c5_log(hdl, log_data, fmt);
1667 } else {
1668 fprintf(stderrstderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
1669 }
1670
1671out:
1672 free(data);
1673 return ret;
1674}
1675
1676static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *acmd,
1677 struct plugin *plugin)
1678{
1679 const char *desc = "Retrieve unsupported requirements log data.";
1680 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1681 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1682 int ret = 0;
1683
1684 struct config {
1685 char *output_format;
1686 };
1687
1688 struct config cfg = {
1689 .output_format = "normal",
1690 };
1691
1692 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
1693
1694 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
1695 if (ret)
1696 return ret;
1697
1698 ret = get_c5_log_page(hdl, cfg.output_format);
1699 if (ret)
1700 fprintf(stderrstderr, "ERROR : OCP : Failure reading the C5 Log Page, ret = %d\n", ret);
1701
1702 return ret;
1703}
1704
1705///////////////////////////////////////////////////////////////////////////////
1706///////////////////////////////////////////////////////////////////////////////
1707///////////////////////////////////////////////////////////////////////////////
1708///////////////////////////////////////////////////////////////////////////////
1709/// Error Recovery Log Page(0xC1)
1710
1711#define C1_ERROR_RECOVERY_LOG_BUF_LEN0x200 0x200
1712
1713static __u8 error_recovery_guid[GUID_LEN16] = {
1714 0x44, 0xd9, 0x31, 0x21,
1715 0xfe, 0x30, 0x34, 0xae,
1716 0xab, 0x4d, 0xfd, 0x3d,
1717 0xba, 0x83, 0x19, 0x5a
1718};
1719
1720static int get_c1_log_page(struct libnvme_transport_handle *hdl, char *format);
1721static int ocp_error_recovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin);
1722
1723static int get_c1_log_page(struct libnvme_transport_handle *hdl, char *format)
1724{
1725 struct ocp_error_recovery_log_page *log_data;
1726 nvme_print_flags_t fmt;
1727 int ret;
1728 __u8 *data;
1729 int i, j;
1730
1731 ret = validate_output_format(format, &fmt);
1732 if (ret < 0) {
1733 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
1734 return ret;
1735 }
1736
1737 data = (__u8 *)malloc(sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN0x200);
1738 if (!data) {
1739 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
1740 return -1;
1741 }
1742 memset(data, 0, sizeof(__u8) * C1_ERROR_RECOVERY_LOG_BUF_LEN0x200);
1743
1744 ret = ocp_get_log_simple(hdl, OCP_LID_EREC, C1_ERROR_RECOVERY_LOG_BUF_LEN0x200, data);
1745
1746 if (!ret) {
1747 log_data = (struct ocp_error_recovery_log_page *)data;
1748
1749 /*
1750 * check log page guid
1751 * Verify GUID matches
1752 */
1753 for (i = 0; i < 16; i++) {
1754 if (error_recovery_guid[i] != log_data->log_page_guid[i]) {
1755 fprintf(stderrstderr, "ERROR : OCP : Unknown GUID in C1 Log Page data\n");
1756 fprintf(stderrstderr, "ERROR : OCP : Expected GUID: 0x");
1757 for (j = 0; j < 16; j++)
1758 fprintf(stderrstderr, "%02x", error_recovery_guid[j]);
1759 fprintf(stderrstderr, "\nERROR : OCP : Actual GUID: 0x");
1760 for (j = 0; j < 16; j++)
1761 fprintf(stderrstderr, "%02x", log_data->log_page_guid[j]);
1762 fprintf(stderrstderr, "\n");
1763
1764 ret = -1;
1765 goto out;
1766 }
1767 }
1768 ocp_c1_log(log_data, fmt);
1769 } else {
1770 fprintf(stderrstderr, "ERROR : OCP : Unable to read C1 data from buffer\n");
1771 }
1772
1773out:
1774 free(data);
1775 return ret;
1776}
1777
1778static int ocp_error_recovery_log(int argc, char **argv, struct command *acmd, struct plugin *plugin)
1779{
1780 const char *desc = "Retrieve C1h Error Recovery Log data.";
1781 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1782 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1783 int ret = 0;
1784
1785 struct config {
1786 char *output_format;
1787 };
1788
1789 struct config cfg = {
1790 .output_format = "normal",
1791 };
1792
1793 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
1794
1795 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
1796 if (ret)
1797 return ret;
1798
1799 ret = get_c1_log_page(hdl, cfg.output_format);
1800 if (ret)
1801 fprintf(stderrstderr, "ERROR : OCP : Failure reading the C1h Log Page, ret = %d\n", ret);
1802
1803 return ret;
1804}
1805
1806///////////////////////////////////////////////////////////////////////////////
1807///////////////////////////////////////////////////////////////////////////////
1808///////////////////////////////////////////////////////////////////////////////
1809///////////////////////////////////////////////////////////////////////////////
1810/// Device Capabilities (Log Identifier C4h) Requirements
1811
1812#define C4_DEV_CAP_REQ_LEN0x1000 0x1000
1813static __u8 dev_cap_req_guid[GUID_LEN16] = {
1814 0x97, 0x42, 0x05, 0x0d,
1815 0xd1, 0xe1, 0xc9, 0x98,
1816 0x5d, 0x49, 0x58, 0x4b,
1817 0x91, 0x3c, 0x05, 0xb7
1818};
1819
1820static int get_c4_log_page(struct libnvme_transport_handle *hdl, char *format);
1821static int ocp_device_capabilities_log(int argc, char **argv, struct command *acmd, struct plugin *plugin);
1822
1823static int get_c4_log_page(struct libnvme_transport_handle *hdl, char *format)
1824{
1825 struct ocp_device_capabilities_log_page *log_data;
1826 nvme_print_flags_t fmt;
1827 int ret;
1828 __u8 *data;
1829 int i, j;
1830
1831 ret = validate_output_format(format, &fmt);
1832 if (ret < 0) {
1833 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
1834 return ret;
1835 }
1836
1837 data = (__u8 *)malloc(sizeof(__u8) * C4_DEV_CAP_REQ_LEN0x1000);
1838 if (!data) {
1839 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
1840 return -1;
1841 }
1842 memset(data, 0, sizeof(__u8) * C4_DEV_CAP_REQ_LEN0x1000);
1843
1844 ret = ocp_get_log_simple(hdl, OCP_LID_DCLP, C4_DEV_CAP_REQ_LEN0x1000, data);
1845
1846 if (!ret) {
1847 log_data = (struct ocp_device_capabilities_log_page *)data;
1848
1849 /*
1850 * check log page guid
1851 * Verify GUID matches
1852 */
1853 for (i = 0; i < 16; i++) {
1854 if (dev_cap_req_guid[i] != log_data->log_page_guid[i]) {
1855 fprintf(stderrstderr, "ERROR : OCP : Unknown GUID in C4 Log Page data\n");
1856 fprintf(stderrstderr, "ERROR : OCP : Expected GUID: 0x");
1857 for (j = 0; j < 16; j++)
1858 fprintf(stderrstderr, "%02x", dev_cap_req_guid[j]);
1859 fprintf(stderrstderr, "\nERROR : OCP : Actual GUID: 0x");
1860 for (j = 0; j < 16; j++)
1861 fprintf(stderrstderr, "%02x", log_data->log_page_guid[j]);
1862 fprintf(stderrstderr, "\n");
1863
1864 ret = -1;
1865 goto out;
1866 }
1867 }
1868 ocp_c4_log(log_data, fmt);
1869 } else {
1870 fprintf(stderrstderr, "ERROR : OCP : Unable to read C4 data from buffer\n");
1871 }
1872
1873out:
1874 free(data);
1875 return ret;
1876}
1877
1878static int ocp_device_capabilities_log(int argc, char **argv, struct command *acmd, struct plugin *plugin)
1879{
1880 const char *desc = "Retrieve C4h Device Capabilities Log data.";
1881 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1882 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1883 int ret = 0;
1884
1885 struct config {
1886 char *output_format;
1887 };
1888
1889 struct config cfg = {
1890 .output_format = "normal",
1891 };
1892
1893 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
1894
1895 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
1896 if (ret)
1897 return ret;
1898
1899 ret = get_c4_log_page(hdl, cfg.output_format);
1900 if (ret)
1901 fprintf(stderrstderr, "ERROR : OCP : Failure reading the C4h Log Page, ret = %d\n", ret);
1902
1903 return ret;
1904}
1905
1906///////////////////////////////////////////////////////////////////////////////
1907///////////////////////////////////////////////////////////////////////////////
1908///////////////////////////////////////////////////////////////////////////////
1909///////////////////////////////////////////////////////////////////////////////
1910/// Set Telemetry Profile (Feature Identifier C8h) Set Feature
1911
1912static int ocp_set_telemetry_profile(struct libnvme_transport_handle *hdl, __u8 tps)
1913{
1914 __u64 result;
1915 int err;
1916 __u8 uidx = 0;
1917
1918 /* OCP 2.0 requires UUID index support */
1919 err = ocp_get_uuid_index(hdl, &uidx);
1920 if (err || !uidx) {
1921 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
1922 return err;
1923 }
1924
1925 err = nvme_set_features(hdl, 0xFFFFFFFF, OCP_FID_TEL_CFG, true1, tps, 0, 0,
1926 uidx, 0, NULL((void*)0), 0, &result);
1927 if (err > 0) {
1928 nvme_show_status(err);
1929 } else if (err < 0) {
1930 nvme_show_perror("Set Telemetry Profile");
1931 fprintf(stderrstderr, "Command failed while parsing.\n");
1932 } else {
1933 printf("Successfully Set Telemetry Profile (feature: 0xC8) to below values\n");
1934 printf("Telemetry Profile Select: 0x%x\n", tps);
1935 }
1936
1937 return err;
1938}
1939
1940static int ocp_set_telemetry_profile_feature(int argc, char **argv, struct command *acmd,
1941 struct plugin *plugin)
1942{
1943 const char *desc = "Set Telemetry Profile (Feature Identifier C8h) Set Feature.";
1944 const char *tps = "Telemetry Profile Select for device debug data collection";
1945 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1946 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1947 int err;
1948
1949 struct config {
1950 __u8 tps;
1951 };
1952
1953 struct config cfg = {
1954 .tps = 0,
1955 };
1956
1957 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-profile-select", 't', "NUM", CFG_BYTE, &
cfg.tps, 1, tps, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
1958 OPT_BYTE("telemetry-profile-select", 't', &cfg.tps, tps))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"telemetry-profile-select", 't', "NUM", CFG_BYTE, &
cfg.tps, 1, tps, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
1959
1960 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
1961 if (err)
1962 return err;
1963
1964 if (argconfig_parse_seen(opts, "telemetry-profile-select"))
1965 err = ocp_set_telemetry_profile(hdl, cfg.tps);
1966 else
1967 nvme_show_error("Telemetry Profile Select is a required argument")nvme_show_message(1, "Telemetry Profile Select is a required argument"
)
;
1968
1969 return err;
1970}
1971
1972///////////////////////////////////////////////////////////////////////////////
1973///////////////////////////////////////////////////////////////////////////////
1974///////////////////////////////////////////////////////////////////////////////
1975///////////////////////////////////////////////////////////////////////////////
1976/// Telemetry Profile (Feature Identifier C8h) Get Feature
1977static int ocp_get_telemetry_profile_feature(int argc, char **argv, struct command *acmd,
1978 struct plugin *plugin)
1979{
1980 const char *desc = "Issue Get Feature command (FID: 0xC8) Telemetry Profile";
1981 const char *sel = "[0-3]: current/default/saved/supported/";
1982 const char *nsid = "Byte[04-07]: Namespace Identifier Valid/Invalid/Inactive";
1983
1984 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1985 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
1986
1987 __u64 result;
1988 int err;
1989 bool_Bool uuid;
1990 __u8 uuid_index = 0;
1991
1992 struct config {
1993 __u8 sel;
1994 __u32 nsid;
1995 };
1996
1997 struct config cfg = {
1998 .sel = 0,
1999 .nsid = 0,
2000 };
2001
2002 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2003 OPT_BYTE("sel", 's', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2004 OPT_UINT("namespace-id", 'n', &cfg.nsid, nsid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2005 OPT_FLAG("no-uuid", 'u', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2006
2007 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2008 if (err)
2009 return err;
2010
2011 uuid = !argconfig_parse_seen(opts, "no-uuid");
2012
2013 if (uuid) {
2014 /* OCP 2.0 requires UUID index support */
2015 err = ocp_get_uuid_index(hdl, &uuid_index);
2016 if (err || !uuid_index) {
2017 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2018 return err;
2019 }
2020 }
2021
2022 err = nvme_get_features(hdl, cfg.nsid, OCP_FID_TEL_CFG, cfg.sel, 0,
2023 uuid_index, NULL((void*)0), 0, &result);
2024 if (!err) {
2025 printf("get-feature:0xC8 %s value: %#016"PRIx64"l" "x""\n",
2026 nvme_select_to_string(cfg.sel), (uint64_t)result);
2027
2028 if (cfg.sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2029 nvme_show_select_result(0xC8, result);
2030 } else {
2031 nvme_show_error("Could not get feature: 0xC8")nvme_show_message(1, "Could not get feature: 0xC8");
2032 }
2033
2034 return err;
2035}
2036
2037///////////////////////////////////////////////////////////////////////////////
2038///////////////////////////////////////////////////////////////////////////////
2039///////////////////////////////////////////////////////////////////////////////
2040///////////////////////////////////////////////////////////////////////////////
2041/// DSSD Power State (Feature Identifier C7h) Set Feature
2042
2043static int
2044set_dssd_power_state(struct libnvme_transport_handle *hdl,
2045 const __u32 nsid,
2046 const __u8 fid, __u8 power_state, bool_Bool sv,
2047 bool_Bool uuid)
2048{
2049 __u64 result;
2050 int err;
2051 __u8 uidx = 0;
2052
2053 if (uuid) {
2054 /* OCP 2.0 requires UUID index support */
2055 err = ocp_get_uuid_index(hdl, &uidx);
2056 if (err || !uidx) {
2057 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2058 return err;
2059 }
2060 }
2061
2062 err = nvme_set_features(hdl, nsid, fid, sv, power_state, 0, 0,
2063 uidx, 0, NULL((void*)0), 0, &result);
2064 if (err > 0) {
2065 nvme_show_status(err);
2066 } else if (err < 0) {
2067 nvme_show_perror("Define DSSD Power State");
2068 fprintf(stderrstderr, "Command failed while parsing.\n");
2069 } else {
2070 printf("Successfully set DSSD Power State (feature: 0xC7) to below values\n");
2071 printf("DSSD Power State: 0x%x\n", power_state);
2072 printf("Save bit Value: 0x%x\n", sv);
2073 }
2074
2075 return err;
2076}
2077
2078static int set_dssd_power_state_feature(int argc, char **argv, struct command *acmd,
2079 struct plugin *plugin)
2080{
2081 const char *desc = "Define DSSD Power State (Feature Identifier C7h) Set Feature.";
2082 const char *power_state = "DSSD Power State to set in watts";
2083 const char *save = "Specifies that the controller shall save the attribute";
2084 const __u32 nsid = 0;
2085 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2086 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2087 int err;
2088
2089 struct config {
2090 __u8 power_state;
2091 bool_Bool save;
2092 };
2093
2094 struct config cfg = {
2095 .power_state = 0,
2096 .save = false0,
2097 };
2098
2099 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"power-state", 'p', "NUM", CFG_BYTE, &cfg.power_state
, 1, power_state, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.save, 0, save, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG
, ((void*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2100 OPT_BYTE("power-state", 'p', &cfg.power_state, power_state),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"power-state", 'p', "NUM", CFG_BYTE, &cfg.power_state
, 1, power_state, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.save, 0, save, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG
, ((void*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2101 OPT_FLAG("save", 's', &cfg.save, save),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"power-state", 'p', "NUM", CFG_BYTE, &cfg.power_state
, 1, power_state, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.save, 0, save, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG
, ((void*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2102 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"power-state", 'p', "NUM", CFG_BYTE, &cfg.power_state
, 1, power_state, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.save, 0, save, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG
, ((void*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2103
2104 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2105 if (err)
2106 return err;
2107
2108 if (argconfig_parse_seen(opts, "power-state"))
2109 err = set_dssd_power_state(hdl, nsid, OCP_FID_DSSDPS, cfg.power_state, cfg.save,
2110 !argconfig_parse_seen(opts, "no-uuid"));
2111
2112 return err;
2113}
2114
2115///////////////////////////////////////////////////////////////////////////////
2116///////////////////////////////////////////////////////////////////////////////
2117///////////////////////////////////////////////////////////////////////////////
2118///////////////////////////////////////////////////////////////////////////////
2119/// DSSD Power State (Feature Identifier C7h) Get Feature
2120
2121static int get_dssd_power_state(struct libnvme_transport_handle *hdl, const __u32 nsid,
2122 const __u8 fid, __u8 sel, bool_Bool uuid)
2123{
2124 __u64 result;
2125 int err;
2126 __u8 uuid_index = 0;
2127
2128 if (uuid) {
2129 /* OCP 2.0 requires UUID index support */
2130 err = ocp_get_uuid_index(hdl, &uuid_index);
2131 if (err || !uuid_index) {
2132 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2133 return err;
2134 }
2135 }
2136
2137 err = nvme_get_features(hdl, nsid, fid, sel, 0, uuid_index, NULL((void*)0), 0, &result);
2138 if (!err) {
2139 printf("get-feature:0xC7 %s value: %#016"PRIx64"l" "x""\n",
2140 nvme_select_to_string(sel), (uint64_t)result);
2141
2142 if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2143 nvme_show_select_result(fid, result);
2144 } else {
2145 nvme_show_error("Could not get feature: 0xC7 with sel: %d\n", sel)nvme_show_message(1, "Could not get feature: 0xC7 with sel: %d\n"
, sel)
;
2146 }
2147
2148 return err;
2149}
2150
2151static int get_dssd_power_state_feature(int argc, char **argv, struct command *acmd,
2152 struct plugin *plugin)
2153{
2154 const char *desc = "Define DSSD Power State (Feature Identifier C7h) Get Feature.";
2155 const char *all = "Print out all 3 values at once - Current, Default, and Saved";
2156 const char *sel = "[0-3]: current/default/saved/supported/";
2157 const __u32 nsid = 0;
2158 const __u8 fid = OCP_FID_DSSDPS;
2159 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2160 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2161 int i, err;
2162
2163 struct config {
2164 __u8 sel;
2165 bool_Bool all;
2166 };
2167
2168 struct config cfg = {
2169 .sel = 0,
2170 .all = false0,
2171 };
2172
2173 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"all", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2174 OPT_BYTE("sel", 'S', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"all", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2175 OPT_FLAG("all", 'a', NULL, all),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"all", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2176 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"all", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
2177
2178 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2179 if (err)
2180 return err;
2181
2182 if (argconfig_parse_seen(opts, "all")) {
2183 for (i = 0; i < 3; i++) {
2184 err = get_dssd_power_state(hdl, nsid, fid, i,
2185 !argconfig_parse_seen(opts, "no-uuid"));
2186 if (err)
2187 break;
2188 }
2189 } else if (argconfig_parse_seen(opts, "sel"))
2190 err = get_dssd_power_state(hdl, nsid, fid, cfg.sel,
2191 !argconfig_parse_seen(opts, "no-uuid"));
2192 else
2193 nvme_show_error("Required to have --sel as an argument, or pass the --all flag.")nvme_show_message(1, "Required to have --sel as an argument, or pass the --all flag."
)
;
2194
2195 return err;
2196}
2197
2198///////////////////////////////////////////////////////////////////////////////
2199///////////////////////////////////////////////////////////////////////////////
2200///////////////////////////////////////////////////////////////////////////////
2201///////////////////////////////////////////////////////////////////////////////
2202/// plp_health_check_interval
2203
2204static int set_plp_health_check_interval(int argc, char **argv, struct command *acmd,
2205 struct plugin *plugin)
2206{
2207
2208 const char *desc = "Issue Set Feature command (FID: 0xC6) PLP Health Check Interval";
2209 const char *plp_health_interval = "[31:16]:PLP Health Check Interval";
2210 const char *sv = "Specifies that the controller shall save the attribute";
2211 const __u32 nsid = 0;
2212 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2213 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2214 int err;
2215 __u64 result;
2216 __u8 uidx = 0;
2217
2218 struct config {
2219 __le16 plp_health_interval;
2220 bool_Bool sv;
2221 };
2222
2223 struct config cfg = {
2224 .plp_health_interval = 0,
2225 .sv = false0,
2226 };
2227
2228 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"plp_health_interval", 'p', "NUM", CFG_BYTE, &cfg
.plp_health_interval, 1, plp_health_interval, 0, }, {"save", 's'
, ((void*)0), CFG_FLAG, &cfg.sv, 0, sv, 0, }, {"no-uuid",
'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid, 0, }, {""
, 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2229 OPT_BYTE("plp_health_interval", 'p', &cfg.plp_health_interval, plp_health_interval),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"plp_health_interval", 'p', "NUM", CFG_BYTE, &cfg
.plp_health_interval, 1, plp_health_interval, 0, }, {"save", 's'
, ((void*)0), CFG_FLAG, &cfg.sv, 0, sv, 0, }, {"no-uuid",
'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid, 0, }, {""
, 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2230 OPT_FLAG("save", 's', &cfg.sv, sv),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"plp_health_interval", 'p', "NUM", CFG_BYTE, &cfg
.plp_health_interval, 1, plp_health_interval, 0, }, {"save", 's'
, ((void*)0), CFG_FLAG, &cfg.sv, 0, sv, 0, }, {"no-uuid",
'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid, 0, }, {""
, 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2231 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"plp_health_interval", 'p', "NUM", CFG_BYTE, &cfg
.plp_health_interval, 1, plp_health_interval, 0, }, {"save", 's'
, ((void*)0), CFG_FLAG, &cfg.sv, 0, sv, 0, }, {"no-uuid",
'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid, 0, }, {""
, 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2232
2233 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2234 if (err)
2235 return err;
2236
2237
2238 if (!argconfig_parse_seen(opts, "no-uuid")) {
2239 /* OCP 2.0 requires UUID index support */
2240 err = ocp_get_uuid_index(hdl, &uidx);
2241 if (err || !uidx) {
2242 printf("ERROR: No OCP UUID index found");
2243 return err;
2244 }
2245 }
2246
2247 err = nvme_set_features(hdl, nsid, OCP_FID_PLPI, cfg.sv,
2248 cfg.plp_health_interval << 16, 0, 0, uidx, 0, NULL((void*)0), 0,
2249 &result);
2250 if (err > 0) {
2251 nvme_show_status(err);
2252 } else if (err < 0) {
2253 nvme_show_perror("Define PLP Health Check Interval");
2254 fprintf(stderrstderr, "Command failed while parsing.\n");
2255 } else {
2256 printf("Successfully set the PLP Health Check Interval");
2257 printf("PLP Health Check Interval: 0x%x\n", cfg.plp_health_interval);
2258 printf("Save bit Value: 0x%x\n", cfg.sv);
2259 }
2260 return err;
2261}
2262
2263static int get_plp_health_check_interval(int argc, char **argv, struct command *acmd,
2264 struct plugin *plugin)
2265{
2266
2267 const char *desc = "Issue Get Feature command (FID: 0xC6) PLP Health Check Interval";
2268 const __u32 nsid = 0;
2269 const __u8 fid = 0xc6;
2270 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2271 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2272 __u64 result;
2273 int err;
2274
2275 struct config {
2276 __u8 sel;
2277 };
2278
2279 struct config cfg = {
2280 .sel = 0,
2281 };
2282
2283 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2284 OPT_BYTE("sel", 'S', &cfg.sel, sel))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2285
2286 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2287 if (err)
2288 return err;
2289
2290 err = nvme_get_features(hdl, nsid, OCP_FID_PLPI, cfg.sel, 0, 0,
2291 NULL((void*)0), 0, &result);
2292 if (!err) {
2293 printf("get-feature:0xC6 %s value: %#016"PRIx64"l" "x""\n",
2294 nvme_select_to_string(cfg.sel), (uint64_t)result);
2295
2296 if (cfg.sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2297 nvme_show_select_result(fid, result);
2298 } else {
2299 nvme_show_error("Could not get feature: 0xC6")nvme_show_message(1, "Could not get feature: 0xC6");
2300 }
2301
2302 return err;
2303}
2304
2305///////////////////////////////////////////////////////////////////////////////
2306///////////////////////////////////////////////////////////////////////////////
2307///////////////////////////////////////////////////////////////////////////////
2308///////////////////////////////////////////////////////////////////////////////
2309/// dssd_async_event_config
2310
2311static int set_dssd_async_event_config(int argc, char **argv, struct command *acmd,
2312 struct plugin *plugin)
2313{
2314
2315 const char *desc = "Issue Set Feature command (FID: 0xC9) DSSD Async Event Config";
2316 const char *epn = "[0]:Enable Panic Notices";
2317 const char *sv = "Specifies that the controller shall save the attribute";
2318 const __u32 nsid = 0;
2319 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2320 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2321 int err;
2322 __u64 result;
2323 __u8 uidx = 0;
2324
2325 struct config {
2326 bool_Bool epn;
2327 bool_Bool sv;
2328 };
2329
2330 struct config cfg = {
2331 .epn = false0,
2332 .sv = false0,
2333 };
2334
2335 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable-panic-notices", 'e', ((void*)0), CFG_FLAG, &
cfg.epn, 0, epn, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.sv, 0, sv, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR,
((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose",
'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2336 OPT_FLAG("enable-panic-notices", 'e', &cfg.epn, epn),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable-panic-notices", 'e', ((void*)0), CFG_FLAG, &
cfg.epn, 0, epn, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.sv, 0, sv, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR,
((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose",
'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2337 OPT_FLAG("save", 's', &cfg.sv, sv))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable-panic-notices", 'e', ((void*)0), CFG_FLAG, &
cfg.epn, 0, epn, 0, }, {"save", 's', ((void*)0), CFG_FLAG, &
cfg.sv, 0, sv, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR,
((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose",
'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2338
2339 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2340 if (err)
2341 return err;
2342
2343 /* OCP 2.0 requires UUID index support */
2344 err = ocp_get_uuid_index(hdl, &uidx);
2345 if (err || !uidx) {
2346 printf("ERROR: No OCP UUID index found\n");
2347 return err;
2348 }
2349
2350 err = nvme_set_features(hdl, nsid, OCP_FID_DAEC, cfg.sv, cfg.epn ? 1 : 0,
2351 0, 0, uidx, 0, NULL((void*)0), 0, &result);
2352 if (err > 0) {
2353 nvme_show_status(err);
2354 } else if (err < 0) {
2355 nvme_show_perror("Set DSSD Asynchronous Event Configuration\n");
2356 fprintf(stderrstderr, "Command failed while parsing.\n");
2357 } else {
2358 printf("Successfully set the DSSD Asynchronous Event Configuration\n");
2359 printf("Enable Panic Notices bit Value: 0x%x\n", cfg.epn);
2360 printf("Save bit Value: 0x%x\n", cfg.sv);
2361 }
2362 return err;
2363}
2364
2365static int get_dssd_async_event_config(int argc, char **argv, struct command *acmd,
2366 struct plugin *plugin)
2367{
2368
2369 const char *desc = "Issue Get Feature command (FID: 0xC9) DSSD Async Event Config";
2370 const char *sel = "[0-3]: current/default/saved/supported";
2371 const __u32 nsid = 0;
2372 const __u8 fid = OCP_FID_DAEC;
2373 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2374 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2375 __u64 result;
2376 int err;
2377
2378 struct config {
2379 __u8 sel;
2380 };
2381
2382 struct config cfg = {
2383 .sel = 0,
2384 };
2385
2386 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2387 OPT_BYTE("sel", 'S', &cfg.sel, sel))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 'S', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Global options"
, 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT, &
nvme_args.verbose, 0, "Increase output verbosity", 0, }, {"output-format"
, 'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2388
2389 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2390 if (err)
2391 return err;
2392
2393 err = nvme_get_features(hdl, nsid, fid, cfg.sel, 0, 0, NULL((void*)0), 0, &result);
2394 if (!err) {
2395 printf("get-feature:0xC9 %s value: %#016"PRIx64"l" "x""\n",
2396 nvme_select_to_string(cfg.sel), (uint64_t)result);
2397
2398 if (cfg.sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2399 nvme_show_select_result(fid, result);
2400 } else {
2401 nvme_show_error("Could not get feature: 0xC9\n")nvme_show_message(1, "Could not get feature: 0xC9\n");
2402 }
2403
2404 return err;
2405}
2406
2407///////////////////////////////////////////////////////////////////////////////
2408///////////////////////////////////////////////////////////////////////////////
2409///////////////////////////////////////////////////////////////////////////////
2410///////////////////////////////////////////////////////////////////////////////
2411/// Telemetry String Log Format Log Page (LID : C9h)
2412
2413/* Function declaration for Telemetry String Log Format (LID:C9h) */
2414static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *acmd,
2415 struct plugin *plugin);
2416
2417static int get_c9_log_page(struct libnvme_transport_handle *hdl,
2418 char *format,
2419 const char *output_file)
2420{
2421 int ret = 0;
2422 nvme_print_flags_t fmt;
2423
2424 ret = validate_output_format(format, &fmt);
2425 if (ret < 0) {
2426 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
2427 return ret;
2428 }
2429
2430 ret = get_c9_log_page_data(hdl, 0, 1, output_file);
2431
2432 if ((!ret) && (fmt != BINARY))
2433 ocp_c9_log(log_data, pC9_string_buffer, total_log_page_sz, fmt);
2434 else if (ret)
2435 fprintf(stderrstderr, "ERROR : OCP : Unable to read C9 data from buffer\n");
2436
2437 free(header_data);
2438 return ret;
2439}
2440
2441static int ocp_telemetry_str_log_format(int argc, char **argv, struct command *acmd,
2442 struct plugin *plugin)
2443{
2444 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2445 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2446 int ret = 0;
2447 char file_path[PATH_MAX4096];
2448 const char *string_suffix = ".bin";
2449 const char *desc = "Retrieve telemetry string log format";
2450 const char *output_file = "Output file name with path;\n"
2451 "e.g. '-f ./path/name'\n'-f ./path1/path2/';\n"
2452 "If requested path does not exist, the directory will be newly created.";
2453
2454 struct config {
2455 char *output_format;
2456 char *output_file;
2457 };
2458
2459 struct config cfg = {
2460 .output_format = "normal",
2461 .output_file = NULL((void*)0),
2462 };
2463
2464 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"output-file", 'f', "FILE", CFG_STRING, &cfg.output_file
, 1, output_file, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2465 OPT_FILE("output-file", 'f', &cfg.output_file, output_file))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"output-file", 'f', "FILE", CFG_STRING, &cfg.output_file
, 1, output_file, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2466
2467 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2468 if (ret)
2469 return ret;
2470
2471 if (cfg.output_file != NULL((void*)0))
2472 sprintf(file_path, "%s-%s", cfg.output_file, string_suffix);
2473 else
2474 sprintf(file_path, "%s", DEFAULT_STRING_BIN"string.bin");
2475
2476 ret = get_c9_log_page(hdl, cfg.output_format, file_path);
2477 if (ret)
2478 fprintf(stderrstderr, "ERROR : OCP : Failure reading the C9 Log Page, ret = %d\n", ret);
2479
2480 return ret;
2481}
2482
2483///////////////////////////////////////////////////////////////////////////////
2484///////////////////////////////////////////////////////////////////////////////
2485///////////////////////////////////////////////////////////////////////////////
2486///////////////////////////////////////////////////////////////////////////////
2487/// TCG Configuration Log Page (LID : C7h)
2488
2489/* C7 TCG Configuration Log Page */
2490#define C7_TCG_CONFIGURATION_LEN512 512
2491
2492static __u8 tcg_configuration_guid[GUID_LEN16] = {
2493 0x06, 0x40, 0x24, 0xBD,
2494 0x7E, 0xE0, 0xE6, 0x83,
2495 0xC0, 0x47, 0x54, 0xFA,
2496 0x9D, 0x2A, 0xE0, 0x54
2497};
2498
2499/* Function declaration for TCG Configuration log page (LID:C7h) */
2500static int ocp_tcg_configuration_log(int argc, char **argv, struct command *acmd,
2501 struct plugin *plugin);
2502
2503static int get_c7_log_page(struct libnvme_transport_handle *hdl, char *format)
2504{
2505 nvme_print_flags_t fmt;
2506 int ret;
2507 __u8 *data;
2508 int i;
2509 struct tcg_configuration_log *log_data;
2510 int j;
2511
2512 ret = validate_output_format(format, &fmt);
2513 if (ret < 0) {
2514 fprintf(stderrstderr, "ERROR : OCP : invalid output format\n");
2515 return ret;
2516 }
2517
2518 data = (__u8 *)malloc(sizeof(__u8) * C7_TCG_CONFIGURATION_LEN512);
2519 if (!data) {
2520 fprintf(stderrstderr, "ERROR : OCP : malloc : %s\n", libnvme_strerror(errno(*__errno_location ())));
2521 return -1;
2522 }
2523 memset(data, 0, sizeof(__u8) * C7_TCG_CONFIGURATION_LEN512);
2524
2525 ret = ocp_get_log_simple(hdl, OCP_LID_TCGL, C7_TCG_CONFIGURATION_LEN512, data);
2526 if (!ret) {
2527 log_data = (struct tcg_configuration_log *)data;
2528
2529 /*
2530 * check log page guid
2531 * Verify GUID matches
2532 */
2533 for (i = 0; i < 16; i++) {
2534 if (tcg_configuration_guid[i] != log_data->log_page_guid[i]) {
2535 fprintf(stderrstderr, "ERROR : OCP : Unknown GUID in C7 Log Page data\n");
2536 fprintf(stderrstderr, "ERROR : OCP : Expected GUID: 0x");
2537 for (j = 0; j < 16; j++)
2538 fprintf(stderrstderr, "%02x", tcg_configuration_guid[j]);
2539 fprintf(stderrstderr, "\nERROR : OCP : Actual GUID: 0x");
2540 for (j = 0; j < 16; j++)
2541 fprintf(stderrstderr, "%02x", log_data->log_page_guid[j]);
2542 fprintf(stderrstderr, "\n");
2543
2544 ret = -1;
2545 goto out;
2546 }
2547 }
2548 ocp_c7_log(hdl, log_data, fmt);
2549 } else {
2550 fprintf(stderrstderr, "ERROR : OCP : Unable to read C7 data from buffer\n");
2551 }
2552
2553out:
2554 free(data);
2555 return ret;
2556}
2557
2558static int ocp_tcg_configuration_log(int argc, char **argv, struct command *acmd,
2559 struct plugin *plugin)
2560{
2561 const char *desc = "Retrieve TCG Configuration Log Page Data";
2562 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2563 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2564 int ret = 0;
2565
2566 struct config {
2567 char *output_format;
2568 };
2569
2570 struct config cfg = {
2571 .output_format = "normal",
2572 };
2573
2574 NVME_ARGS(opts)struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
2575
2576 ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2577 if (ret)
2578 return ret;
2579
2580 ret = get_c7_log_page(hdl, cfg.output_format);
2581 if (ret)
2582 fprintf(stderrstderr, "ERROR : OCP : Failure reading the C7 Log Page, ret = %d\n", ret);
2583
2584 return ret;
2585}
2586
2587///////////////////////////////////////////////////////////////////////////////
2588///////////////////////////////////////////////////////////////////////////////
2589///////////////////////////////////////////////////////////////////////////////
2590///////////////////////////////////////////////////////////////////////////////
2591/// Misc
2592
2593static int clear_fw_update_history(int argc, char **argv,
2594 struct command *command, struct plugin *plugin)
2595{
2596 return ocp_clear_fw_update_history(argc, argv, command, plugin);
2597}
2598
2599static int smart_add_log(int argc, char **argv, struct command *acmd,
2600 struct plugin *plugin)
2601{
2602 return ocp_smart_add_log(argc, argv, acmd, plugin);
2603}
2604
2605static int clear_pcie_correctable_error_counters(int argc, char **argv, struct command *acmd,
2606 struct plugin *plugin)
2607{
2608 return ocp_clear_pcie_correctable_errors(argc, argv, acmd, plugin);
2609}
2610
2611static int get_clear_pcie_correctable_error_counters(int argc, char **argv, struct command *acmd,
2612 struct plugin *plugin)
2613{
2614 return get_ocp_error_counters(argc, argv, acmd, plugin);
2615}
2616
2617static int fw_activation_history_log(int argc, char **argv, struct command *acmd,
2618 struct plugin *plugin)
2619{
2620 return ocp_fw_activation_history_log(argc, argv, acmd, plugin);
2621}
2622
2623static int error_injection_get(struct libnvme_transport_handle *hdl, const __u8 sel, bool_Bool uuid, __u32 nsid)
2624{
2625 __cleanup_libnvme_free__attribute__((cleanup(libnvme_freep))) struct erri_entry *entry = NULL((void*)0);
2626 struct erri_get_cq_entry cq_entry;
2627 const __u8 fid = OCP_FID_ERRI;
2628 __u64 result;
2629 __u32 data_len = 0;
2630 __u8 uidx = 0;
2631 int err;
2632 int i;
2633
2634 data_len = sizeof(*entry) * ERRI_ENTRIES_MAX127;
2635
2636 if (uuid) {
2637 /* OCP 2.0 requires UUID index support */
2638 err = ocp_get_uuid_index(hdl, &uidx);
2639 if (err || !uidx) {
2640 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2641 return err;
2642 }
2643 }
2644
2645 entry = libnvme_alloc(data_len);
2646 if (!entry) {
2647 nvme_show_error("malloc: %s", libnvme_strerror(errno))nvme_show_message(1, "malloc: %s", libnvme_strerror((*__errno_location
())))
;
2648 return -ENOMEM12;
2649 }
2650
2651 err = nvme_get_features(hdl, 0, fid, sel, 0, uidx, entry,
2652 data_len, &result);
2653 if (!err) {
2654 cq_entry.nume = result;
2655 nvme_show_result("Number of Error Injections (feature: %#0*x): %#0*x (%s: %d)",nvme_show_message(0, "Number of Error Injections (feature: %#0*x): %#0*x (%s: %d)"
, fid ? 4 : 2, fid, cq_entry.nume ? 10 : 8, cq_entry.nume, nvme_select_to_string
(sel), cq_entry.nume)
2656 fid ? 4 : 2, fid, cq_entry.nume ? 10 : 8, cq_entry.nume,nvme_show_message(0, "Number of Error Injections (feature: %#0*x): %#0*x (%s: %d)"
, fid ? 4 : 2, fid, cq_entry.nume ? 10 : 8, cq_entry.nume, nvme_select_to_string
(sel), cq_entry.nume)
2657 nvme_select_to_string(sel), cq_entry.nume)nvme_show_message(0, "Number of Error Injections (feature: %#0*x): %#0*x (%s: %d)"
, fid ? 4 : 2, fid, cq_entry.nume ? 10 : 8, cq_entry.nume, nvme_select_to_string
(sel), cq_entry.nume)
;
2658 if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2659 nvme_show_select_result(fid, result);
2660 for (i = 0; i < cq_entry.nume; i++) {
2661 printf("Entry: %d, Flags: %x (%s%s), Type: %x (%s), NRTDP: %d\n", i,
2662 entry[i].flags, entry[i].enable ? "Enabled" : "Disabled",
2663 entry[i].single ? ", Single instance" : "", entry[i].type,
2664 erri_type_to_string(entry[i].type), entry[i].nrtdp);
2665 }
2666 } else {
2667 nvme_show_error("Could not get feature: %#0*x. %d", fid ? 4 : 2, fid)nvme_show_message(1, "Could not get feature: %#0*x. %d", fid ?
4 : 2, fid)
;
2668 }
2669
2670 return err;
2671}
2672
2673static int get_error_injection(int argc, char **argv, struct command *acmd, struct plugin *plugin)
2674{
2675 const char *desc = "Get Error Injection Feature";
2676 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2677 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2678 int err;
2679 struct config {
2680 __u8 sel;
2681 };
2682 __u32 nsid;
2683 struct config cfg = { 0 };
2684
2685
2686 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all_ns
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2687 OPT_BYTE("sel", 's', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all_ns
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2688 OPT_FLAG("no-uuid", 'n', NULL, no_uuid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all_ns
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2689 OPT_FLAG("all-ns", 'a', NULL, all_ns))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*)0), 0, all_ns
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
2690
2691 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2692 if (err)
2693 return err;
2694
2695 /*
2696 * Different spec versions ask for different nsid values
2697 * OCP v1.0 - NSID: Shall be set to zero
2698 * OCP v2.0r21 - NSID: Shall be set to FFFFFFFFh.
2699 * OCP v2.5 - NSID: The host should either clear this to zero or set this to FFFFFFFFh
2700 */
2701 nsid = argconfig_parse_seen(opts, "all-ns") ? NVME_NSID_ALL : 0;
2702
2703 return error_injection_get(hdl, cfg.sel, !argconfig_parse_seen(opts, "no-uuid"), nsid);
2704}
2705
2706static int error_injection_set(struct libnvme_transport_handle *hdl, struct erri_config *cfg, bool_Bool uuid, __u32 nsid)
2707{
2708 __cleanup_libnvme_free__attribute__((cleanup(libnvme_freep))) struct erri_entry *entry = NULL((void*)0);
2709 __cleanup_fd__attribute__((cleanup(cleanup_fd))) int ffd = -1;
2710 __u32 data_len;
2711 __u8 uidx = 0;
2712 int err;
2713
2714 if (uuid) {
2715 /* OCP 2.0 requires UUID index support */
2716 err = ocp_get_uuid_index(hdl, &uidx);
2717 if (err || !uidx) {
2718 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2719 return err;
2720 }
2721 }
2722
2723 data_len = cfg->number * sizeof(struct erri_entry);
2724 entry = libnvme_alloc(data_len);
2725 if (!entry) {
2726 nvme_show_error("malloc: %s", libnvme_strerror(errno))nvme_show_message(1, "malloc: %s", libnvme_strerror((*__errno_location
())))
;
2727 return -ENOMEM12;
2728 }
2729
2730 if (cfg->file && strlen(cfg->file)) {
2731 ffd = open(cfg->file, O_RDONLY00);
2732 if (ffd < 0) {
2733 nvme_show_error("Failed to open file %s: %s", cfg->file, libnvme_strerror(errno))nvme_show_message(1, "Failed to open file %s: %s", cfg->file
, libnvme_strerror((*__errno_location ())))
;
2734 return -EINVAL22;
2735 }
2736 err = read(ffd, entry, data_len);
2737 if (err < 0) {
2738 nvme_show_error("failed to read data buffer from input file: %s",nvme_show_message(1, "failed to read data buffer from input file: %s"
, libnvme_strerror((*__errno_location ())))
2739 libnvme_strerror(errno))nvme_show_message(1, "failed to read data buffer from input file: %s"
, libnvme_strerror((*__errno_location ())))
;
2740 return -errno(*__errno_location ());
2741 }
2742 } else {
2743 entry->enable = 1;
2744 entry->single = 1;
2745 entry->type = cfg->type;
2746 entry->nrtdp = cfg->nrtdp;
2747 }
2748
2749 err = nvme_set_features(hdl, nsid, OCP_FID_ERRI, false0, cfg->number,
2750 0, 0, 0, 0, entry, data_len, NULL((void*)0));
2751 if (err) {
2752 if (err < 0)
2753 nvme_show_error("set-error-injection: %s", libnvme_strerror(errno))nvme_show_message(1, "set-error-injection: %s", libnvme_strerror
((*__errno_location ())))
;
2754 else if (err > 0)
2755 nvme_show_status(err);
2756 return err;
2757 }
2758
2759 printf("set-error-injection, data: %s, number: %d, uuid: %d, type: %d, nrtdp: %d\n",
2760 cfg->file, cfg->number, uidx, cfg->type, cfg->nrtdp);
2761 if (entry)
2762 d((unsigned char *)entry, data_len, 16, 1);
2763
2764 return 0;
2765}
2766
2767static int set_error_injection(int argc, char **argv, struct command *acmd, struct plugin *plugin)
2768{
2769 const char *desc = "Inject error conditions";
2770 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2771 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2772 __u32 nsid;
2773 int err;
2774
2775 struct erri_config cfg = {
2776 .number = 1,
2777 };
2778
2779 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2780 OPT_FILE("data", 'd', &cfg.file, data),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2781 OPT_BYTE("number", 'n', &cfg.number, number),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2782 OPT_FLAG("no-uuid", 'N', NULL, no_uuid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2783 OPT_FLAG("all-ns", 'a', NULL, all_ns),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2784 OPT_SHRT("type", 't', &cfg.type, type),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2785 OPT_SHRT("nrtdp", 'r', &cfg.nrtdp, nrtdp))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"data", 'd', "FILE", CFG_STRING, &cfg.file, 1, data
, 0, }, {"number", 'n', "NUM", CFG_BYTE, &cfg.number, 1, number
, 0, }, {"no-uuid", 'N', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"all-ns", 'a', ((void*)0), CFG_FLAG, ((void*
)0), 0, all_ns, 0, }, {"type", 't', "NUM", CFG_SHORT, &cfg
.type, 1, type, 0, }, {"nrtdp", 'r', "NUM", CFG_SHORT, &cfg
.nrtdp, 1, nrtdp, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2786
2787 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2788 if (err)
2789 return err;
2790
2791 /*
2792 * Different spec versions ask for different nsid values
2793 * OCP v1.0 - NSID: Shall be set to zero
2794 * OCP v2.0r21 - NSID: Shall be set to FFFFFFFFh.
2795 * OCP v2.5 - NSID: The host should either clear this to zero or set this to FFFFFFFFh
2796 */
2797 nsid = argconfig_parse_seen(opts, "all-ns") ? NVME_NSID_ALL : 0;
2798 return error_injection_set(hdl, &cfg, !argconfig_parse_seen(opts, "no-uuid"), nsid);
2799}
2800
2801static int enable_ieee1667_silo_get(struct libnvme_transport_handle *hdl, const __u8 sel, bool_Bool uuid)
2802{
2803 struct ieee1667_get_cq_entry cq_entry = { 0 };
2804 const __u8 fid = OCP_FID_1667;
2805 __u64 result;
2806 __u8 uidx = 0;
2807 int err;
2808
2809 if (uuid) {
2810 /* OCP 2.0 requires UUID index support */
2811 err = ocp_get_uuid_index(hdl, &uidx);
2812 if (err || !uidx) {
2813 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2814 return err;
2815 }
2816 }
2817
2818 err = nvme_get_features(hdl, NVME_NSID_NONE, fid, sel, 0, uidx,
2819 NULL((void*)0), 0, &result);
2820 if (!err) {
2821 if (sel == NVME_GET_FEATURES_SEL_SUPPORTED)
2822 nvme_show_select_result(fid, result);
2823 else
2824 nvme_show_result("IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)",nvme_show_message(0, "IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)"
, fid, cq_entry.enabled, nvme_select_to_string(sel), cq_entry
.enabled ? "enabled" : "disabled")
2825 fid, cq_entry.enabled, nvme_select_to_string(sel),nvme_show_message(0, "IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)"
, fid, cq_entry.enabled, nvme_select_to_string(sel), cq_entry
.enabled ? "enabled" : "disabled")
2826 cq_entry.enabled ? "enabled" : "disabled")nvme_show_message(0, "IEEE1667 Sifo Enabled (feature: 0x%02x): 0x%0x (%s: %s)"
, fid, cq_entry.enabled, nvme_select_to_string(sel), cq_entry
.enabled ? "enabled" : "disabled")
;
2827 } else {
2828 nvme_show_error("Could not get feature: 0x%02x.", fid)nvme_show_message(1, "Could not get feature: 0x%02x.", fid);
2829 }
2830
2831 return err;
2832}
2833
2834static int get_enable_ieee1667_silo(int argc, char **argv, struct command *acmd,
2835 struct plugin *plugin)
2836{
2837 const char *desc = "Get Enable IEEE1667 Silo Feature";
2838 int err;
2839 struct config {
2840 __u8 sel;
2841 };
2842 struct config cfg = { 0 };
2843
2844 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2845 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2846
2847 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2848 OPT_BYTE("sel", 's', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
2849 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0
, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM", CFG_INCREMENT
, &nvme_args.verbose, 0, "Increase output verbosity", 0, }
, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args.output_format
, 1, "Output format: normal|json|binary|tabular", 0, }, {"timeout"
, 0, "NUM", CFG_POSITIVE, &nvme_args.timeout, 1, "timeout value, in milliseconds"
, 0, }, {"dry-run", 0, ((void*)0), CFG_FLAG, &nvme_args.dry_run
, 0, "show command instead of executing", 0, }, {"no-retries"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_retries, 0, "disable retry logic on errors"
, 0, }, {"no-ioctl-probing", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_ioctl_probing, 0, "disable 64-bit IOCTL support probing",
0, }, {"output-format-version", 0, "NUM", CFG_POSITIVE, &
nvme_args.output_format_ver, 1, "output format version: 1|2",
0, }, {"human-readable", 'H', ((void*)0), CFG_FLAG, &nvme_args
.verbose, 0, ((void*)0), 0, ((void*)0), 1}, { ((void*)0) } }
;
2850
2851 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2852 if (err)
2853 return err;
2854
2855 return enable_ieee1667_silo_get(hdl, cfg.sel, !argconfig_parse_seen(opts, "no-uuid"));
2856}
2857
2858static int enable_ieee1667_silo_set(struct libnvme_transport_handle *hdl,
2859 struct argconfig_commandline_options *opts)
2860{
2861 bool_Bool enable = argconfig_parse_seen(opts, "enable");
2862 bool_Bool save = argconfig_parse_seen(opts, "save");
2863 struct ieee1667_get_cq_entry cq_entry;
2864 const __u8 fid = OCP_FID_1667;
2865 __u64 result;
2866 __u32 cdw11;
2867 __u8 uidx = 0;
2868 int err;
2869
2870 if (!argconfig_parse_seen(opts, "no-uuid")) {
2871 /* OCP 2.0 requires UUID index support */
2872 err = ocp_get_uuid_index(hdl, &uidx);
2873 if (err || !uidx) {
2874 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
2875 return err;
2876 }
2877 }
2878
2879 cdw11 = OCP_SET(enable, ENABLE_IEEE1667_SILO)(((__u32)(enable) & NVME_OCP_ENABLE_IEEE1667_SILO_MASK) <<
NVME_OCP_ENABLE_IEEE1667_SILO_SHIFT)
;
2880 err = nvme_set_features(hdl, NVME_NSID_NONE, fid, save,
2881 cdw11, 0, 0, uidx, 0, NULL((void*)0), 0, &result);
2882 memcpy(&cq_entry, &result, sizeof(cq_entry));
2883 if (err > 0) {
2884 nvme_show_status(err);
2885 } else if (err < 0) {
2886 nvme_show_perror(enable_ieee1667_silo);
2887 fprintf(stderrstderr, "Command failed while parsing.\n");
2888 } else {
2889 nvme_show_result("Successfully set enable (feature: 0x%02x): %d (%s: %s).", fid,nvme_show_message(0, "Successfully set enable (feature: 0x%02x): %d (%s: %s)."
, fid, enable, save ? "Save" : "Not save", enable ? "Enabled"
: "Disabled")
2890 enable, save ? "Save" : "Not save",nvme_show_message(0, "Successfully set enable (feature: 0x%02x): %d (%s: %s)."
, fid, enable, save ? "Save" : "Not save", enable ? "Enabled"
: "Disabled")
2891 enable ? "Enabled" : "Disabled")nvme_show_message(0, "Successfully set enable (feature: 0x%02x): %d (%s: %s)."
, fid, enable, save ? "Save" : "Not save", enable ? "Enabled"
: "Disabled")
;
2892 }
2893
2894 return err;
2895}
2896
2897static int set_enable_ieee1667_silo(int argc, char **argv, struct command *acmd,
2898 struct plugin *plugin)
2899{
2900 int err;
2901
2902 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2903 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2904
2905 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable", 'e', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"save", 's', ((void*)0), CFG_FLAG, ((void*)0), 0, save
, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void
*)0), 0, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM"
, CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2906 OPT_FLAG("enable", 'e', NULL, no_uuid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable", 'e', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"save", 's', ((void*)0), CFG_FLAG, ((void*)0), 0, save
, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void
*)0), 0, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM"
, CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2907 OPT_FLAG("save", 's', NULL, save),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable", 'e', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"save", 's', ((void*)0), CFG_FLAG, ((void*)0), 0, save
, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void
*)0), 0, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM"
, CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2908 OPT_FLAG("no-uuid", 'n', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"enable", 'e', ((void*)0), CFG_FLAG, ((void*)0), 0, no_uuid
, 0, }, {"save", 's', ((void*)0), CFG_FLAG, ((void*)0), 0, save
, 0, }, {"no-uuid", 'n', ((void*)0), CFG_FLAG, ((void*)0), 0,
no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR, ((void
*)0), 0, "Global options", 0, ((void*)0)}, {"verbose", 'v', "NUM"
, CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2909
2910 err = parse_and_open(&ctx, &hdl, argc, argv, enable_ieee1667_silo, opts);
2911 if (err)
2912 return err;
2913
2914 return enable_ieee1667_silo_set(hdl, opts);
2915}
2916
2917static int hwcomp_log(int argc, char **argv, struct command *acmd, struct plugin *plugin)
2918{
2919 return ocp_hwcomp_log(argc, argv, acmd, plugin);
2920}
2921
2922static int ocp_get_persistent_event_log(int argc, char **argv,
2923 struct command *command, struct plugin *plugin)
2924{
2925 const char *desc = "Retrieve Persistent Event log info for the given " \
2926 "device in either decoded format(default), json or binary.";
2927 const char *action = "action the controller shall take during " \
2928 "processing this persistent log page command.";
2929 const char *log_len = "number of bytes to retrieve";
2930
2931 __cleanup_libnvme_free__attribute__((cleanup(libnvme_freep))) struct nvme_persistent_event_log *pevent = NULL((void*)0);
2932 struct nvme_persistent_event_log *pevent_collected = NULL((void*)0);
2933 __cleanup_huge__attribute__((cleanup(libnvme_free_huge))) struct libnvme_mem_huge mh = { 0, };
2934 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
2935 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
2936
2937 nvme_print_flags_t flags;
2938 void *pevent_log_info;
2939 int err;
2940
2941 struct config {
2942 __u8 action;
2943 __u32 log_len;
2944 bool_Bool raw_binary;
2945 };
2946
2947 struct config cfg = {
2948 .action = 0xff,
2949 .log_len = 0,
2950 .raw_binary = false0,
2951 };
2952
2953 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"action", 'a', "NUM", CFG_BYTE, &cfg.action, 1, action
, 0, }, {"log_len", 'l', "NUM", CFG_POSITIVE, &cfg.log_len
, 1, log_len, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG,
&cfg.raw_binary, 0, raw_use, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2954 OPT_BYTE("action", 'a', &cfg.action, action),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"action", 'a', "NUM", CFG_BYTE, &cfg.action, 1, action
, 0, }, {"log_len", 'l', "NUM", CFG_POSITIVE, &cfg.log_len
, 1, log_len, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG,
&cfg.raw_binary, 0, raw_use, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2955 OPT_UINT("log_len", 'l', &cfg.log_len, log_len),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"action", 'a', "NUM", CFG_BYTE, &cfg.action, 1, action
, 0, }, {"log_len", 'l', "NUM", CFG_POSITIVE, &cfg.log_len
, 1, log_len, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG,
&cfg.raw_binary, 0, raw_use, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
2956 OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw_use))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"action", 'a', "NUM", CFG_BYTE, &cfg.action, 1, action
, 0, }, {"log_len", 'l', "NUM", CFG_POSITIVE, &cfg.log_len
, 1, log_len, 0, }, {"raw-binary", 'b', ((void*)0), CFG_FLAG,
&cfg.raw_binary, 0, raw_use, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
2957
2958 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
2959 if (err)
2960 return err;
2961
2962 err = validate_output_format(nvme_args.output_format, &flags);
2963 if (err < 0) {
2964 nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format");
2965 return err;
2966 }
2967
2968 if (cfg.raw_binary)
2969 flags = BINARY;
2970
2971 pevent = libnvme_alloc(sizeof(*pevent));
2972 if (!pevent)
2973 return -ENOMEM12;
2974
2975 err = nvme_get_log_persistent_event(hdl, cfg.action,
2976 pevent, sizeof(*pevent));
2977 if (err < 0) {
2978 nvme_show_error("persistent event log: %s", libnvme_strerror(err))nvme_show_message(1, "persistent event log: %s", libnvme_strerror
(err))
;
2979 return err;
2980 } else if (err) {
2981 nvme_show_status(err);
2982 return err;
2983 }
2984
2985 if (cfg.action == NVME_PEVENT_LOG_RELEASE_CTX) {
2986 printf("Releasing Persistent Event Log Context\n");
2987 return 0;
2988 }
2989
2990 if (!cfg.log_len && cfg.action != NVME_PEVENT_LOG_EST_CTX_AND_READ) {
2991 cfg.log_len = le64_to_cpu(pevent->tll);
2992 } else if (!cfg.log_len && cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ) {
2993 printf("Establishing Persistent Event Log Context\n");
2994 return 0;
2995 }
2996
2997 /*
2998 * if header already read with context establish action 0x1,
2999 * action shall not be 0x1 again in the subsequent request,
3000 * until the current context is released by issuing action
3001 * with 0x2, otherwise throws command sequence error, make
3002 * it as zero to read the log page
3003 */
3004 if (cfg.action == NVME_PEVENT_LOG_EST_CTX_AND_READ)
3005 cfg.action = NVME_PEVENT_LOG_READ;
3006
3007 pevent_log_info = libnvme_alloc_huge(cfg.log_len, &mh);
3008 if (!pevent_log_info) {
3009 nvme_show_error("failed to allocate huge memory")nvme_show_message(1, "failed to allocate huge memory");
3010 return -ENOMEM12;
3011 }
3012
3013 err = nvme_get_log_persistent_event(hdl, cfg.action,
3014 pevent_log_info, cfg.log_len);
3015 if (!err) {
3016 err = nvme_get_log_persistent_event(hdl, cfg.action,
3017 pevent,
3018 sizeof(*pevent));
3019 if (err < 0) {
3020 nvme_show_error("persistent event log: %s", libnvme_strerror(err))nvme_show_message(1, "persistent event log: %s", libnvme_strerror
(err))
;
3021 return err;
3022 } else if (err) {
3023 nvme_show_status(err);
3024 return err;
3025 }
3026 pevent_collected = pevent_log_info;
3027 if (pevent_collected->gen_number != pevent->gen_number) {
3028 printf("Collected Persistent Event Log may be invalid,\n"
3029 "Re-read the log is required\n");
3030 return -EINVAL22;
3031 }
3032
3033 ocp_show_persistent_event_log(pevent_log_info, cfg.action,
3034 cfg.log_len, libnvme_transport_handle_get_name(hdl), flags);
3035 } else if (err > 0) {
3036 nvme_show_status(err);
3037 } else {
3038 nvme_show_error("persistent event log: %s", libnvme_strerror(err))nvme_show_message(1, "persistent event log: %s", libnvme_strerror
(err))
;
3039 }
3040
3041 return err;
3042}
3043
3044///////////////////////////////////////////////////////////////////////////////
3045///////////////////////////////////////////////////////////////////////////////
3046///////////////////////////////////////////////////////////////////////////////
3047///////////////////////////////////////////////////////////////////////////////
3048/// Idle Wake Up Time Configuration (Feature Identifier CAh) Get Feature
3049static int ocp_get_idle_wakeup_time_config_feature(int argc, char **argv,
3050 struct command *acmd,
3051 struct plugin *plugin)
3052{
3053 const char *desc = "Issue Get Feature command (FID: 0xCA) IWUT";
3054 const char *sel = "[0-3]: current/default/saved/supported/";
3055 const char *nsid = "Byte[04-07]: NSID Valid/Invalid/Inactive";
3056
3057 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
3058 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
3059
3060
3061 __u64 result;
3062 int err;
3063 bool_Bool uuid;
3064 __u8 uuid_index = 0;
3065
3066 struct config {
3067 __u8 sel;
3068 __u32 nsid;
3069 };
3070
3071 struct config cfg = {
3072 .sel = 0,
3073 .nsid = 0,
3074 };
3075
3076 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
3077 OPT_BYTE("sel", 's', &cfg.sel, sel),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
3078 OPT_UINT("namespace-id", 'n', &cfg.nsid, nsid),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
3079 OPT_FLAG("no-uuid", 'u', NULL, no_uuid))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"sel", 's', "NUM", CFG_BYTE, &cfg.sel, 1, sel, 0,
}, {"namespace-id", 'n', "NUM", CFG_POSITIVE, &cfg.nsid,
1, nsid, 0, }, {"no-uuid", 'u', ((void*)0), CFG_FLAG, ((void
*)0), 0, no_uuid, 0, }, {"", 0, ((void*)0), CFG_GROUP_SEPARATOR
, ((void*)0), 0, "Global options", 0, ((void*)0)}, {"verbose"
, 'v', "NUM", CFG_INCREMENT, &nvme_args.verbose, 0, "Increase output verbosity"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary|tabular"
, 0, }, {"timeout", 0, "NUM", CFG_POSITIVE, &nvme_args.timeout
, 1, "timeout value, in milliseconds", 0, }, {"dry-run", 0, (
(void*)0), CFG_FLAG, &nvme_args.dry_run, 0, "show command instead of executing"
, 0, }, {"no-retries", 0, ((void*)0), CFG_FLAG, &nvme_args
.no_retries, 0, "disable retry logic on errors", 0, }, {"no-ioctl-probing"
, 0, ((void*)0), CFG_FLAG, &nvme_args.no_ioctl_probing, 0
, "disable 64-bit IOCTL support probing", 0, }, {"output-format-version"
, 0, "NUM", CFG_POSITIVE, &nvme_args.output_format_ver, 1
, "output format version: 1|2", 0, }, {"human-readable", 'H',
((void*)0), CFG_FLAG, &nvme_args.verbose, 0, ((void*)0),
0, ((void*)0), 1}, { ((void*)0) } }
;
3080
3081 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
3082 if (err)
3083 return err;
3084
3085 uuid = !argconfig_parse_seen(opts, "no-uuid");
3086
3087 if (uuid) {
3088 /* OCP 2.0 requires UUID index support */
3089 err = ocp_get_uuid_index(hdl, &uuid_index);
3090 if (err || !uuid_index) {
3091 nvme_show_error("ERROR: No OCP UUID index found")nvme_show_message(1, "ERROR: No OCP UUID index found");
3092 return err;
3093 }
3094 }
3095
3096 err = nvme_get_features(hdl, cfg.nsid, OCP_FID_IWTC, cfg.sel, 0,
3097 uuid_index, NULL((void*)0), 0, &result);
3098 if (!err) {
3099 if (result == 0) {
3100 printf("get-feature:CAh,SEL=%s,IWUT Disabled: %#016"PRIx64"l" "x""\n",
3101 nvme_select_to_string(cfg.sel), (uint64_t)result);
3102 } else {
3103 printf("get-feature:CAh SEL=%s,IWUT is: %#016"PRIx64"l" "x""\n",
3104 nvme_select_to_string(cfg.sel), (uint64_t)result);
3105 }
3106 if (cfg.sel == NVME_GET_FEATURES_SEL_SUPPORTED)
3107 nvme_show_select_result(0xCA, result);
3108 } else {
3109 nvme_show_error("Could not get feature: 0xCA")nvme_show_message(1, "Could not get feature: 0xCA");
3110 }
3111
3112 return err;
3113}