Bug Summary

File:.build-ci/../plugins/solidigm/solidigm-workload-tracker.c
Warning:line 360, column 5
Value stored to 'err' 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 solidigm-workload-tracker.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/solidigm/solidigm-workload-tracker.c
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) 2024 Solidigm.
4 *
5 * Authors: leonardo.da.cunha@solidigm.com
6 */
7
8#include <errno(*__errno_location ()).h>
9#include <time.h>
10
11#include "common.h"
12#include "nvme-cmds.h"
13#include "nvme-print.h"
14
15#define LID0xf9 0xf9
16#define FID0xf1 0xf1
17#define WLT2US25 25
18#define WLT2MS(25 * 1000) (WLT2US25 * 1000)
19#define MAX_WORKLOAD_LOG_ENTRIES126 126
20#define MAX_WORKLOAD_LOG_ENTRY_SIZE32 32
21#define MAX_FIELDS15 15
22
23char const *samplet[] = {
24 "default",
25 "1ms",
26 "5ms",
27 "10ms",
28 "50ms",
29 "100ms",
30 "500ms",
31 "1s",
32 "5s",
33 "10s",
34 "30s",
35 "1m",
36 "5m",
37 "10m",
38 "30m",
39 "1h"
40};
41
42char const *trk_types[] = {
43 "Base",
44 "CmdQ",
45 "Pattern",
46 "RandSeq",
47 "Throttle",
48 "Power",
49 "Defrag"
50};
51
52struct field {
53 __u8 size;
54 char *name;
55 char *desc;
56};
57
58struct field group_fields[][MAX_FIELDS15] = {
59{ // Base, group 0
60 {4, "hostReads", "Host Read Count in Sectors"},
61 {4, "hostWrites", "Host Write Count in Sectors"},
62 {4, "nandWrites", "Nand Write Count in Sectors"},
63 {1, "misalignment%", "% of Misaligned Sectors"},
64 {1, "collision%", "% of Colliding Sectors"},
65 {1, "randomWrite%", "% of Random Write Sectors vs. Sequential"},
66 {1, "randomRead%", "% of Random Read Sectors vs. Sequential"},
67 {4, "xorInvokedCount", "Count of XOR Operations Invoked"},
68 {4, "hostSoftReadSuccess", "Count of Soft Reads Completed Successfully."},
69 {4, "bandDefragRelocation", "Count of BDRs"},
70 {1, "pwrThrottle%", "% of Throttle Period due to Power Regulation"},
71 {1, "thmThrottle%", "% of Throttle Period due to Thermal Levels"},
72 {1, "tbufBg%", "% of Background TBUF Work vs. All Available Work"},
73 {1, "tbufHost%", "% of Host Requested TBUF Work vs. All Available Work"},
74 {0}
75},
76{ //CmdQ stats, group 1
77 {4, "CmdQ_InternalReadQDepth", "Snapshot of the Internal Read Queue Depth"},
78 {4, "CmdQ_DetectedWriteQDepth", "Snapshot of the Internal Write Queue Depth"},
79 {4, "CmdQ_ReadCmdsPending", "Snapshot of the Internal Read Commands Pending"},
80 {1, "misalignment%", "% of Misaligned Sectors"},
81 {1, "collision%", "% of Colliding Sectors"},
82 {1, "randomWrite%", "% of Random Write Sectors vs. Sequential"},
83 {1, "randomRead%", "% of Random Read Sectors vs. Sequential"},
84 {4, "CmdQ_WriteCmdsPending", "Snapshot of the Internal Write Commands Pending"},
85 {4, "CmdQ_ReadCmdsOutstanding", "Snapshot of the Internal Read Commands Outstanding"},
86 {4, "CmdQ_WriteCmdsOutstanding", "Snapshot of the Internal Read Commands Outstanding"},
87 {1, "pwrThrottle%", "% of Throttle Period due to Power Regulation"},
88 {1, "thmThrottle%", "% of Throttle Period due to Thermal Levels"},
89 {1, "tbufBg%", "% of Background TBUF Work vs. All Available Work"},
90 {1, "tbufHost%", "% of Host Requested TBUF Work vs. All Available Work"},
91 {0}
92},
93{ // test pattern, group 2
94 {4, "x11223300"},
95 {4, "x44556600_"},
96 {4, "x77889900_"},
97 {4, "xAABBCC00_"},
98 {2, "xDD00"},
99 {2, "xEE00"},
100 {2, "xFF00"},
101 {2, "x0_"},
102 {1, "x00"},
103 {1, "x80"},
104 {1, "x__"},
105 {1, "x8_"},
106 {4, "x33322100"},
107 {0}
108},
109{ // Random vs. Sequential Data, group 3
110 {4, "hostReads", "Host Read Count in Sectors"},
111 {4, "hostWrites", "Host Write Count in Sectors"},
112 {4, "nandWrites", "Nand Write Count in Sectors"},
113 {4, "randomReadCmd", "Count of Random Read Commands (vs. Sequential)"},
114 {4, "randomWriteCmd", "Count of Random Write Commands (vs. Sequential)"},
115 {4, "hostReadCmd", "Count of Total Host Read Commands (vs. Sequential)"},
116 {4, "hostWriteCmd", "Count of Total Host Read Commands (vs. Sequential)"},
117 {1, NULL((void*)0)},
118 {1, NULL((void*)0)},
119 {1, "randomWrite%", "% of Random Write Sectors vs. Sequential"},
120 {1, "randomThrottleRead%", "% of Random Read Sectors vs. Sequential"},
121 {0}
122},
123{ //Detailed Throttle Data, group 4
124 {4, "pwrThrottleOn_ms", "Duration of Power Throttling in mS."},
125 {4, "thmThrottleOn_ms", "Duration of Thermal Throttling in mS."},
126 {4, "powerOn_us", "Duration of Power-on in uS."},
127 {4, NULL((void*)0)},
128 {4, NULL((void*)0)},
129 {4, NULL((void*)0)},
130 {4, NULL((void*)0)},
131 {1, "pwrThrottle%", "% of Throttle Period due to Power Regulation"},
132 {1, "thmThrottle%", "% of Throttle Period due to Thermal Levels"},
133 {0}
134},
135{ // Detailed Power Data, group 5
136 // PMIC and/or Input Voltage Power
137 {4, "vin1Power", "in uW"},
138 {4, "vin2Power"},
139 // NAND Workload
140 {4, "nandWrites", "Nand Write Count in Sectors"},
141 {4, "nandReads", "Nand Read Count in Sectors"},
142 // Power Governor (if not enabled, all-0s)
143 {4, "lastNandAvgPwr"},
144 {4, "lastDriveAvgPwr"},
145 {4, "NscPwgSysCreditCnt"},
146 {4, "burstPowerBudget"},
147 {0}
148},
149{ // Defrag, group 6
150 {4, "hostReads", "Host Read Count in Sectors"},
151 {4, "hostWrites", "Host Write Count in Sectors"},
152 {4, "nandWrites", "Nand Write Count in Sectors"},
153 {4, "defragSlots", "Current defragSlots"},
154 {4, "hostSlots", "hostSlots"},
155 {4, "totalSlots", "Total slots"},
156 {1, "hostBufferUse%", "% of WCM_GetHostBuffersInUse to WCM_GetDesiredHostBuffer"},
157 {1, "defragBufferUse%", "% of defragBuffer to Desired defrag buffer %"},
158 {1, "defragSlotsUse%", "defragSlots to Total defrag slots %"},
159 {1, "hostSlotsUse%", "hostSlots to Total defrag slots %"},
160 {1, "aiuUse%", "% of AvailableIndirectionUnits to Start Setpoint IU"},
161 {1, "isImminentFRorWL", "defrag/Wear leveling is imminent"},
162 {1, "defragType", "defrag type"},
163 {0}
164}};
165
166#pragma pack(push, 1)
167union WorkloadLogEnable {
168 struct {
169 __u32 trackerEnable : 1;
170 __u32 triggerEnable : 1;
171 __u32 triggerSynchronous : 1; // trigger mode, 1=Synchronous,0=ASynchronous(Latency)
172 __u32 triggerDelta : 1; // trigger value mode, 1=delta, 0=current value
173 __u32 triggerDwordIndex : 3; // trigger dword index, 0~7 of a log entry
174 __u32 triggerByteWordIndex : 2; // trigger byte or word index,byte=0~3, word=0~1
175 __u32 triggerSize : 2; // trigger size, 1=byte, 2=word, 3=dword as a trigger
176 __u32 sampleTime : 4; // trigger sample time
177 __u32 contentGroup : 4; // content group select
178 __u32 stopCount : 12;// event limit,if<>0,stop tracker after stopCount events
179 __u32 eventDumpEnable : 1; // trigger event dump enable
180 };
181 __u32 dword;
182};
183
184struct workloadLog { // Full WL Log Structure
185 __u16 majorVersion; // Major Version
186 __u16 minorVersion; // Minor Version
187 __u32 workloadLogCount; // Number of Entries in the Workload Log
188 __u32 reserved; // reserve for future
189 __u32 triggeredEvents; // Count of events triggered
190 __u32 samplePeriodInMilliseconds; // Sample Period In Milliseconds
191 __u64 timestamp_lastEntry; // Timestamp for the last full entry
192 __u64 timestamp_triggered; // Timestamp at the point of trigger
193 union WorkloadLogEnable config; // Workload trigger and enable settings
194 __u32 triggerthreshold; // Trigger threshold
195 __u32 triggeredValue; // Actual value fired the trigger
196 __u8 entry[MAX_WORKLOAD_LOG_ENTRIES126][MAX_WORKLOAD_LOG_ENTRY_SIZE32];
197};
198#pragma pack(pop)
199
200struct wltracker {
201 struct libnvme_transport_handle *hdl;
202 __u8 uuid_index;
203 struct workloadLog workload_log;
204 size_t poll_count;
205 bool_Bool show_wall_timestamp;
206 __u64 us_epoch_ssd_delta;
207 __u64 start_time_us;
208 __u64 run_time_us;
209 bool_Bool disable;
210};
211
212static void wltracker_print_field_names(struct wltracker *wlt)
213{
214 struct workloadLog *log = &wlt->workload_log;
215
216 if (log->workloadLogCount == 0)
217 return;
218
219 printf("%-16s", "timestamp");
220
221 for (int i = 0 ; i < MAX_FIELDS15; i++) {
222 struct field f = group_fields[log->config.contentGroup][i];
223
224 if (f.size == 0)
225 break;
226 if (f.name == NULL((void*)0))
227 continue;
228 printf("%s ", f.name);
229 }
230
231 if (wlt->show_wall_timestamp)
232 printf("%-*s", (int)sizeof("YYYY-MM-DD-hh:mm:ss.uuuuuu"), "wall-time");
233
234 if (nvme_args.verbose > 1)
235 printf("%s", "entry# ");
236
237 printf("\n");
238}
239
240static void wltracker_print_header(struct wltracker *wlt)
241{
242 struct workloadLog *log = &wlt->workload_log;
243
244 printf("%-24s %u.%u\n", "Log page version:", le16_to_cpu(log->majorVersion),
245 le16_to_cpu(log->minorVersion));
246 printf("%-24s %u\n", "Sample period(ms):", le32_to_cpu(log->samplePeriodInMilliseconds));
247 printf("%-24s %lu\n", "timestamp_lastChange:", le64_to_cpu(log->timestamp_lastEntry));
248 printf("%-24s %lu\n", "timestamp_triggered:", le64_to_cpu(log->timestamp_triggered));
249 printf("%-24s 0x%x\n", "config:", le32_to_cpu(log->config.dword));
250 printf("%-24s %u\n", "Triggerthreshold:", le32_to_cpu(log->triggerthreshold));
251 printf("%-24s %u\n", "ValueTriggered:", le32_to_cpu(log->triggeredValue));
252 printf("%-24s %s\n", "Tracker Type:", trk_types[log->config.contentGroup]);
253 printf("%-24s %u\n", "Total log page entries:", le32_to_cpu(log->workloadLogCount));
254 printf("%-24s %u\n", "Trigger count:", log->triggeredEvents);
255 if (nvme_args.verbose > 1)
256 printf("%-24s %ld\n", "Poll count:", wlt->poll_count);
257 if (wlt->poll_count != 0)
258 wltracker_print_field_names(wlt);
259}
260
261__u64 micros_id(clockid_t clk_id)
262{
263 struct timespec ts;
264 __u64 us;
265
266 clock_gettime(clk_id, &ts);
267 us = (((__u64)ts.tv_sec)*1000000) + (((__u64)ts.tv_nsec)/1000);
268 return us;
269}
270
271__u64 micros(void)
272{
273 return micros_id(CLOCK_REALTIME0);
274}
275
276int wltracker_config(struct wltracker *wlt, union WorkloadLogEnable *we)
277{
278 return nvme_set_features(wlt->hdl, 0, FID0xf1, 0, we->dword, 0, 0, 0,
279 wlt->uuid_index, NULL((void*)0), 0, NULL((void*)0));
280}
281
282static int wltracker_show_newer_entries(struct wltracker *wlt)
283{
284 struct workloadLog *log = &wlt->workload_log;
285 union WorkloadLogEnable workloadEnable;
286 static __u64 last_timestamp_us;
287 struct libnvme_passthru_cmd cmd;
288 __u64 timestamp_us = 0;
289 __u64 timestamp = 0;
290 __u8 content_group;
291 __u8 cnt;
292 int err;
293
294 nvme_init_get_log(&cmd, NVME_NSID_NONE, LID0xf9, NVME_CSI_NVM,
295 log, sizeof(*log));
296 cmd.cdw14 |= NVME_FIELD_ENCODE(wlt->uuid_index,(((__u32)(wlt->uuid_index) & (NVME_LOG_CDW14_UUID_MASK
)) << (NVME_LOG_CDW14_UUID_SHIFT))
297 NVME_LOG_CDW14_UUID_SHIFT,(((__u32)(wlt->uuid_index) & (NVME_LOG_CDW14_UUID_MASK
)) << (NVME_LOG_CDW14_UUID_SHIFT))
298 NVME_LOG_CDW14_UUID_MASK)(((__u32)(wlt->uuid_index) & (NVME_LOG_CDW14_UUID_MASK
)) << (NVME_LOG_CDW14_UUID_SHIFT))
;
299 err = libnvme_get_log(wlt->hdl, &cmd, false0, NVME_LOG_PAGE_PDU_SIZE4096);
300 if (err > 0) {
301 nvme_show_status(err);
302 return err;
303 }
304 if (err < 0)
305 return err;
306
307 if (nvme_args.verbose)
308 wltracker_print_header(wlt);
309
310 cnt = log->workloadLogCount;
311 workloadEnable = log->config;
312 content_group = workloadEnable.contentGroup;
313
314 if (cnt == 0) {
315 nvme_show_error("Warning : No valid workload log data\n")nvme_show_message(1, "Warning : No valid workload log data\n"
)
;
316 return 0;
317 }
318
319 timestamp_us = (le64_to_cpu(log->timestamp_lastEntry) / WLT2US25) -
320 (log->samplePeriodInMilliseconds * 1000 * (cnt - 1));
321 timestamp = le64_to_cpu(log->timestamp_lastEntry) -
322 (log->samplePeriodInMilliseconds * WLT2MS(25 * 1000) * (cnt - 1));
323
324 if (wlt->poll_count++ == 0) {
325 __u64 tle = log->timestamp_lastEntry;
326 __u8 tracker_enable_bit = workloadEnable.trackerEnable;
327
328 wltracker_print_field_names(wlt);
329
330 if (wlt->show_wall_timestamp &&
331 ((log->triggeredEvents && wlt->disable) || !tracker_enable_bit)) {
332 // retrieve fresh timestamp to reconstruct wall time
333 union WorkloadLogEnable we = log->config;
334
335 if (nvme_args.verbose > 1) {
336 printf("Temporarily enabling tracker to find current timestamp\n");
337 printf("Original config value: 0x%08x\n", we.dword);
338 }
339 we.trackerEnable = true1;
340 we.triggerEnable = false0;
341 we.sampleTime = 1;
342
343 if (nvme_args.verbose > 1)
344 printf("Modified config value: 0x%08x\n", we.dword);
345
346 err = wltracker_config(wlt, &we);
347 usleep(1000);
348 if (!err) {
349 struct workloadLog tl;
350
351 err = nvme_get_log_simple(wlt->hdl, LID0xf9, &tl, sizeof(tl));
352 tle = tl.timestamp_lastEntry;
353 }
354 if (err) {
355 nvme_show_error("Failed to retrieve latest SSD timestamp")nvme_show_message(1, "Failed to retrieve latest SSD timestamp"
)
;
356 } else {
357 // Restore original config , but don't reenable trigger
358 we = log->config;
359 we.triggerEnable = false0;
360 err = wltracker_config(wlt, &we);
Value stored to 'err' is never read
361 if (nvme_args.verbose > 1)
362 printf("Restored config value: 0x%08x\n",
363 we.dword);
364 }
365 }
366 wlt->us_epoch_ssd_delta = (micros() - le64_to_cpu(tle) / WLT2US25);
367 }
368
369 for (int i = cnt - 1; i >= 0; i--) {
370 int offset = 0;
371 __u8 *entry = (__u8 *) &log->entry[i];
372 // allow 10% sample skew
373 bool_Bool is_old = timestamp_us <= last_timestamp_us +
374 (log->samplePeriodInMilliseconds * 100);
375
376 if (is_old) {
377 timestamp_us += (log->samplePeriodInMilliseconds * 1000);
378 timestamp += log->samplePeriodInMilliseconds * WLT2MS(25 * 1000);
379 continue;
380 }
381 printf("%-16llu", timestamp);
382 for (int j = 0; j < MAX_FIELDS15; j++) {
383 __u32 val = 0;
384 struct field f = group_fields[content_group][j];
385
386 if (f.size == 0) {
387 if (wlt->show_wall_timestamp) {
388 time_t epoch_ts_us = timestamp_us +
389 wlt->us_epoch_ssd_delta;
390 time_t ts_s = epoch_ts_us / 1000000;
391 struct tm ts = *localtime(&ts_s);
392 char buf[80];
393
394 strftime(buf, sizeof(buf), "%Y-%m-%d-%H:%M:%S", &ts);
395 printf("%s.%06" PRIu64"l" "u" " ", buf,
396 (uint64_t)(epoch_ts_us % 1000000ULL));
397 }
398
399 if (nvme_args.verbose > 1)
400 printf("%-*i", (int)sizeof("entry#"), i);
401
402 printf("\n");
403 break;
404 }
405 if (f.name == NULL((void*)0))
406 continue;
407
408 switch (f.size) {
409 case 1:
410 val = *(entry+offset);
411 break;
412 case 2:
413 val = *(__u16 *)(entry + offset);
414 break;
415 case 4:
416 val = *(__u32 *)(entry + offset);
417 break;
418 default:
419 nvme_show_error("Bad field size")nvme_show_message(1, "Bad field size");
420 }
421 offset += f.size;
422
423 printf("%-*u ", (int)strlen(f.name), val);
424 }
425 timestamp_us += (log->samplePeriodInMilliseconds * 1000);
426 timestamp += log->samplePeriodInMilliseconds * WLT2MS(25 * 1000);
427 }
428 last_timestamp_us = log->timestamp_lastEntry / WLT2US25;
429 return 0;
430}
431
432void wltracker_run_time_update(struct wltracker *wlt)
433{
434 wlt->run_time_us = micros() - wlt->start_time_us;
435 if (nvme_args.verbose > 0)
436 printf("run_time: %lluus\n", wlt->run_time_us);
437}
438
439static int stricmp(char const *a, char const *b)
440{
441 if (!a || !b)
442 return 1;
443 for (; *a || *b; a++, b++)
444 if (tolower((unsigned char)*a)(__extension__ ({ int __res; if (sizeof ((unsigned char)*a) >
1) { if (__builtin_constant_p ((unsigned char)*a)) { int __c
= ((unsigned char)*a); __res = __c < -128 || __c > 255
? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower
((unsigned char)*a); } else __res = (*__ctype_tolower_loc ()
)[(int) ((unsigned char)*a)]; __res; }))
!= tolower((unsigned char)*b)(__extension__ ({ int __res; if (sizeof ((unsigned char)*b) >
1) { if (__builtin_constant_p ((unsigned char)*b)) { int __c
= ((unsigned char)*b); __res = __c < -128 || __c > 255
? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower
((unsigned char)*b); } else __res = (*__ctype_tolower_loc ()
)[(int) ((unsigned char)*b)]; __res; }))
)
445 return 1;
446 return 0;
447}
448
449static int find_option(char const *list[], int size, const char *val)
450{
451 for (int i = 0; i < size; i++) {
452 if (!stricmp(val, list[i]))
453 return i;
454 }
455 return -EINVAL22;
456}
457
458static void join_options(char *dest, char const *list[], size_t list_size)
459{
460 strcat(dest, list[0]);
461 for (int i = 1; i < list_size; i++) {
462 strcat(dest, "|");
463 strcat(dest, list[i]);
464 }
465}
466
467static int find_field(struct field *fields, const char *val)
468{
469 for (int i = 0; i < MAX_FIELDS15; i++) {
470 if (!stricmp(val, fields[i].name))
471 return i;
472 }
473 return -EINVAL22;
474}
475
476static void join_fields(char *dest, struct field *fields)
477{
478 strcat(dest, fields[0].name);
479 for (int i = 1; i < MAX_FIELDS15; i++) {
480 char *name = fields[i].name;
481
482 if (name) {
483 strcat(dest, "|");
484 strcat(dest, name);
485 }
486 }
487}
488
489int sldgm_get_workload_tracker(int argc, char **argv, struct command *acmd, struct plugin *plugin)
490{
491 const char *desc = "Real Time capture Workload Tracker samples";
492 const char *sample_interval = "Sample interval";
493 const char *run_time = "Limit runtime capture time in seconds";
494 const char *flush_frequency =
495 "Samples (1 to 126) to wait for extracting data. Default 100 samples";
496 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
497 __cleanup_nvme_transport_handle__attribute__((cleanup(cleanup_nvme_transport_handle))) struct libnvme_transport_handle *hdl = NULL((void*)0);
498 struct wltracker wlt = {0};
499 union WorkloadLogEnable we = {0};
500 char type_options[80] = {0};
501 char sample_options[80] = {0};
502 __u64 stop_time_us;
503 __u64 next_sample_us = 0;
504 int opt;
505 int err;
506
507 struct config {
508 bool_Bool enable;
509 bool_Bool disable;
510 bool_Bool trigger_on_delta;
511 bool_Bool trigger_on_latency;
512 const char *tracker_type;
513 const char *sample_time;
514 __u32 run_time_s;
515 int flush_frequency;
516 char *trigger_field;
517 __u32 trigger_treshold;
518 };
519
520 struct config cfg = {
521 .sample_time = samplet[0],
522 .flush_frequency = 100,
523 .tracker_type = trk_types[0],
524 .trigger_field = "",
525 };
526
527 join_options(type_options, trk_types, ARRAY_SIZE(trk_types)(sizeof(trk_types) / sizeof((trk_types)[0])));
528 join_options(sample_options, samplet, ARRAY_SIZE(samplet)(sizeof(samplet) / sizeof((samplet)[0])));
529
530 NVME_ARGS(opts,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
531 OPT_BYTE("uuid-index", 'U', &wlt.uuid_index, "specify uuid index"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
532 OPT_FLAG("enable", 'e', &cfg.enable, "tracker enable"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
533 OPT_FLAG("disable", 'd', &cfg.disable, "tracker disable"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
534 OPT_STRING("sample-time", 's', sample_options, &cfg.sample_time, sample_interval),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
535 OPT_STRING("type", 't', type_options, &cfg.tracker_type, "Tracker type"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
536 OPT_UINT("run-time", 'r', &cfg.run_time_s, run_time),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
537 OPT_INT("flush-freq", 'f', &cfg.flush_frequency, flush_frequency),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
538 OPT_FLAG("wall-clock", 'w', &wlt.show_wall_timestamp,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
539 "Logs current wall timestamp when entry was retrieved"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
540 OPT_STR("trigger-field", 'T', &cfg.trigger_field, "Field name to stop trigger on"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
541 OPT_UINT("trigger-threshold", 'V', &cfg.trigger_treshold,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
542 "Field value to trigger stop sampling"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
543 OPT_FLAG("trigger-on-delta", 'D', &cfg.trigger_on_delta,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
544 "Trigger on delta to stop sampling"),struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
545 OPT_FLAG("trigger-on-latency", 'L', &cfg.trigger_on_latency,struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
546 "Use latency tracker to trigger stop sampling"))struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"uuid-index", 'U', "NUM", CFG_BYTE, &wlt.uuid_index
, 1, "specify uuid index", 0, }, {"enable", 'e', ((void*)0), CFG_FLAG
, &cfg.enable, 0, "tracker enable", 0, }, {"disable", 'd'
, ((void*)0), CFG_FLAG, &cfg.disable, 0, "tracker disable"
, 0, }, {"sample-time", 's', sample_options, CFG_STRING, &
cfg.sample_time, 1, sample_interval, 0, }, {"type", 't', type_options
, CFG_STRING, &cfg.tracker_type, 1, "Tracker type", 0, },
{"run-time", 'r', "NUM", CFG_POSITIVE, &cfg.run_time_s, 1
, run_time, 0, }, {"flush-freq", 'f', "NUM", CFG_INT, &cfg
.flush_frequency, 1, flush_frequency, 0, }, {"wall-clock", 'w'
, ((void*)0), CFG_FLAG, &wlt.show_wall_timestamp, 0, "Logs current wall timestamp when entry was retrieved"
, 0, }, {"trigger-field", 'T', "STRING", CFG_STRING, &cfg
.trigger_field, 1, "Field name to stop trigger on", 0, }, {"trigger-threshold"
, 'V', "NUM", CFG_POSITIVE, &cfg.trigger_treshold, 1, "Field value to trigger stop sampling"
, 0, }, {"trigger-on-delta", 'D', ((void*)0), CFG_FLAG, &
cfg.trigger_on_delta, 0, "Trigger on delta to stop sampling",
0, }, {"trigger-on-latency", 'L', ((void*)0), CFG_FLAG, &
cfg.trigger_on_latency, 0, "Use latency tracker to trigger stop sampling"
, 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) } }
;
547
548 err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts);
549 if (err)
550 return err;
551
552 if (wlt.uuid_index > 127) {
553 nvme_show_error("invalid uuid index param: %u", wlt.uuid_index)nvme_show_message(1, "invalid uuid index param: %u", wlt.uuid_index
)
;
554 return -1;
555 }
556
557 wlt.hdl = hdl;
558
559 if ((cfg.flush_frequency < 1) || (cfg.flush_frequency > MAX_WORKLOAD_LOG_ENTRIES126)) {
560 nvme_show_error("Invalid number of samples: %s. Valid values: 1-%d",nvme_show_message(1, "Invalid number of samples: %s. Valid values: 1-%d"
, cfg.flush_frequency, 126)
561 cfg.flush_frequency, MAX_WORKLOAD_LOG_ENTRIES)nvme_show_message(1, "Invalid number of samples: %s. Valid values: 1-%d"
, cfg.flush_frequency, 126)
;
562 return -EINVAL22;
563 }
564
565 opt = find_option(samplet, ARRAY_SIZE(samplet)(sizeof(samplet) / sizeof((samplet)[0])), cfg.sample_time);
566 if (opt < 0) {
567 nvme_show_error("invalid Sample interval: %s. Valid values: %s",nvme_show_message(1, "invalid Sample interval: %s. Valid values: %s"
, cfg.sample_time, sample_options)
568 cfg.sample_time, sample_options)nvme_show_message(1, "invalid Sample interval: %s. Valid values: %s"
, cfg.sample_time, sample_options)
;
569 return -EINVAL22;
570 }
571 we.sampleTime = opt;
572
573 opt = find_option(trk_types, ARRAY_SIZE(trk_types)(sizeof(trk_types) / sizeof((trk_types)[0])), cfg.tracker_type);
574 if (opt < 0) {
575 nvme_show_error("Invalid tracker type: \"%s\". Valid types: %s",nvme_show_message(1, "Invalid tracker type: \"%s\". Valid types: %s"
, cfg.tracker_type, type_options)
576 cfg.tracker_type, type_options)nvme_show_message(1, "Invalid tracker type: \"%s\". Valid types: %s"
, cfg.tracker_type, type_options)
;
577 return -EINVAL22;
578 }
579 we.contentGroup = opt;
580 if (argconfig_parse_seen(opts, "trigger-field")) {
581 int field_pos = find_field(group_fields[opt], cfg.trigger_field);
582 int field_offset = 0;
583
584 if (field_pos < 0) {
585 char field_options[256];
586
587 join_fields(field_options, group_fields[opt]);
588 nvme_show_error(nvme_show_message(1, "Invalid field name: %s. For type: \"%s\", valid fields are: %s"
, cfg.trigger_field, cfg.tracker_type, field_options)
589 "Invalid field name: %s. For type: \"%s\", valid fields are: %s",nvme_show_message(1, "Invalid field name: %s. For type: \"%s\", valid fields are: %s"
, cfg.trigger_field, cfg.tracker_type, field_options)
590 cfg.trigger_field, cfg.tracker_type, field_options)nvme_show_message(1, "Invalid field name: %s. For type: \"%s\", valid fields are: %s"
, cfg.trigger_field, cfg.tracker_type, field_options)
;
591 return -EINVAL22;
592 }
593 for (int i = 0; i < field_pos; i++)
594 field_offset += group_fields[opt][i].size;
595
596 we.triggerDwordIndex += field_offset / 4;
597 we.triggerSize =
598 group_fields[opt][field_pos].size ==
599 4 ? 3 : group_fields[opt][field_pos].size;
600 we.triggerByteWordIndex = field_offset % 4 /
601 group_fields[opt][field_pos].size;
602 we.triggerEnable = true1;
603 we.triggerDelta = cfg.trigger_on_delta;
604 we.triggerSynchronous = !cfg.trigger_on_latency;
605 err = nvme_set_features(wlt.hdl, 0, 0xf5, 0, cfg.trigger_treshold, 0,
606 0, wlt.uuid_index, 0, NULL((void*)0), 0, NULL((void*)0));
607 if (err < 0) {
608 nvme_show_error("Trigger Threshold set-feature: %s", libnvme_strerror(errno))nvme_show_message(1, "Trigger Threshold set-feature: %s", libnvme_strerror
((*__errno_location ())))
;
609 return err;
610 } else if (err > 0) {
611 nvme_show_status(err);
612 return err;
613 }
614 }
615
616 if (cfg.enable && cfg.disable) {
617 nvme_show_error("Can't enable disable simultaneously")nvme_show_message(1, "Can't enable disable simultaneously");
618 return -EINVAL22;
619 }
620 wlt.disable = cfg.disable;
621
622 if (cfg.enable) {
623 we.trackerEnable = true1;
624 err = wltracker_config(&wlt, &we);
625 if (err < 0) {
626 nvme_show_error("tracker set-feature: %s", libnvme_strerror(errno))nvme_show_message(1, "tracker set-feature: %s", libnvme_strerror
((*__errno_location ())))
;
627 return err;
628 } else if (err > 0) {
629 nvme_show_status(err);
630 return err;
631 }
632 }
633
634 wlt.start_time_us = micros();
635 stop_time_us = cfg.run_time_s * 1000000;
636 while (wlt.run_time_us < stop_time_us) {
637 __u64 interval;
638 __u64 elapsed;
639 __u64 prev_run_time_us = wlt.run_time_us;
640
641 err = wltracker_show_newer_entries(&wlt);
642
643 if (err > 0) {
644 nvme_show_status(err);
645 return err;
646 }
647 interval = ((__u64)wlt.workload_log.samplePeriodInMilliseconds) * 1000 *
648 cfg.flush_frequency;
649 next_sample_us += interval;
650 wltracker_run_time_update(&wlt);
651
652 if (wlt.workload_log.triggeredEvents)
653 break;
654 elapsed = wlt.run_time_us - prev_run_time_us;
655 if (interval > elapsed) {
656 __u64 period_us = min(next_sample_us - wlt.run_time_us,((next_sample_us - wlt.run_time_us) > (stop_time_us - wlt.
run_time_us) ? (stop_time_us - wlt.run_time_us) : (next_sample_us
- wlt.run_time_us))
657 stop_time_us - wlt.run_time_us)((next_sample_us - wlt.run_time_us) > (stop_time_us - wlt.
run_time_us) ? (stop_time_us - wlt.run_time_us) : (next_sample_us
- wlt.run_time_us))
;
658 if (nvme_args.verbose > 1)
659 printf("Sleeping %lluus..\n", period_us);
660 usleep(period_us);
661 wltracker_run_time_update(&wlt);
662 }
663 }
664
665 if (!wlt.workload_log.triggeredEvents) {
666 err = wltracker_show_newer_entries(&wlt);
667 wltracker_run_time_update(&wlt);
668 }
669
670 if (cfg.disable) {
671 union WorkloadLogEnable we2 = wlt.workload_log.config;
672
673 if (nvme_args.verbose > 1)
674 printf("Original config value: 0x%08x\n", we2.dword);
675
676 we2.trackerEnable = false0;
677 we2.triggerEnable = false0;
678 err = wltracker_config(&wlt, &we2);
679 if (err < 0) {
680 nvme_show_error("tracker set-feature: %s", libnvme_strerror(errno))nvme_show_message(1, "tracker set-feature: %s", libnvme_strerror
((*__errno_location ())))
;
681 return err;
682 } else if (err > 0) {
683 nvme_show_status(err);
684 return err;
685 }
686 if (nvme_args.verbose > 1)
687 printf("Modified config value: 0x%08x\n", we2.dword);
688 printf("Tracker disabled\n");
689 return 0;
690 }
691
692 if (err > 0) {
693 nvme_show_status(err);
694 return err;
695 }
696 return err;
697}