Bug Summary

File:.build-ci/../src/fabrics.c
Warning:line 1413, column 10
Potential leak of memory pointed to by 'fa.traddr'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name fabrics.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 static -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/bin/../lib/clang/22 -include /__w/nvme-cli/nvme-cli/.build-ci/nvme-config.h -I nvme.p -I . -I .. -I src -I ../src -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/bin/../lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=gnu11 -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 -fdwarf2-cfi-asm -o /__w/nvme-cli/nvme-cli/.build-ci/scan-results/2026-09-23-073103-589-1 -x c ../src/fabrics.c
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (C) 2016 Intel Corporation. All rights reserved.
4 * Copyright (c) 2016 HGST, a Western Digital Company.
5 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 *
18 * This file implements the discovery controller feature of NVMe over
19 * Fabrics specification standard.
20 */
21
22#include <errno(*__errno_location ()).h>
23#include <fcntl.h>
24#include <getopt.h>
25#include <inttypes.h>
26#include <libgen.h>
27#include <stdbool.h>
28#include <stddef.h>
29#include <stdint.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <sys/stat.h>
33#include <sys/types.h>
34#include <time.h>
35#include <unistd.h>
36
37#ifdef NVME_HAVE_NETDB
38#include <arpa/inet.h>
39#include <netdb.h>
40#include <sys/socket.h>
41#endif
42
43#ifdef NVME_HAVE_LIBKMOD
44#include <libkmod.h>
45#endif
46
47#include <libnvme.h>
48
49#include <ccan/endian/endian.h>
50#include <ccan/str/str.h>
51#include <shared/io-util.h>
52#include <shared/sig-util.h>
53
54#include "cleanup.h"
55#include "config-convert.h"
56#include "fabrics.h"
57#include "global-ctx.h"
58#include "logging.h"
59#include "nvme-print.h"
60
61#define MAX_DISC_ARGS32 32
62#define MAX_DISC_RETRIES10 10
63
64#define NVMF_DEF_DISC_TMO30 30
65
66/* Name of file to output log pages in their raw format */
67static char *raw;
68
69static const char *nvmf_config_file = "Use specified INI configuration file (auto-converts a legacy .json) or 'none' to disable";
70static const char *nvmf_config_file_ro = "INI configuration file (default: " PATH_NVMF_INI"/usr/local/etc" "/nvme/nvme-fabrics.conf" ")";
71
72void nvmf_default_args(struct nvmf_args *fa)
73{
74 fa->tos = -1;
75 fa->ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO600;
76}
77
78void nvmf_args_to_params(struct libnvmf_params *params,
79 const struct nvmf_args *fa)
80{
81 char buf[32];
82
83 if (fa->nr_io_queues) {
84 snprintf(buf, sizeof(buf), "%d", fa->nr_io_queues);
85 libnvmf_params_set(params, "nr-io-queues", buf);
86 }
87 if (fa->nr_write_queues) {
88 snprintf(buf, sizeof(buf), "%d", fa->nr_write_queues);
89 libnvmf_params_set(params, "nr-write-queues", buf);
90 }
91 if (fa->nr_poll_queues) {
92 snprintf(buf, sizeof(buf), "%d", fa->nr_poll_queues);
93 libnvmf_params_set(params, "nr-poll-queues", buf);
94 }
95 if (fa->queue_size) {
96 snprintf(buf, sizeof(buf), "%d", fa->queue_size);
97 libnvmf_params_set(params, "queue-size", buf);
98 }
99 if (fa->keep_alive_tmo) {
100 snprintf(buf, sizeof(buf), "%d", fa->keep_alive_tmo);
101 libnvmf_params_set(params, "keep-alive-tmo", buf);
102 }
103 if (fa->reconnect_delay) {
104 snprintf(buf, sizeof(buf), "%d", fa->reconnect_delay);
105 libnvmf_params_set(params, "reconnect-delay", buf);
106 }
107 if (fa->ctrl_loss_tmo != NVMF_DEF_CTRL_LOSS_TMO600) {
108 snprintf(buf, sizeof(buf), "%d", fa->ctrl_loss_tmo);
109 libnvmf_params_set(params, "ctrl-loss-tmo", buf);
110 }
111 if (fa->fast_io_fail_tmo) {
112 snprintf(buf, sizeof(buf), "%d", fa->fast_io_fail_tmo);
113 libnvmf_params_set(params, "fast-io-fail-tmo", buf);
114 }
115 if (fa->tos != -1) {
116 snprintf(buf, sizeof(buf), "%d", fa->tos);
117 libnvmf_params_set(params, "tos", buf);
118 }
119 if (fa->duplicate_connect)
120 libnvmf_params_set(params, "duplicate-connect", "true");
121 if (fa->disable_sqflow)
122 libnvmf_params_set(params, "disable-sqflow", "true");
123 if (fa->hdr_digest)
124 libnvmf_params_set(params, "hdr-digest", "true");
125 if (fa->data_digest)
126 libnvmf_params_set(params, "data-digest", "true");
127 if (fa->tls)
128 libnvmf_params_set(params, "tls", "true");
129 if (fa->concat)
130 libnvmf_params_set(params, "concat", "true");
131 if (fa->hostkey)
132 libnvmf_params_set(params, "kxchap-secret", fa->hostkey);
133 if (fa->ctrlkey)
134 libnvmf_params_set(params, "kxchap-ctrl-secret", fa->ctrlkey);
135 if (fa->keyring)
136 libnvmf_params_set(params, "keyring", fa->keyring);
137 if (fa->tls_key)
138 libnvmf_params_set(params, "tls-key", fa->tls_key);
139 if (fa->tls_key_identity)
140 libnvmf_params_set(params, "tls-key-identity",
141 fa->tls_key_identity);
142}
143
144static void save_discovery_log(char *raw, const struct nvmf_discovery_log *log)
145{
146 __cleanup_free__attribute__((cleanup(shr_freep))) char *path = NULL((void*)0);
147 static unsigned int save_count;
148 int fd, len, ret;
149 uint64_t numrec;
150
151 if (save_count) {
152 if (asprintf(&path, "%s.%u", raw, save_count) < 0) {
153 nvme_show_error("failed to allocate path for %s", raw)nvme_show_message(1, "failed to allocate path for %s", raw);
154 return;
155 }
156 } else {
157 path = strdup(raw);
158 if (!path) {
159 nvme_show_error("failed to allocate path for %s", raw)nvme_show_message(1, "failed to allocate path for %s", raw);
160 return;
161 }
162 }
163
164 fd = open(path, O_CREAT0100 | O_RDWR02 | O_TRUNC01000, 0600);
165 if (fd < 0) {
166 nvme_show_error("failed to open %s: %s",nvme_show_message(1, "failed to open %s: %s", path, libnvme_strerror
((*__errno_location ())))
167 path, libnvme_strerror(errno))nvme_show_message(1, "failed to open %s: %s", path, libnvme_strerror
((*__errno_location ())))
;
168 return;
169 }
170
171 numrec = le64_to_cpu(log->numrec);
172 len = sizeof(struct nvmf_discovery_log) +
173 numrec * sizeof(struct nvmf_disc_log_entry);
174
175 ret = shr_write_all(fd, log, len);
176 if (ret < 0)
177 nvme_show_error("failed to write to %s: %s",nvme_show_message(1, "failed to write to %s: %s", path, libnvme_strerror
(-ret))
178 path, libnvme_strerror(-ret))nvme_show_message(1, "failed to write to %s: %s", path, libnvme_strerror
(-ret))
;
179 else
180 nvme_show_verbose_info("Discovery log is saved to %s", path)nvme_show_verbose_message("Discovery log is saved to %s", path
)
;
181
182 close(fd);
183
184 save_count++;
185}
186
187static int setup_common_context(struct libnvmf_context *fctx,
188 struct nvmf_args *fa);
189
190struct hook_fabrics_data {
191 nvme_print_flags_t flags;
192 char *raw;
193};
194
195static bool_Bool hook_decide_retry(struct libnvmf_context *fctx, int err,
196 void *user_data)
197{
198 if (err == -EAGAIN11 || (err == -EINTR4 && !shr_sigint_received)) {
199 print_debug("libnvmf_add_ctrl returned '%s'\n", libnvme_strerror(-err))do { if (is_printable_at_level(LIBNVME_LOG_DEBUG)) printf("libnvmf_add_ctrl returned '%s'\n"
, libnvme_strerror(-err)); } while (0)
;
200 return true1;
201 }
202
203 return false0;
204}
205
206static void hook_connected(struct libnvmf_context *fctx,
207 struct libnvme_ctrl *c, void *user_data)
208{
209 struct hook_fabrics_data *hfd = user_data;
210
211 if (hfd->flags == NORMAL) {
212 nvme_show_verbose_info("connecting to device: %s", libnvme_ctrl_get_name(c))nvme_show_verbose_message("connecting to device: %s", libnvme_ctrl_get_name
(c))
;
213 return;
214 }
215
216#ifdef CONFIG_JSONC
217 if (hfd->flags == JSON) {
218 struct json_object *root;
219
220 root = json_create_object()json_object_new_object();
221
222 json_object_add_value_string(root, "device",
223 libnvme_ctrl_get_name(c));
224
225 json_print_object(root, NULL)printf("%s", json_object_to_json_string_ext(root, (1 <<
1) | (1 << 4)))
;
226 printf("\n");
227 json_free_object(root)json_object_put(root);
228 }
229#endif
230}
231
232static void hook_already_connected(struct libnvmf_context *fctx,
233 struct libnvme_host *host, const char *subsysnqn,
234 const char *transport, const char *traddr,
235 const char *trsvcid, void *user_data)
236{
237 /*
238 * Already-connected is reported through the exit code alone; this is
239 * just extra detail for --verbose, not a message a script should
240 * have to filter out of normal output.
241 */
242 nvme_show_verbose_info(nvme_show_verbose_message("already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s"
, libnvme_host_get_hostnqn(host), subsysnqn, transport, traddr
, trsvcid)
243 "already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s",nvme_show_verbose_message("already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s"
, libnvme_host_get_hostnqn(host), subsysnqn, transport, traddr
, trsvcid)
244 libnvme_host_get_hostnqn(host), subsysnqn,nvme_show_verbose_message("already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s"
, libnvme_host_get_hostnqn(host), subsysnqn, transport, traddr
, trsvcid)
245 transport, traddr, trsvcid)nvme_show_verbose_message("already connected to hostnqn=%s,nqn=%s,transport=%s,traddr=%s,trsvcid=%s"
, libnvme_host_get_hostnqn(host), subsysnqn, transport, traddr
, trsvcid)
;
246}
247
248static void hook_discovery_log(struct libnvmf_context *fctx,
249 const struct nvmf_discovery_log *log,
250 uint64_t numrec, void *user_data)
251{
252 struct hook_fabrics_data *hfd = user_data;
253
254 if (hfd->raw)
255 save_discovery_log(hfd->raw, log);
256 else if (!libnvmf_context_get_connect(fctx))
257 nvme_show_discovery_log(log, numrec, hfd->flags);
258}
259
260/*
261 * Resolve *addr in place if it names a tcp/rdma hostname; left untouched for
262 * any other transport, a NULL/"none" address, or one that is already
263 * numeric. Resolution is the caller's job, not libnvme's -- this is where
264 * that happens.
265 *
266 * Deliberately crude and sequential: one blocking getaddrinfo() call at a
267 * time, no threads. nvme-cli is a one-shot tool, so multiple discovery.conf
268 * lines simply resolve one after another.
269 */
270/*
271 * Resolve @addr to a canonical (numeric) address when @transport is tcp or
272 * rdma and @addr is a hostname; otherwise just copy it through unchanged.
273 *
274 * On success (0), *resolved always holds a fresh, caller-owned copy of the
275 * address to use from then on -- NULL only if @addr itself was NULL. The
276 * caller never needs to compare it against @addr to work out whether
277 * resolution actually happened: *resolved is always safe to free (e.g.
278 * __cleanup_free) once this returns 0.
279 */
280static int nvmf_resolve_addr(const char *transport, const char *addr, char **resolved)
281{
282 *resolved = NULL((void*)0);
283
284 if (!addr
6.1
'addr' is non-null
)
285 return 0;
286
287 if (!transport
6.2
'transport' is null
|| (strcmp(transport, "tcp") && strcmp(transport, "rdma")) ||
288 !strcmp(addr, "none") || libnvmf_traddr_is_numeric(addr))
289 goto copy_through;
7
Control jumps to line 342
290
291#ifdef NVME_HAVE_NETDB
292 {
293 struct addrinfo hints = { .ai_family = AF_UNSPEC0 };
294 struct addrinfo *host_info = NULL((void*)0);
295 char addrstr[NVMF_TRADDR_SIZE];
296 const char *p = NULL((void*)0);
297 int ret;
298
299 ret = getaddrinfo(addr, NULL((void*)0), &hints, &host_info);
300 if (ret) {
301 nvme_show_error("failed to resolve host '%s': %s",nvme_show_message(1, "failed to resolve host '%s': %s", addr,
gai_strerror(ret))
302 addr, gai_strerror(ret))nvme_show_message(1, "failed to resolve host '%s': %s", addr,
gai_strerror(ret))
;
303 return -EINVAL22;
304 }
305
306 switch (host_info->ai_family) {
307 case AF_INET2:
308 p = inet_ntop(host_info->ai_family,
309 &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr),
310 addrstr, NVMF_TRADDR_SIZE);
311 break;
312 case AF_INET610:
313 p = inet_ntop(host_info->ai_family,
314 &(((struct sockaddr_in6 *)
315 host_info->ai_addr)->sin6_addr),
316 addrstr, NVMF_TRADDR_SIZE);
317 break;
318 default:
319 break;
320 }
321
322 if (!p) {
323 nvme_show_error(nvme_show_message(1, "failed to resolve host '%s': unrecognized address family"
, addr)
324 "failed to resolve host '%s': unrecognized address family",nvme_show_message(1, "failed to resolve host '%s': unrecognized address family"
, addr)
325 addr)nvme_show_message(1, "failed to resolve host '%s': unrecognized address family"
, addr)
;
326 freeaddrinfo(host_info);
327 return -EINVAL22;
328 }
329
330 freeaddrinfo(host_info);
331
332 *resolved = strdup(addrstr);
333 return *resolved ? 0 : -ENOMEM12;
334 }
335#else /* NVME_HAVE_NETDB */
336 nvme_show_error(nvme_show_message(1, "hostname resolution is not available in this build; use a numeric address"
)
337 "hostname resolution is not available in this build; use a numeric address")nvme_show_message(1, "hostname resolution is not available in this build; use a numeric address"
)
;
338 return -ENOTSUP95;
339#endif /* NVME_HAVE_NETDB */
340
341copy_through:
342 *resolved = strdup(addr);
8
Memory is allocated
343 return *resolved ? 0 : -ENOMEM12;
9
Assuming the condition is true
10
'?' condition is true
344}
345
346static int set_fabrics_options(struct libnvmf_context *fctx,
347 struct nvmf_args *fa)
348{
349 libnvmf_context_set_io_queues(fctx, fa->nr_io_queues,
350 fa->nr_write_queues, fa->nr_poll_queues,
351 fa->queue_size, fa->disable_sqflow);
352 libnvmf_context_set_reconnect_policy(fctx, fa->ctrl_loss_tmo,
353 fa->reconnect_delay, fa->fast_io_fail_tmo);
354 libnvmf_context_set_keep_alive_tmo(fctx, fa->keep_alive_tmo);
355 libnvmf_context_set_tos(fctx, fa->tos);
356 libnvmf_context_set_keyring_id(fctx, fa->keyring_id);
357 libnvmf_context_set_tls_key_id(fctx, fa->tls_key_id);
358 libnvmf_context_set_tls_configured_key_id(fctx,
359 fa->tls_configured_key_id);
360 libnvmf_context_set_duplicate_connect(fctx, fa->duplicate_connect);
361 libnvmf_context_set_hdr_digest(fctx, fa->hdr_digest);
362 libnvmf_context_set_data_digest(fctx, fa->data_digest);
363 libnvmf_context_set_tls(fctx, fa->tls);
364 libnvmf_context_set_concat(fctx, fa->concat);
365
366 return 0;
367}
368
369enum consume_mode {
370 /* connect-all/discover: DC entries discover; IOC entries connect,
371 * but only for connect-all.
372 */
373 CONSUME_ROLE_BASED,
374 /* nvme connect -J: every entry connects directly, no discovery. */
375 CONSUME_CONNECT_ONLY,
376};
377
378struct consume_state {
379 struct libnvme_global_ctx *ctx;
380 enum consume_mode mode;
381 bool_Bool connect;
382 bool_Bool no_reuse;
383 nvme_print_flags_t flags;
384 char *raw;
385 const char *hostnqn;
386 const char *hostid;
387 int err;
388};
389
390/*
391 * Resolve traddr (if it's a hostname), settle host identity (falling back
392 * to @default_hostnqn/@default_hostid when @conn's own persona doesn't set
393 * one), then build the TID -- which doubles as validator/sanitizer:
394 * rejects a non-numeric traddr or host_traddr on tcp/rdma, canonicalizes a
395 * numeric one.
396 */
397static int build_conn_tid(const struct libnvmf_config_conn *conn,
398 const char *default_hostnqn, const char *default_hostid,
399 struct libnvmf_tid **tid)
400{
401 const char *transport, *hostnqn, *hostid;
402 __cleanup_free__attribute__((cleanup(shr_freep))) char *traddr = NULL((void*)0);
403 int err;
404
405 transport = libnvmf_config_conn_get_transport(conn);
406
407 /* Only traddr (remote target) may be a hostname (not host_traddr) */
408 err = nvmf_resolve_addr(transport, libnvmf_config_conn_get_traddr(conn), &traddr);
409 if (err)
410 return err;
411
412 hostnqn = libnvmf_config_conn_get_hostnqn(conn);
413 if (!hostnqn)
414 hostnqn = default_hostnqn;
415 hostid = libnvmf_config_conn_get_hostid(conn);
416 if (!hostid)
417 hostid = default_hostid;
418
419 return libnvmf_tid_from_fields(transport, traddr,
420 libnvmf_config_conn_get_trsvcid(conn),
421 libnvmf_config_conn_get_subsysnqn(conn),
422 libnvmf_config_conn_get_host_traddr(conn),
423 libnvmf_config_conn_get_host_iface(conn),
424 hostnqn, hostid, tid);
425}
426
427/* libnvmf_config_conn_for_each() callback: settle addressing/identity,
428 * check exclusion, then discover or connect.
429 */
430static void consume_conn(const struct libnvmf_config_conn *conn,
431 void *user_data)
432{
433 struct consume_state *st = user_data;
434 bool_Bool is_dc = libnvmf_config_conn_is_dc(conn);
435 struct hook_fabrics_data hfd = { .flags = st->flags, .raw = st->raw };
436 __cleanup_nvmf_context__attribute__((cleanup(cleanup_nvmf_context))) struct libnvmf_context *fctx = NULL((void*)0);
437 __cleanup_nvmf_tid__attribute__((cleanup(cleanup_nvmf_tid))) struct libnvmf_tid *tid = NULL((void*)0);
438 int err;
439
440 if (st->mode == CONSUME_ROLE_BASED && !is_dc && !st->connect)
441 return;
442
443 err = build_conn_tid(conn, st->hostnqn, st->hostid, &tid);
444 if (err)
445 goto record_err;
446
447 /* Auto-connect (both modes) enforces exclusion, unlike a single
448 * explicit "nvme connect" (see fabrics_connect()'s exempt-with-note
449 * case).
450 */
451 if (libnvmf_exclusion_match(st->ctx, tid)) {
452 nvme_show_verbose_info("%s: on the exclusion list, skipping",nvme_show_verbose_message("%s: on the exclusion list, skipping"
, libnvmf_config_conn_get_source(conn))
453 libnvmf_config_conn_get_source(conn))nvme_show_verbose_message("%s: on the exclusion list, skipping"
, libnvmf_config_conn_get_source(conn))
;
454 return;
455 }
456
457 err = libnvmf_context_create(st->ctx, hook_decide_retry, hook_connected,
458 hook_already_connected, &hfd, &fctx);
459 if (err)
460 goto record_err;
461
462 err = libnvmf_context_set_connection_from_tid(fctx, tid);
463 if (!err)
464 err = libnvmf_context_apply_params(fctx,
465 libnvmf_config_conn_get_params(conn));
466 if (err)
467 goto record_err;
468
469 if (st->mode == CONSUME_CONNECT_ONLY) {
470 err = libnvmf_connect(st->ctx, fctx);
471 } else if (is_dc) {
472 libnvmf_context_set_discovery_hooks(fctx, hook_discovery_log);
473 libnvmf_context_set_default_max_discovery_retries(fctx,
474 MAX_DISC_RETRIES10);
475 libnvmf_context_set_default_keep_alive_timeout(fctx,
476 NVMF_DEF_DISC_TMO30);
477 libnvmf_context_set_connect(fctx, st->connect);
478 libnvmf_context_set_no_reuse(fctx, st->no_reuse);
479 err = libnvmf_discover(st->ctx, fctx);
480 } else {
481 err = libnvmf_connect(st->ctx, fctx);
482 }
483 if (err == -ENVME_CONNECT_ALREADY)
484 err = 0;
485
486record_err:
487 if (err) {
488 nvme_show_error("%s: %s", libnvmf_config_conn_get_source(conn),nvme_show_message(1, "%s: %s", libnvmf_config_conn_get_source
(conn), libnvme_strerror(-err))
489 libnvme_strerror(-err))nvme_show_message(1, "%s: %s", libnvmf_config_conn_get_source
(conn), libnvme_strerror(-err))
;
490 if (!st->err)
491 st->err = err;
492 }
493}
494
495const char *nvmf_resolve_persistent_arg(
496 struct argconfig_commandline_options *opts, const char *arg)
497{
498 if (!argconfig_parse_seen(opts, "persistent"))
499 return NULL((void*)0);
500
501 return arg ? arg : "auto";
502}
503
504/*
505 * Parse one discovery.conf line -- the same argv-style syntax 'nvme
506 * discover'/'connect-all' accept, reusing NVMF_ARGS so every short and long
507 * form works identically to real usage -- and hand the parsed arguments to
508 * nvme_config_convert_discovery_args(). @line is modified in place (strsep()).
509 *
510 * A blank line, a comment, or one with neither transport nor traddr is
511 * silently skipped (0, nothing added), tolerating a discovery.conf that
512 * mixes real entries with commentary.
513 */
514int nvmf_convert_discovery_line(struct libnvmf_config_emitter *emitter,
515 char *line)
516{
517 struct nvmf_args fa = { 0 };
518 char *argv[MAX_DISC_ARGS32] = { "discovery.conf" };
519 char *ptr, *p = line;
520 int argc = 1;
521 bool_Bool no_reuse = false0;
522 char *persistent_arg = NULL((void*)0);
523
524 NVMF_ARGS(opts, fa,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
525 OPT_STRING_OPTIONAL("persistent", 'p', "no|auto|force",nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
526 &persistent_arg,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
527 "persistent discovery connection mode "nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
528 "(default: no; auto if given bare)"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
529 OPT_FLAG("no-reuse", 0, &no_reuse,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
530 "always create a new connection, never reuse "nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
531 "an existing one"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
532 OPT_FLAG("force", 0, &no_reuse,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
533 "deprecated, see --no-reuse"))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"persistent", 'p', "no|auto|force"
, CFG_STRING, &persistent_arg, 2, "persistent discovery connection mode "
"(default: no; auto if given bare)", 0, }, {"no-reuse", 0, (
(void*)0), CFG_FLAG, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
534
535 if (line[0] == '#' || line[0] == '\n' || line[0] == '\0')
536 return 0;
537
538 fa.tos = -1;
539 fa.ctrl_loss_tmo = NVMF_DEF_CTRL_LOSS_TMO600;
540
541 /*
542 * Split on whitespace only, not '=' -- a glued "--opt=value" token
543 * (e.g. "--persistent=force") must reach argconfig_parse() intact.
544 * getopt_long() parses '=' within a single token natively for
545 * every option shape, so splitting it out here is never required.
546 */
547 while ((ptr = strsep(&p, "\n ")) != NULL((void*)0) && argc < MAX_DISC_ARGS32 - 1)
548 argv[argc++] = ptr;
549 argv[argc] = NULL((void*)0);
550
551 fa.subsysnqn = NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery";
552 if (argconfig_parse(argc, argv, "discovery.conf", opts))
553 return 0;
554
555 if (!fa.transport && !fa.traddr)
556 return 0;
557
558 return nvme_config_convert_discovery_args(emitter, &fa,
559 nvmf_resolve_persistent_arg(opts, persistent_arg));
560}
561
562static int setup_common_context(struct libnvmf_context *fctx,
563 struct nvmf_args *fa)
564{
565 int err;
566
567 err = libnvmf_context_set_connection(fctx,
568 fa->subsysnqn, fa->transport,
569 fa->traddr, fa->trsvcid,
570 fa->host_traddr, fa->host_iface);
571 if (err)
572 return err;
573
574 err = libnvmf_context_set_hostnqn(fctx,
575 fa->hostnqn, fa->hostid);
576 if (err)
577 return err;
578
579 err = libnvmf_context_set_crypto(fctx,
580 fa->hostkey, fa->ctrlkey,
581 fa->keyring, fa->tls_key,
582 fa->tls_key_identity);
583 if (err)
584 return err;
585
586 return set_fabrics_options(fctx, fa);
587}
588
589static int create_common_context(struct libnvme_global_ctx *ctx, struct nvmf_args *fa,
590 void *user_data, struct libnvmf_context **fctxp)
591{
592 struct libnvmf_context *fctx;
593 int err;
594
595 err = libnvmf_context_create(ctx, hook_decide_retry, hook_connected,
596 hook_already_connected, user_data, &fctx);
597 if (err)
598 return err;
599
600 err = setup_common_context(fctx, fa);
601 if (err)
602 goto err;
603
604 *fctxp = fctx;
605
606 return 0;
607
608err:
609 libnvmf_context_free(fctx);
610 return err;
611}
612
613static int create_discovery_context(struct libnvme_global_ctx *ctx,
614 const char *device, struct nvmf_args *fa,
615 void *user_data, struct libnvmf_context **fctxp)
616{
617 struct libnvmf_context *fctx;
618 int err;
619
620 err = create_common_context(ctx, fa, user_data, &fctx);
621 if (err)
622 return err;
623
624 err = libnvmf_context_set_discovery_hooks(fctx, hook_discovery_log);
625 if (err)
626 goto err;
627
628 libnvmf_context_set_default_max_discovery_retries(fctx,
629 MAX_DISC_RETRIES10);
630 libnvmf_context_set_default_keep_alive_timeout(fctx, NVMF_DEF_DISC_TMO30);
631
632 err = libnvmf_context_set_device(fctx, device);
633 if (err)
634 goto err;
635
636 *fctxp = fctx;
637 return 0;
638
639err:
640 libnvmf_context_free(fctx);
641 return err;
642}
643
644static void load_nvme_fabrics_module(void)
645{
646#ifdef NVME_HAVE_LIBKMOD
647 struct kmod_ctx *ctx;
648 struct kmod_module *mod;
649 int err, state;
650 int timeout = 20; /* 2 seconds */
651
652 ctx = kmod_new(NULL((void*)0), NULL((void*)0));
653 if (!ctx)
654 return;
655
656 err = kmod_module_new_from_name(ctx, "nvme-fabrics", &mod);
657 if (err)
658 goto unref;
659
660 state = kmod_module_get_initstate(mod);
661 if (state != KMOD_MODULE_LIVE && state != KMOD_MODULE_BUILTIN) {
662 err = kmod_module_probe_insert_module(mod,
663 KMOD_PROBE_APPLY_BLACKLIST, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
664 if (err)
665 goto mod_unref;
666
667 while (timeout--) {
668 state = kmod_module_get_initstate(mod);
669 if (state == KMOD_MODULE_LIVE)
670 goto mod_unref;
671
672 /* 100 ms */
673 usleep(100 * 1000);
674 }
675 err = -ENOENT2;
676 }
677
678mod_unref:
679 kmod_module_unref(mod);
680unref:
681 kmod_unref(ctx);
682
683 if (err)
684 nvme_show_error("Couldn't load the nvme-fabrics module")nvme_show_message(1, "Couldn't load the nvme-fabrics module");
685#endif
686}
687
688/*
689 * The config-driven half of a bare "connect-all"/"discover": auto-convert
690 * a legacy file if needed, settle host identity once, then discover or
691 * connect every resolved connection in @config_file.
692 */
693static int fabrics_discovery_config(struct libnvme_global_ctx *ctx,
694 char *config_file, const char *hostnqn_arg,
695 const char *hostid_arg, bool_Bool connect, bool_Bool no_reuse,
696 nvme_print_flags_t flags)
697{
698 __cleanup_free__attribute__((cleanup(shr_freep))) char *ini_path = NULL((void*)0);
699 __cleanup_free__attribute__((cleanup(shr_freep))) char *hostnqn = NULL((void*)0);
700 __cleanup_free__attribute__((cleanup(shr_freep))) char *hostid = NULL((void*)0);
701 struct libnvmf_config *cfg;
702 struct consume_state st;
703 bool_Bool is_default_config;
704 int ret;
705
706 /* Custom --config failing is fatal (explicit ask). Default path
707 * failing isn't: boot-time connect-all must keep going.
708 */
709 is_default_config = !strcmp(config_file, PATH_NVMF_INI"/usr/local/etc" "/nvme/nvme-fabrics.conf");
710
711 ret = nvme_config_convert_auto(ctx, config_file, &ini_path);
712 if (ret) {
713 nvme_show_error("auto-conversion failed: %s",nvme_show_message(1, "auto-conversion failed: %s", libnvme_strerror
(-ret))
714 libnvme_strerror(-ret))nvme_show_message(1, "auto-conversion failed: %s", libnvme_strerror
(-ret))
;
715 if (!is_default_config)
716 return ret;
717 }
718 config_file = ini_path;
719
720 ret = libnvmf_host_get_ids(ctx, hostnqn_arg, hostid_arg,
721 &hostnqn, &hostid);
722 if (ret) {
723 nvme_show_error("failed to determine host identity: %s",nvme_show_message(1, "failed to determine host identity: %s",
libnvme_strerror(-ret))
724 libnvme_strerror(-ret))nvme_show_message(1, "failed to determine host identity: %s",
libnvme_strerror(-ret))
;
725 return ret;
726 }
727
728 ret = libnvmf_config_read(ctx, config_file, &cfg);
729 if (ret) {
730 nvme_show_error("failed to read %s: %s", config_file,nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
731 libnvme_strerror(-ret))nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
;
732 return ret;
733 }
734
735 st = (struct consume_state){
736 .ctx = ctx,
737 .mode = CONSUME_ROLE_BASED,
738 .connect = connect,
739 .no_reuse = no_reuse,
740 .flags = flags,
741 .raw = raw,
742 .hostnqn = hostnqn,
743 .hostid = hostid,
744 };
745 libnvmf_config_conn_for_each(cfg, consume_conn, &st);
746 libnvmf_config_free(cfg);
747
748 return st.err;
749}
750
751#define NBFT_SYSFS_PATH"/sys/firmware/acpi/tables" "/sys/firmware/acpi/tables"
752
753/*
754 * A controller's ownership extends to everything done through it, so the
755 * caller's operation may not proceed unless the invoking owner matches
756 * (mirrors disconnect_all_match()'s registry check). No ownerless
757 * exemption -- a mismatched or missing --owner is skipped the same way;
758 * the escape hatch is passing the owner's own identity.
759 *
760 * --no-reuse skips the check entirely: it means the caller will never
761 * reuse an existing controller, so there is nothing to check ownership
762 * against.
763 *
764 * Returns 0 to proceed, 1 to skip, or a negative errno on a registry
765 * read failure.
766 */
767static int check_ctrl_owner(struct libnvme_global_ctx *ctx,
768 struct libnvmf_context *fctx,
769 const char *owner, bool_Bool no_reuse)
770{
771 __cleanup_free__attribute__((cleanup(shr_freep))) char *reg_owner = NULL((void*)0);
772 int ret;
773
774 if (no_reuse)
775 return 0;
776
777 ret = libnvmf_get_owner_from_fctx(ctx, fctx, &reg_owner);
778 if (ret)
779 return ret;
780 if (!reg_owner) /* no owner in registry */
781 return 0;
782
783 if (owner && streq(reg_owner, owner)(strcmp((reg_owner),(owner)) == 0))
784 return 0;
785
786 nvme_show_message(false0,
787 "owned by '%s'; skipping -- owner handles discovery",
788 reg_owner);
789 return 1;
790}
791
792int fabrics_discover(const char *desc, int argc, char **argv, bool_Bool connect)
793{
794 __cleanup_free__attribute__((cleanup(shr_freep))) char *hnqn = NULL((void*)0);
795 __cleanup_free__attribute__((cleanup(shr_freep))) char *hid = NULL((void*)0);
796 char *config_file = PATH_NVMF_INI"/usr/local/etc" "/nvme/nvme-fabrics.conf";
797 nvme_print_flags_t flags;
798 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
799 __cleanup_nvmf_context__attribute__((cleanup(cleanup_nvmf_context))) struct libnvmf_context *fctx = NULL((void*)0);
800 __cleanup_free__attribute__((cleanup(shr_freep))) char *resolved_traddr = NULL((void*)0);
801 int ret;
802 struct nvmf_args fa = { .subsysnqn = NVME_DISC_SUBSYS_NAME"nqn.2014-08.org.nvmexpress.discovery" };
803 char *device = NULL((void*)0);
804 bool_Bool no_reuse = false0;
805 char *persistent_arg = NULL((void*)0);
806 const char *persistent;
807 bool_Bool nbft = false0, nonbft = false0;
808 char *nbft_path = NBFT_SYSFS_PATH"/sys/firmware/acpi/tables";
809 char *owner = NULL((void*)0);
810
811 NVMF_ARGS(opts, fa,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
812 OPT_STRING("device", 'd', "DEV", &device, "use existing discovery controller device"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
813 OPT_FILE("raw", 'r', &raw, "save raw output to file"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
814 OPT_STRING_OPTIONAL("persistent", 'p', "no|auto|force",nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
815 &persistent_arg,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
816 "persistent discovery connection mode "nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
817 "(default: no; auto if given bare)"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
818 OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
819 OPT_FLAG("no-reuse", 0, &no_reuse,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
820 "always create a new connection, never reuse "nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
821 "an existing one"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
822 OPT_FLAG("force", 0, &no_reuse,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
823 "deprecated, see --no-reuse"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
824 OPT_FLAG("nbft", 0, &nbft, "Only look at NBFT tables"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
825 OPT_FLAG("no-nbft", 0, &nonbft, "Do not look at NBFT tables"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
826 OPT_STRING("owner", 0, "NAME", &owner, "record this owner in the registry"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
827 OPT_STRING("nbft-path", 0, "STR", &nbft_path, "user-defined path for NBFT tables"))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &device, 1, "use existing discovery controller device"
, 0, }, {"raw", 'r', "FILE", CFG_STRING, &raw, 1, "save raw output to file"
, 0, }, {"persistent", 'p', "no|auto|force", CFG_STRING, &
persistent_arg, 2, "persistent discovery connection mode " "(default: no; auto if given bare)"
, 0, }, {"config", 'J', "FILE", CFG_STRING, &config_file,
1, nvmf_config_file, 0, }, {"no-reuse", 0, ((void*)0), CFG_FLAG
, &no_reuse, 0, "always create a new connection, never reuse "
"an existing one", 0, }, {"force", 0, ((void*)0), CFG_FLAG, &
no_reuse, 0, "deprecated, see --no-reuse", 0, }, {"nbft", 0, (
(void*)0), CFG_FLAG, &nbft, 0, "Only look at NBFT tables"
, 0, }, {"no-nbft", 0, ((void*)0), CFG_FLAG, &nonbft, 0, "Do not look at NBFT tables"
, 0, }, {"owner", 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"nbft-path", 0, "STR", CFG_STRING, &nbft_path, 1
, "user-defined path for NBFT tables", 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
828
829 nvmf_default_args(&fa);
830
831 ret = parse_args(argc, argv, desc, opts);
832 if (ret)
833 return ret;
834
835 load_nvme_fabrics_module();
836
837 ret = validate_output_format(nvme_args.output_format, &flags);
838 if (ret < 0) {
839 nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format");
840 return ret;
841 }
842
843 persistent = nvmf_resolve_persistent_arg(opts, persistent_arg);
844
845 if (!strcmp(config_file, "none"))
846 config_file = NULL((void*)0);
847
848 ret = nvme_create_global_ctx_hostnqn(&ctx,
849 fa.hostnqn, fa.hostid, &hnqn, &hid);
850 if (ret)
851 return ret;
852 fa.hostnqn = hnqn;
853 fa.hostid = hid;
854
855 /*
856 * --nbft defaults the owner to "nbft" so legacy boot scripts that
857 * call "connect-all --nbft" record ownership unchanged. An explicit
858 * --owner overrides that default.
859 */
860 if (owner || nbft) {
861 ret = libnvme_set_owner(ctx, owner ? owner : "nbft");
862 if (ret) {
863 nvme_show_error("failed to set owner: %s",nvme_show_message(1, "failed to set owner: %s", libnvme_strerror
(-ret))
864 libnvme_strerror(-ret))nvme_show_message(1, "failed to set owner: %s", libnvme_strerror
(-ret))
;
865 return ret;
866 }
867 }
868
869 libnvme_skip_namespaces(ctx);
870 ret = libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0));
871 if (ret < 0) {
872 nvme_show_error("Failed to scan topology: %s",nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
873 libnvme_strerror(-ret))nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
;
874 return ret;
875 }
876
877 if (device) {
878 if (!strcmp(device, "none"))
879 device = NULL((void*)0);
880 else if (!strncmp(device, "/dev/", 5))
881 device += 5;
882 }
883
884 /* Only traddr may be a hostname; host_traddr never is. */
885 ret = nvmf_resolve_addr(fa.transport, fa.traddr, &resolved_traddr);
886 if (ret)
887 return ret;
888 fa.traddr = resolved_traddr;
889
890 struct hook_fabrics_data dld = {
891 .flags = flags,
892 .raw = raw,
893 };
894
895 ret = create_discovery_context(ctx, device, &fa, &dld, &fctx);
896 if (ret)
897 return ret;
898
899 libnvmf_context_set_connect(fctx, connect);
900 libnvmf_context_set_no_reuse(fctx, no_reuse);
901
902 if (persistent && libnvmf_context_set_persistent(fctx, persistent)) {
903 nvme_show_error(nvme_show_message(1, "invalid --persistent value '%s' (expected no, auto, or force)"
, persistent)
904 "invalid --persistent value '%s' (expected no, auto, or force)",nvme_show_message(1, "invalid --persistent value '%s' (expected no, auto, or force)"
, persistent)
905 persistent)nvme_show_message(1, "invalid --persistent value '%s' (expected no, auto, or force)"
, persistent)
;
906 return -EINVAL22;
907 }
908
909 if (!device && !fa.transport && !fa.traddr) {
910 if (!nonbft) {
911 if (!nbft_path) {
912 nvme_show_error("no nbft_path set")nvme_show_message(1, "no nbft_path set");
913 return -EINVAL22;
914 }
915 libnvmf_context_set_nbft_path(fctx, nbft_path);
916 ret = libnvmf_discover_nbft(ctx, fctx);
917 }
918 if (!nbft && config_file)
919 ret = fabrics_discovery_config(ctx, config_file,
920 fa.hostnqn, fa.hostid, connect, no_reuse,
921 flags);
922 } else {
923 ret = check_ctrl_owner(ctx, fctx,
924 owner ? owner : (nbft ? "nbft" : NULL((void*)0)),
925 no_reuse);
926 if (ret < 0) {
927 nvme_show_error("failed to check owner: %s",nvme_show_message(1, "failed to check owner: %s", libnvme_strerror
(-ret))
928 libnvme_strerror(-ret))nvme_show_message(1, "failed to check owner: %s", libnvme_strerror
(-ret))
;
929 return ret;
930 }
931 if (ret)
932 return 0;
933
934 ret = libnvmf_discover(ctx, fctx);
935 }
936
937 return ret;
938}
939
940/*
941 * The config-driven half of "nvme connect -J": auto-convert a legacy file
942 * if needed, settle host identity once, then connect every resolved
943 * connection in @config_file.
944 */
945static int fabrics_connect_config(struct libnvme_global_ctx *ctx,
946 char *config_file, const char *hostnqn_arg,
947 const char *hostid_arg, nvme_print_flags_t flags)
948{
949 __cleanup_free__attribute__((cleanup(shr_freep))) char *ini_path = NULL((void*)0);
950 __cleanup_free__attribute__((cleanup(shr_freep))) char *hostnqn = NULL((void*)0);
951 __cleanup_free__attribute__((cleanup(shr_freep))) char *hostid = NULL((void*)0);
952 struct libnvmf_config *cfg;
953 struct consume_state st;
954 int ret;
955
956 /* Always explicit here (no implicit default read), so a
957 * conversion failure is always fatal.
958 */
959 ret = nvme_config_convert_auto(ctx, config_file, &ini_path);
960 if (ret) {
961 nvme_show_error("auto-conversion failed: %s",nvme_show_message(1, "auto-conversion failed: %s", libnvme_strerror
(-ret))
962 libnvme_strerror(-ret))nvme_show_message(1, "auto-conversion failed: %s", libnvme_strerror
(-ret))
;
963 return ret;
964 }
965 config_file = ini_path;
966
967 ret = libnvmf_host_get_ids(ctx, hostnqn_arg, hostid_arg,
968 &hostnqn, &hostid);
969 if (ret) {
970 nvme_show_error("failed to determine host identity: %s",nvme_show_message(1, "failed to determine host identity: %s",
libnvme_strerror(-ret))
971 libnvme_strerror(-ret))nvme_show_message(1, "failed to determine host identity: %s",
libnvme_strerror(-ret))
;
972 return ret;
973 }
974
975 ret = libnvmf_config_read(ctx, config_file, &cfg);
976 if (ret) {
977 nvme_show_error("failed to read %s: %s", config_file,nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
978 libnvme_strerror(-ret))nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
;
979 return ret;
980 }
981
982 st = (struct consume_state){
983 .ctx = ctx,
984 .mode = CONSUME_CONNECT_ONLY,
985 .flags = flags,
986 .raw = raw,
987 .hostnqn = hostnqn,
988 .hostid = hostid,
989 };
990 libnvmf_config_conn_for_each(cfg, consume_conn, &st);
991 libnvmf_config_free(cfg);
992
993 return st.err;
994}
995
996int fabrics_connect(const char *desc, int argc, char **argv)
997{
998 __cleanup_free__attribute__((cleanup(shr_freep))) char *hnqn = NULL((void*)0);
999 __cleanup_free__attribute__((cleanup(shr_freep))) char *hid = NULL((void*)0);
1000 char *config_file = NULL((void*)0);
1001 char *owner = NULL((void*)0);
1002 char *devid_file = NULL((void*)0);
1003 bool_Bool idempotent = false0;
1004 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1005 __cleanup_nvmf_context__attribute__((cleanup(cleanup_nvmf_context))) struct libnvmf_context *fctx = NULL((void*)0);
1006 __cleanup_nvme_ctrl__attribute__((cleanup(cleanup_nvme_ctrl))) struct libnvme_ctrl *c = NULL((void*)0);
1007 __cleanup_free__attribute__((cleanup(shr_freep))) char *resolved_traddr = NULL((void*)0);
1008 int ret;
1009 nvme_print_flags_t flags;
1010 struct nvmf_args fa = { 0 };
1011
1012 NVMF_ARGS(opts, fa,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1013 OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1014 OPT_STRING("owner", 0, "NAME", &owner, "record this owner in the registry"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1015 OPT_STRING("devid-file", 0, "FILE", &devid_file,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1016 "write connected device name to FILE"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1017 OPT_FLAG("idempotent", 0, &idempotent,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1018 "exit 0 if already connected"))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"config", 'J', "FILE"
, CFG_STRING, &config_file, 1, nvmf_config_file, 0, }, {"owner"
, 0, "NAME", CFG_STRING, &owner, 1, "record this owner in the registry"
, 0, }, {"devid-file", 0, "FILE", CFG_STRING, &devid_file
, 1, "write connected device name to FILE", 0, }, {"idempotent"
, 0, ((void*)0), CFG_FLAG, &idempotent, 0, "exit 0 if already connected"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
1019
1020 nvmf_default_args(&fa);
1021
1022 ret = parse_args(argc, argv, desc, opts);
1023 if (ret)
1024 return ret;
1025
1026 load_nvme_fabrics_module();
1027
1028 ret = validate_output_format(nvme_args.output_format, &flags);
1029 if (ret < 0) {
1030 nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format");
1031 return ret;
1032 }
1033
1034 if (config_file && !strcmp(config_file, "none"))
1035 config_file = NULL((void*)0);
1036
1037 if (config_file)
1038 goto do_connect;
1039
1040 if (!fa.subsysnqn) {
1041 nvme_show_error(nvme_show_message(1, "required argument [--nqn | -n] not specified\n"
)
1042 "required argument [--nqn | -n] not specified\n")nvme_show_message(1, "required argument [--nqn | -n] not specified\n"
)
;
1043 return -EINVAL22;
1044 }
1045
1046 if (!fa.transport) {
1047 nvme_show_error(nvme_show_message(1, "required argument [--transport | -t] not specified\n"
)
1048 "required argument [--transport | -t] not specified\n")nvme_show_message(1, "required argument [--transport | -t] not specified\n"
)
;
1049 return -EINVAL22;
1050 }
1051
1052 if (strcmp(fa.transport, "loop")) {
1053 if (!fa.traddr) {
1054 nvme_show_error(nvme_show_message(1, "required argument [--traddr | -a] not specified for transport %s\n"
, fa.transport)
1055 "required argument [--traddr | -a] not specified for transport %s\n",nvme_show_message(1, "required argument [--traddr | -a] not specified for transport %s\n"
, fa.transport)
1056 fa.transport)nvme_show_message(1, "required argument [--traddr | -a] not specified for transport %s\n"
, fa.transport)
;
1057 return -EINVAL22;
1058 }
1059 }
1060
1061 /* Only traddr may be a hostname; host_traddr never is. */
1062 ret = nvmf_resolve_addr(fa.transport, fa.traddr, &resolved_traddr);
1063 if (ret)
1064 return ret;
1065 fa.traddr = resolved_traddr;
1066
1067do_connect:
1068 ret = nvme_create_global_ctx_hostnqn(&ctx,
1069 fa.hostnqn, fa.hostid, &hnqn, &hid);
1070 if (ret)
1071 return ret;
1072 fa.hostnqn = hnqn;
1073 fa.hostid = hid;
1074
1075 if (owner) {
1076 ret = libnvme_set_owner(ctx, owner);
1077 if (ret) {
1078 nvme_show_error("failed to set owner: %s",nvme_show_message(1, "failed to set owner: %s", libnvme_strerror
(-ret))
1079 libnvme_strerror(-ret))nvme_show_message(1, "failed to set owner: %s", libnvme_strerror
(-ret))
;
1080 return ret;
1081 }
1082 }
1083
1084 libnvme_skip_namespaces(ctx);
1085 ret = libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0));
1086 if (ret < 0) {
1087 nvme_show_error("Failed to scan topology: %s",nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
1088 libnvme_strerror(-ret))nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
;
1089 return ret;
1090 }
1091
1092 if (config_file)
1093 return fabrics_connect_config(ctx, config_file, fa.hostnqn,
1094 fa.hostid, flags);
1095
1096 struct hook_fabrics_data hfd = {
1097 .flags = flags,
1098 .raw = raw,
1099 };
1100 ret = create_common_context(ctx, &fa, &hfd, &fctx);
1101 if (ret)
1102 return ret;
1103
1104 if (devid_file)
1105 libnvmf_context_set_devid_file(fctx, devid_file);
1106
1107 /*
1108 * The exclusion list governs auto-connecting orchestrators, not an
1109 * explicit "nvme connect", so we never block it here. But under
1110 * --verbose, note when the target matches an exclusion entry so the
1111 * operator knows they are overriding their own opt-out.
1112 */
1113 if (nvme_args.verbose) {
1114 struct libnvmf_tid *tid;
1115
1116 libnvmf_tid_from_fields(fa.transport, fa.traddr,
1117 fa.trsvcid, fa.subsysnqn,
1118 fa.host_traddr, fa.host_iface,
1119 fa.hostnqn, fa.hostid, &tid);
1120 if (tid && libnvmf_exclusion_match(ctx, tid))
1121 nvme_show_error(nvme_show_message(1, "Note: %s is on the exclusion list; connecting anyway\n"
, fa.subsysnqn ? fa.subsysnqn : "this controller")
1122 "Note: %s is on the exclusion list; connecting anyway\n",nvme_show_message(1, "Note: %s is on the exclusion list; connecting anyway\n"
, fa.subsysnqn ? fa.subsysnqn : "this controller")
1123 fa.subsysnqn ? fa.subsysnqn : "this controller")nvme_show_message(1, "Note: %s is on the exclusion list; connecting anyway\n"
, fa.subsysnqn ? fa.subsysnqn : "this controller")
;
1124 libnvmf_tid_free(tid);
1125 }
1126
1127 ret = libnvmf_connect(ctx, fctx);
1128 if (ret == -ENVME_CONNECT_ALREADY && idempotent)
1129 ret = 0;
1130 if (ret) {
1131 /*
1132 * hook_already_connected() already reported the specific
1133 * reason; the generic message here would just overwrite it.
1134 */
1135 if (ret != -ENVME_CONNECT_ALREADY)
1136 nvme_show_error("failed to connect: %s",nvme_show_message(1, "failed to connect: %s", libnvme_strerror
(-ret))
1137 libnvme_strerror(-ret))nvme_show_message(1, "failed to connect: %s", libnvme_strerror
(-ret))
;
1138 return ret;
1139 }
1140
1141 return 0;
1142}
1143
1144static struct libnvme_ctrl *lookup_nvme_ctrl(struct libnvme_global_ctx *ctx,
1145 const char *name)
1146{
1147 struct libnvme_host *h;
1148 struct libnvme_subsystem *s;
1149 struct libnvme_ctrl *c;
1150
1151 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1152 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1153 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
1154 if (!strcmp(libnvme_ctrl_get_name(c), name))
1155 return c;
1156 }
1157 }
1158 }
1159 return NULL((void*)0);
1160}
1161
1162static bool_Bool opt_matches(const char *want, const char *have)
1163{
1164 return !want || (have && !strcmp(want, have));
1165}
1166
1167static bool_Bool nvmf_ctrl_matches_args(struct libnvme_host *h, struct libnvme_ctrl *c,
1168 const struct nvmf_args *fa)
1169{
1170 return opt_matches(fa->transport, libnvme_ctrl_get_transport(c)) &&
1171 opt_matches(fa->subsysnqn, libnvme_ctrl_get_subsysnqn(c)) &&
1172 opt_matches(fa->traddr, libnvme_ctrl_get_traddr(c)) &&
1173 opt_matches(fa->trsvcid, libnvme_ctrl_get_trsvcid(c)) &&
1174 opt_matches(fa->host_traddr, libnvme_ctrl_get_host_traddr(c)) &&
1175 opt_matches(fa->host_iface, libnvme_ctrl_get_host_iface(c)) &&
1176 opt_matches(fa->hostnqn, libnvme_host_get_hostnqn(h)) &&
1177 opt_matches(fa->hostid, libnvme_host_get_hostid(h));
1178}
1179
1180static int nvmf_disconnect_nqn(struct libnvme_global_ctx *ctx, char *nqn)
1181{
1182 int i = 0;
1183 char *n = nqn;
1184 char *p;
1185 struct libnvme_host *h;
1186 struct libnvme_subsystem *s;
1187 struct libnvme_ctrl *c;
1188
1189 while ((p = strsep(&n, ",")) != NULL((void*)0)) {
1190 if (!strlen(p))
1191 continue;
1192 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1193 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1194 if (strcmp(libnvme_subsystem_get_subsysnqn(s), p))
1195 continue;
1196 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
1197 if (!libnvmf_disconnect_ctrl(c))
1198 i++;
1199 }
1200 }
1201 }
1202 }
1203 nvme_show_verbose_result("NQN:%s disconnected %d controller(s)", nqn, i)nvme_show_verbose_message("NQN:%s disconnected %d controller(s)"
, nqn, i)
;
1204
1205 return 0;
1206}
1207
1208static int disconnect_validate_args(bool_Bool has_device, bool_Bool has_subsysnqn,
1209 bool_Bool match_args)
1210{
1211 if (has_device && (has_subsysnqn || match_args)) {
1212 nvme_show_error(nvme_show_message(1, "Device name [--device | -d] cannot be combined with other identifying options\n"
)
1213 "Device name [--device | -d] cannot be combined with other identifying options\n")nvme_show_message(1, "Device name [--device | -d] cannot be combined with other identifying options\n"
)
;
1214 return -EINVAL22;
1215 }
1216
1217 if (!has_device && !has_subsysnqn && match_args) {
1218 nvme_show_error(nvme_show_message(1, "Fabrics identifying options require an NQN [--nqn | -n]\n"
)
1219 "Fabrics identifying options require an NQN [--nqn | -n]\n")nvme_show_message(1, "Fabrics identifying options require an NQN [--nqn | -n]\n"
)
;
1220 return -EINVAL22;
1221 }
1222
1223 if (!has_device && !has_subsysnqn) {
1224 nvme_show_error(nvme_show_message(1, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"
)
1225 "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n")nvme_show_message(1, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"
)
;
1226 return -EINVAL22;
1227 }
1228
1229 return 0;
1230}
1231
1232static int add_exclusion_ctrl(struct libnvme_global_ctx *ctx,
1233 struct libnvme_ctrl *c)
1234{
1235 int err;
1236
1237 /*
1238 * Write exclusion entry before disconnecting so that
1239 * orchestrators see the exclusion in place before the
1240 * device removal event fires.
1241 */
1242 err = libnvmf_exclusion_add_ctrl(ctx, NULL((void*)0), c);
1243 if (!err)
1244 return 0;
1245
1246 nvme_show_error("Warning: failed to write exclusion entry: %s\n",nvme_show_message(1, "Warning: failed to write exclusion entry: %s\n"
, libnvme_strerror(-err))
1247 libnvme_strerror(-err))nvme_show_message(1, "Warning: failed to write exclusion entry: %s\n"
, libnvme_strerror(-err))
;
1248
1249 return err;
1250}
1251
1252static int add_exclusion_subsysnqn(struct libnvme_global_ctx *ctx,
1253 const char *subsysnqn)
1254{
1255 int err;
1256
1257 /*
1258 * Write exclusion entry before disconnecting so that
1259 * orchestrators see the exclusion in place before the
1260 * device removal event fires.
1261 */
1262 err = libnvmf_exclusion_add_subsysnqn(ctx, NULL((void*)0), subsysnqn);
1263 if (!err)
1264 return 0;
1265
1266 nvme_show_error("Warning: failed to write exclusion entry: %s\n",nvme_show_message(1, "Warning: failed to write exclusion entry: %s\n"
, libnvme_strerror(-err))
1267 libnvme_strerror(-err))nvme_show_message(1, "Warning: failed to write exclusion entry: %s\n"
, libnvme_strerror(-err))
;
1268
1269 return err;
1270}
1271
1272static int disconnect_by_device(struct libnvme_global_ctx *ctx,
1273 char *device, bool_Bool exclude)
1274{
1275 struct libnvme_ctrl *c;
1276 char *p;
1277 int err;
1278
1279 while ((p = strsep(&device, ",")) != NULL((void*)0)) {
1280 if (!strncmp(p, "/dev/", 5))
1281 p += 5;
1282
1283 c = lookup_nvme_ctrl(ctx, p);
1284 if (!c) {
1285 nvme_show_error("Did not find device %s\n", p)nvme_show_message(1, "Did not find device %s\n", p);
1286 return -ENODEV19;
1287 }
1288
1289 if (exclude)
1290 add_exclusion_ctrl(ctx, c);
1291
1292 err = libnvmf_disconnect_ctrl(c);
1293 if (err)
1294 nvme_show_error("Failed to disconnect %s: %s\n",nvme_show_message(1, "Failed to disconnect %s: %s\n", p, libnvme_strerror
(-err))
1295 p, libnvme_strerror(-err))nvme_show_message(1, "Failed to disconnect %s: %s\n", p, libnvme_strerror
(-err))
;
1296 }
1297
1298 return 0;
1299}
1300
1301static int disconnect_by_args(struct libnvme_global_ctx *ctx,
1302 const struct nvmf_args *fa, bool_Bool exclude)
1303{
1304 struct libnvme_host *h;
1305 struct libnvme_subsystem *s;
1306 struct libnvme_ctrl *c;
1307 int err, i = 0;
1308
1309 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1310 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1311 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
1312 if (!nvmf_ctrl_matches_args(h, c, fa))
1313 continue;
1314
1315 if (exclude)
1316 add_exclusion_ctrl(ctx, c);
1317
1318 err = libnvmf_disconnect_ctrl(c);
1319 if (err)
1320 nvme_show_error("Failed to disconnect %s: %s\n",nvme_show_message(1, "Failed to disconnect %s: %s\n", libnvme_ctrl_get_name
(c), libnvme_strerror(-err))
1321 libnvme_ctrl_get_name(c),nvme_show_message(1, "Failed to disconnect %s: %s\n", libnvme_ctrl_get_name
(c), libnvme_strerror(-err))
1322 libnvme_strerror(-err))nvme_show_message(1, "Failed to disconnect %s: %s\n", libnvme_ctrl_get_name
(c), libnvme_strerror(-err))
;
1323 else
1324 i++;
1325 }
1326 }
1327 }
1328
1329 if (!i)
1330 nvme_show_error("Did not find a matching controller\n")nvme_show_message(1, "Did not find a matching controller\n");
1331
1332 nvme_show_verbose_result("disconnected %d controller(s)", i)nvme_show_verbose_message("disconnected %d controller(s)", i);
1333
1334 return 0;
1335}
1336
1337static int disconnect_by_nqn(struct libnvme_global_ctx *ctx, const char *nqn,
1338 bool_Bool exclude)
1339{
1340 __cleanup_free__attribute__((cleanup(shr_freep))) char *n = NULL((void*)0);
1341
1342 n = strdup(nqn);
1343 if (!n)
1344 return -ENOMEM12;
1345
1346 if (exclude) {
1347 __cleanup_free__attribute__((cleanup(shr_freep))) char *excl = strdup(nqn);
1348 char *t, *p;
1349
1350 if (!excl)
1351 return -ENOMEM12;
1352
1353 t = excl;
1354 while ((p = strsep(&t, ",")) != NULL((void*)0)) {
1355 if (!*p)
1356 continue;
1357
1358 add_exclusion_subsysnqn(ctx, p);
1359 }
1360 }
1361
1362 return nvmf_disconnect_nqn(ctx, n);
1363}
1364
1365int fabrics_disconnect(const char *desc, int argc, char **argv)
1366{
1367 const char *device = "nvme device handle";
1368 const char *exclude_help = "write exclusion entry before disconnecting";
1369
1370 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1371 __cleanup_free__attribute__((cleanup(shr_freep))) char *resolved_traddr = NULL((void*)0);
1372 struct nvmf_args fa = { 0 };
1373 bool_Bool match_args;
1374 int err;
1375
1376 struct config {
1377 char *device;
1378 bool_Bool exclude;
1379 };
1380
1381 struct config cfg = { 0 };
1382
1383 NVMF_ARGS(opts, fa,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &cfg.device, 1, device, 0, }, {"exclude", 'x'
, ((void*)0), CFG_FLAG, &cfg.exclude, 0, exclude_help, 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, }, {"quiet"
, 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1384 OPT_STRING("device", 'd', "DEV", &cfg.device, device),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &cfg.device, 1, device, 0, }, {"exclude", 'x'
, ((void*)0), CFG_FLAG, &cfg.exclude, 0, exclude_help, 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, }, {"quiet"
, 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1385 OPT_FLAG("exclude", 'x', &cfg.exclude, exclude_help))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &fa.transport
, 1, "transport type", 0, }, {"nqn", 'n', "STR", CFG_STRING, &
fa.subsysnqn, 1, "subsystem nqn", 0, }, {"traddr", 'a', "STR"
, CFG_STRING, &fa.traddr, 1, "transport address", 0, }, {
"trsvcid", 's', "STR", CFG_STRING, &fa.trsvcid, 1, "transport service id (e.g. IP port)"
, 0, }, {"host-traddr", 'w', "STR", CFG_STRING, &fa.host_traddr
, 1, "host traddr (e.g. FC WWN's)", 0, }, {"host-iface", 'f',
"STR", CFG_STRING, &fa.host_iface, 1, "host interface (for tcp transport)"
, 0, }, {"hostnqn", 'q', "STR", CFG_STRING, &fa.hostnqn, 1
, "user-defined hostnqn", 0, }, {"hostid", 'I', "STR", CFG_STRING
, &fa.hostid, 1, "user-defined hostid (if default not used)"
, 0, }, {"kxchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, }
, {"kxchap-ctrl-secret", 'C', "STR", CFG_STRING, &fa.ctrlkey
, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, }, {"dhchap-secret", 'S', "STR", CFG_STRING, &fa.hostkey
, 1, "user-defined kxchap secret (if default not used)", 0, (
(void*)0), 1}, {"dhchap-ctrl-secret", 'C', "STR", CFG_STRING,
&fa.ctrlkey, 1, "user-defined kxchap controller secret (for bi-directional authentication)"
, 0, ((void*)0), 1}, {"keyring", 0, "STR", CFG_STRING, &fa
.keyring, 1, "Keyring for TLS key lookup (key id or keyring name)"
, 0, }, {"tls-key", 0, "STR", CFG_STRING, &fa.tls_key, 1,
"TLS key to use (key id or key in interchange format)", 0, }
, {"tls-key-identity", 0, "STR", CFG_STRING, &fa.tls_key_identity
, 1, "TLS key identity", 0, }, {"nr-io-queues", 'i', "NUM", CFG_INT
, &fa.nr_io_queues, 1, "number of io queues to use (default is core count)"
, 0, }, {"nr-write-queues", 'W', "NUM", CFG_INT, &fa.nr_write_queues
, 1, "number of write queues to use (default 0)", 0, }, {"nr-poll-queues"
, 'P', "NUM", CFG_INT, &fa.nr_poll_queues, 1, "number of poll queues to use (default 0)"
, 0, }, {"queue-size", 'Q', "NUM", CFG_INT, &fa.queue_size
, 1, "number of io queue elements to use (default 128)", 0, }
, {"keep-alive-tmo", 'k', "NUM", CFG_INT, &fa.keep_alive_tmo
, 1, "keep alive timeout period in seconds", 0, }, {"reconnect-delay"
, 'c', "NUM", CFG_INT, &fa.reconnect_delay, 1, "reconnect timeout period in seconds"
, 0, }, {"ctrl-loss-tmo", 'l', "NUM", CFG_INT, &fa.ctrl_loss_tmo
, 1, "controller loss timeout period in seconds", 0, }, {"fast-io-fail-tmo"
, 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo, 1, "fast I/O fail timeout (default off)"
, 0, }, {"fast_io_fail_tmo", 'F', "NUM", CFG_INT, &fa.fast_io_fail_tmo
, 1, "fast I/O fail timeout (default off)", 0, ((void*)0), 1}
, {"tos", 'T', "NUM", CFG_INT, &fa.tos, 1, "type of service"
, 0, }, {"tls_key", 0, "NUM", CFG_INT, &fa.tls_key_id, 1,
"TLS key to use (key id)", 0, }, {"duplicate-connect", 'D', (
(void*)0), CFG_FLAG, &fa.duplicate_connect, 0, "allow duplicate connections between same transport host and subsystem port"
, 0, }, {"disable-sqflow", 0, ((void*)0), CFG_FLAG, &fa.disable_sqflow
, 0, "disable controller sq flow control (default false)", 0,
}, {"hdr-digest", 'g', ((void*)0), CFG_FLAG, &fa.hdr_digest
, 0, "enable transport protocol header digest (TCP transport)"
, 0, }, {"data-digest", 'G', ((void*)0), CFG_FLAG, &fa.data_digest
, 0, "enable transport protocol data digest (TCP transport)",
0, }, {"tls", 0, ((void*)0), CFG_FLAG, &fa.tls, 0, "enable TLS"
, 0, }, {"concat", 0, ((void*)0), CFG_FLAG, &fa.concat, 0
, "enable secure concatenation", 0, }, {"device", 'd', "DEV",
CFG_STRING, &cfg.device, 1, device, 0, }, {"exclude", 'x'
, ((void*)0), CFG_FLAG, &cfg.exclude, 0, exclude_help, 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, }, {"quiet"
, 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
1386
1387 nvmf_default_args(&fa);
1388
1389 err = parse_args(argc, argv, desc, opts);
1390 if (err)
1
Assuming 'err' is 0
1391 return err;
1392
1393 /*
1394 * Any of the "connect"-style options beyond bare --nqn narrow the
1395 * lookup to a specific controller instead of a whole subsystem.
1396 */
1397 match_args = fa.transport || fa.traddr || fa.trsvcid ||
2
Assuming field 'transport' is null
3
Assuming field 'traddr' is non-null
1398 fa.host_traddr || fa.host_iface || fa.hostnqn || fa.hostid;
1399
1400 err = disconnect_validate_args(!!cfg.device,
1401 !!fa.subsysnqn, match_args);
4
Assuming field 'subsysnqn' is non-null
1402 if (err
4.1
'err' is 0
)
5
Taking false branch
1403 return err;
1404
1405 err = nvmf_resolve_addr(fa.transport, fa.traddr, &resolved_traddr);
6
Calling 'nvmf_resolve_addr'
11
Returned allocated memory via 3rd parameter
1406 if (err
11.1
'err' is 0
)
12
Taking false branch
1407 return err;
1408 fa.traddr = resolved_traddr;
1409
1410 err = nvme_create_global_ctx_hostnqn(&ctx,
1411 fa.hostnqn, fa.hostid, NULL((void*)0), NULL((void*)0));
1412 if (err)
13
Assuming 'err' is not equal to 0
14
Taking true branch
1413 return err;
15
Potential leak of memory pointed to by 'fa.traddr'
1414
1415 libnvme_skip_namespaces(ctx);
1416 err = libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0));
1417 if (err < 0) {
1418 /*
1419 * Do not report an error when the modules are not
1420 * loaded, this allows the user to unconditionally call
1421 * disconnect.
1422 */
1423 if (err == -ENOENT2)
1424 return 0;
1425
1426 nvme_show_error("Failed to scan topology: %s",nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-err))
1427 libnvme_strerror(-err))nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-err))
;
1428 return err;
1429 }
1430
1431 if (cfg.device)
1432 return disconnect_by_device(ctx, cfg.device, cfg.exclude);
1433
1434 if (match_args)
1435 return disconnect_by_args(ctx, &fa, cfg.exclude);
1436
1437 return disconnect_by_nqn(ctx, fa.subsysnqn, cfg.exclude);
1438}
1439
1440/* disconnect-all policy: should controller @c be torn down? */
1441static bool_Bool disconnect_all_match(struct libnvme_global_ctx *ctx,
1442 struct libnvme_ctrl *c, const char *transport,
1443 const char *owner, bool_Bool force)
1444{
1445 if (transport && strcmp(transport, libnvme_ctrl_get_transport(c)))
1446 return false0;
1447 if (!libnvme_ctrl_is_transport_fabric(c))
1448 return false0;
1449 if (force)
1450 return true1;
1451
1452 /*
1453 * attr_equal() returns 0 only on an exact match; a read error (<0)
1454 * compares as "not a match", so we never disconnect on error.
1455 */
1456 return libnvmf_registry_attr_equal(ctx, libnvme_ctrl_get_name(c),
1457 "owner", owner) == 0;
1458}
1459
1460int fabrics_disconnect_all(const char *desc, int argc, char **argv)
1461{
1462 const char *owner_help = "disconnect only controllers owned by NAME";
1463 const char *force_help = "disconnect all controllers regardless of ownership";
1464 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1465 struct libnvme_host *h;
1466 struct libnvme_subsystem *s;
1467 struct libnvme_ctrl *c;
1468 int ret;
1469
1470 struct config {
1471 char *transport;
1472 char *owner;
1473 bool_Bool force;
1474 };
1475
1476 struct config cfg = { 0 };
1477
1478 NVME_ARGS(opts,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &cfg.transport
, 1, "transport type", 0, }, {"owner", 0, "NAME", CFG_STRING,
&cfg.owner, 1, owner_help, 0, }, {"force", 0, ((void*)0)
, CFG_FLAG, &cfg.force, 0, force_help, 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1479 OPT_STRING("transport", 't', "STR", &cfg.transport, DESC_NVMF_TPORT),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &cfg.transport
, 1, "transport type", 0, }, {"owner", 0, "NAME", CFG_STRING,
&cfg.owner, 1, owner_help, 0, }, {"force", 0, ((void*)0)
, CFG_FLAG, &cfg.force, 0, force_help, 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1480 OPT_STRING("owner", 0, "NAME", &cfg.owner, owner_help),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &cfg.transport
, 1, "transport type", 0, }, {"owner", 0, "NAME", CFG_STRING,
&cfg.owner, 1, owner_help, 0, }, {"force", 0, ((void*)0)
, CFG_FLAG, &cfg.force, 0, force_help, 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1481 OPT_FLAG("force", 0, &cfg.force, force_help))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"transport", 't', "STR", CFG_STRING, &cfg.transport
, 1, "transport type", 0, }, {"owner", 0, "NAME", CFG_STRING,
&cfg.owner, 1, owner_help, 0, }, {"force", 0, ((void*)0)
, CFG_FLAG, &cfg.force, 0, force_help, 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, }, {"quiet", 0, (
(void*)0), CFG_FLAG, &nvme_args.quiet, 0, "suppress informational output"
, 0, }, {"output-format", 'o', "FMT", CFG_STRING, &nvme_args
.output_format, 1, "Output format: normal|json|binary", 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
1482
1483 ret = parse_args(argc, argv, desc, opts);
1484 if (ret)
1485 return ret;
1486
1487 if (cfg.force && cfg.owner) {
1488 nvme_show_error("--force and --owner are mutually exclusive")nvme_show_message(1, "--force and --owner are mutually exclusive"
)
;
1489 return -EINVAL22;
1490 }
1491
1492 if ((cfg.force || cfg.owner) && isatty(STDIN_FILENO0)) {
1493 char ans[8] = { 0 };
1494
1495 if (cfg.force)
1496 fprintf(stderrstderr,
1497 "WARNING: --force disconnects all NVMeoF controllers\n"
1498 "regardless of ownership. Type 'yes' to confirm: ");
1499 else
1500 fprintf(stderrstderr,
1501 "WARNING: --owner disconnects all NVMeoF controllers\n"
1502 "owned by '%s'. Type 'yes' to confirm: ",
1503 cfg.owner);
1504 if (!fgets(ans, sizeof(ans), stdinstdin)) {
1505 nvme_show_error("Aborted.")nvme_show_message(1, "Aborted.");
1506 return -EINVAL22;
1507 }
1508 ans[strcspn(ans, "\n")] = '\0';
1509 if (strcmp(ans, "yes") != 0) {
1510 nvme_show_error("Aborted.")nvme_show_message(1, "Aborted.");
1511 return -EINVAL22;
1512 }
1513 }
1514
1515 ret = nvme_create_global_ctx(&ctx);
1516 if (ret)
1517 return ret;
1518
1519 libnvme_skip_namespaces(ctx);
1520 ret = libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0));
1521 if (ret < 0) {
1522 /*
1523 * Do not report an error when the modules are not
1524 * loaded, this allows the user to unconditionally call
1525 * disconnect.
1526 */
1527 if (ret == -ENOENT2)
1528 return 0;
1529
1530 nvme_show_error("Failed to scan topology: %s",nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
1531 libnvme_strerror(-ret))nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
;
1532 return ret;
1533 }
1534
1535 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1536 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1537 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
{
1538 if (!disconnect_all_match(ctx, c, cfg.transport,
1539 cfg.owner, cfg.force))
1540 continue;
1541 if (libnvmf_disconnect_ctrl(c))
1542 nvme_show_error(nvme_show_message(1, "failed to disconnect %s\n", libnvme_ctrl_get_name
(c))
1543 "failed to disconnect %s\n",nvme_show_message(1, "failed to disconnect %s\n", libnvme_ctrl_get_name
(c))
1544 libnvme_ctrl_get_name(c))nvme_show_message(1, "failed to disconnect %s\n", libnvme_ctrl_get_name
(c))
;
1545 }
1546 }
1547 }
1548
1549 return 0;
1550}
1551
1552int fabrics_config_validate(const char *desc, int argc, char **argv)
1553{
1554 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1555 char *config_file = PATH_NVMF_INI"/usr/local/etc" "/nvme/nvme-fabrics.conf";
1556 int ret;
1557
1558 OPT_ARGS(opts)struct argconfig_commandline_options opts[] = {
1559 OPT_STRING("config", 'J', "FILE", &config_file, nvmf_config_file_ro){"config", 'J', "FILE", CFG_STRING, &config_file, 1, nvmf_config_file_ro
, 0, }
,
1560 OPT_END(){ ((void*)0) }
1561 };
1562
1563 ret = parse_args(argc, argv, desc, opts);
1564 if (ret)
1565 return ret;
1566
1567 ret = nvme_create_global_ctx(&ctx);
1568 if (ret)
1569 return ret;
1570
1571 if (access(config_file, F_OK0)) {
1572 nvme_show_error("%s: no such file", config_file)nvme_show_message(1, "%s: no such file", config_file);
1573 return -ENOENT2;
1574 }
1575
1576 ret = libnvmf_config_validate(ctx, config_file);
1577 if (ret)
1578 nvme_show_error("%s: invalid configuration", config_file)nvme_show_message(1, "%s: invalid configuration", config_file
)
;
1579 else
1580 nvme_show_result("%s: OK", config_file)nvme_show_message(0, "%s: OK", config_file);
1581
1582 return ret;
1583}
1584
1585int fabrics_config_show(const char *desc, int argc, char **argv)
1586{
1587 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1588 struct libnvmf_config *cfg;
1589 char *config_file = PATH_NVMF_INI"/usr/local/etc" "/nvme/nvme-fabrics.conf";
1590 nvme_print_flags_t flags;
1591 int ret;
1592
1593 NVME_ARGS(opts,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"config", 'J', "FILE", CFG_STRING, &config_file, 1
, nvmf_config_file_ro, 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, }, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet
, 0, "suppress informational output", 0, }, {"output-format",
'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1594 OPT_STRING("config", 'J', "FILE", &config_file,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"config", 'J', "FILE", CFG_STRING, &config_file, 1
, nvmf_config_file_ro, 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, }, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet
, 0, "suppress informational output", 0, }, {"output-format",
'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1595 nvmf_config_file_ro))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"config", 'J', "FILE", CFG_STRING, &config_file, 1
, nvmf_config_file_ro, 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, }, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet
, 0, "suppress informational output", 0, }, {"output-format",
'o', "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
1596
1597 ret = parse_args(argc, argv, desc, opts);
1598 if (ret)
1599 return ret;
1600
1601 ret = validate_output_format(nvme_args.output_format, &flags);
1602 if (ret < 0) {
1603 nvme_show_error("Invalid output format")nvme_show_message(1, "Invalid output format");
1604 return ret;
1605 }
1606
1607 ret = nvme_create_global_ctx(&ctx);
1608 if (ret)
1609 return ret;
1610
1611 ret = libnvmf_config_read(ctx, config_file, &cfg);
1612 if (ret) {
1613 nvme_show_error("failed to read %s: %s", config_file,nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
1614 libnvme_strerror(-ret))nvme_show_message(1, "failed to read %s: %s", config_file, libnvme_strerror
(-ret))
;
1615 return ret;
1616 }
1617
1618 nvme_show_config_conn_list(cfg, flags);
1619 libnvmf_config_free(cfg);
1620
1621 return 0;
1622}
1623
1624static int dim_operation(struct libnvme_ctrl *c, enum nvmf_dim_tas tas, const char *name)
1625{
1626 static const char * const task[] = {
1627 [NVMF_DIM_TAS_REGISTER] = "register",
1628 [NVMF_DIM_TAS_DEREGISTER] = "deregister",
1629 };
1630 const char *t;
1631 int status;
1632 __u32 result;
1633
1634 t = (tas > NVMF_DIM_TAS_DEREGISTER || !task[tas]) ? "reserved" : task[tas];
1635 status = libnvmf_register_ctrl(c, tas, &result);
1636 if (status == NVME_SC_SUCCESS) {
1637 nvme_show_verbose_result("%s DIM %s command success", name, t)nvme_show_verbose_message("%s DIM %s command success", name, t
)
;
1638 } else if (status < NVME_SC_SUCCESS) {
1639 nvme_show_error("%s DIM %s command error. Status:0x%04x - %s",nvme_show_message(1, "%s DIM %s command error. Status:0x%04x - %s"
, name, t, status, libnvme_status_to_string(status, 0))
1640 name, t, status, libnvme_status_to_string(status, false))nvme_show_message(1, "%s DIM %s command error. Status:0x%04x - %s"
, name, t, status, libnvme_status_to_string(status, 0))
;
1641 } else {
1642 nvme_show_error("%s DIM %s command error. Result:0x%04x, Status:0x%04x - %s",nvme_show_message(1, "%s DIM %s command error. Result:0x%04x, Status:0x%04x - %s"
, name, t, result, status, libnvme_status_to_string(status, 0
))
1643 name, t, result, status, libnvme_status_to_string(status, false))nvme_show_message(1, "%s DIM %s command error. Result:0x%04x, Status:0x%04x - %s"
, name, t, result, status, libnvme_status_to_string(status, 0
))
;
1644 }
1645
1646 return libnvme_status_to_errno(status, true1);
1647}
1648
1649int fabrics_dim(const char *desc, int argc, char **argv)
1650{
1651 __cleanup_nvme_global_ctx__attribute__((cleanup(cleanup_nvme_global_ctx))) struct libnvme_global_ctx *ctx = NULL((void*)0);
1652 enum nvmf_dim_tas tas;
1653 struct libnvme_ctrl *c;
1654 char *p;
1655 int ret;
1656
1657 struct {
1658 char *nqn;
1659 char *device;
1660 char *tas;
1661 } cfg = { 0 };
1662
1663 NVME_ARGS(opts,nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"nqn", 'n', "NAME", CFG_STRING, &cfg.nqn, 1, "Comma-separated list of DC nqn"
, 0, }, {"device", 'd', "DEV", CFG_STRING, &cfg.device, 1
, "Comma-separated list of DC nvme device handle.", 0, }, {"task"
, 't', "TASK", CFG_STRING, &cfg.tas, 1, "[register|deregister]"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1664 OPT_STRING("nqn", 'n', "NAME", &cfg.nqn, "Comma-separated list of DC nqn"),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"nqn", 'n', "NAME", CFG_STRING, &cfg.nqn, 1, "Comma-separated list of DC nqn"
, 0, }, {"device", 'd', "DEV", CFG_STRING, &cfg.device, 1
, "Comma-separated list of DC nvme device handle.", 0, }, {"task"
, 't', "TASK", CFG_STRING, &cfg.tas, 1, "[register|deregister]"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1665 OPT_STRING("device", 'd', "DEV", &cfg.device, "Comma-separated list of DC nvme device handle."),nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"nqn", 'n', "NAME", CFG_STRING, &cfg.nqn, 1, "Comma-separated list of DC nqn"
, 0, }, {"device", 'd', "DEV", CFG_STRING, &cfg.device, 1
, "Comma-separated list of DC nvme device handle.", 0, }, {"task"
, 't', "TASK", CFG_STRING, &cfg.tas, 1, "[register|deregister]"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
1666 OPT_STRING("task", 't', "TASK", &cfg.tas, "[register|deregister]"))nvme_args.supported_output_formats = (NORMAL | JSON | BINARY)
; struct argconfig_commandline_options opts[] = { {"", 0, ((void
*)0), CFG_GROUP_SEPARATOR, ((void*)0), 0, "Options", 0, ((void
*)0)}, {"nqn", 'n', "NAME", CFG_STRING, &cfg.nqn, 1, "Comma-separated list of DC nqn"
, 0, }, {"device", 'd', "DEV", CFG_STRING, &cfg.device, 1
, "Comma-separated list of DC nvme device handle.", 0, }, {"task"
, 't', "TASK", CFG_STRING, &cfg.tas, 1, "[register|deregister]"
, 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, }
, {"quiet", 0, ((void*)0), CFG_FLAG, &nvme_args.quiet, 0,
"suppress informational output", 0, }, {"output-format", 'o'
, "FMT", CFG_STRING, &nvme_args.output_format, 1, "Output format: normal|json|binary"
, 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}, {"set-options", 0, "KEY=VALUE", CFG_STRING
, &nvme_args.set_options, 1, "set a libnvme library option (key=value[,key=value,...]);"
, 0, }, { ((void*)0) } }
;
1667
1668 ret = parse_args(argc, argv, desc, opts);
1669 if (ret)
1670 return ret;
1671
1672 if (!cfg.nqn && !cfg.device) {
1673 nvme_show_error(nvme_show_message(1, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"
)
1674 "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n")nvme_show_message(1, "Neither device name [--device | -d] nor NQN [--nqn | -n] provided\n"
)
;
1675 return -EINVAL22;
1676 }
1677
1678 if (!cfg.tas) {
1679 nvme_show_error(nvme_show_message(1, "Task [--task | -t] must be specified\n"
)
1680 "Task [--task | -t] must be specified\n")nvme_show_message(1, "Task [--task | -t] must be specified\n"
)
;
1681 return -EINVAL22;
1682 }
1683
1684 /* Allow partial name (e.g. "reg" for "register" */
1685 if (strstarts("register", cfg.tas)(strncmp(("register"),(cfg.tas),strlen(cfg.tas)) == 0)) {
1686 tas = NVMF_DIM_TAS_REGISTER;
1687 } else if (strstarts("deregister", cfg.tas)(strncmp(("deregister"),(cfg.tas),strlen(cfg.tas)) == 0)) {
1688 tas = NVMF_DIM_TAS_DEREGISTER;
1689 } else {
1690 nvme_show_error("Invalid --task: %s", cfg.tas)nvme_show_message(1, "Invalid --task: %s", cfg.tas);
1691 return -EINVAL22;
1692 }
1693
1694 ret = nvme_create_global_ctx(&ctx);
1695 if (ret)
1696 return ret;
1697
1698 libnvme_skip_namespaces(ctx);
1699 ret = libnvme_scan_topology(ctx, NULL((void*)0), NULL((void*)0));
1700 if (ret < 0) {
1701 nvme_show_error("Failed to scan topology: %s",nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
1702 libnvme_strerror(-ret))nvme_show_message(1, "Failed to scan topology: %s", libnvme_strerror
(-ret))
;
1703 return ret;
1704 }
1705
1706 if (cfg.nqn) {
1707 struct libnvme_host *h;
1708 struct libnvme_subsystem *s;
1709 char *n = cfg.nqn;
1710
1711 while ((p = strsep(&n, ",")) != NULL((void*)0)) {
1712 if (!strlen(p))
1713 continue;
1714 libnvme_for_each_host(ctx, h)for (h = libnvme_first_host(ctx); h != ((void*)0); h = libnvme_next_host
(ctx, h))
{
1715 libnvme_for_each_subsystem(h, s)for (s = libnvme_first_subsystem(h); s != ((void*)0); s = libnvme_next_subsystem
(h, s))
{
1716 if (strcmp(libnvme_subsystem_get_subsysnqn(s), p))
1717 continue;
1718 libnvme_subsystem_for_each_ctrl(s, c)for (c = libnvme_subsystem_first_ctrl(s); c != ((void*)0); c =
libnvme_subsystem_next_ctrl(s, c))
1719 ret = dim_operation(c, tas, p);
1720 }
1721 }
1722 }
1723 }
1724
1725 if (cfg.device) {
1726 char *d = cfg.device;
1727
1728 while ((p = strsep(&d, ",")) != NULL((void*)0)) {
1729 if (!strncmp(p, "/dev/", 5))
1730 p += 5;
1731 ret = libnvme_scan_ctrl(ctx, p, &c);
1732 if (ret) {
1733 nvme_show_error(nvme_show_message(1, "Did not find device %s: %s\n", p, libnvme_strerror
(ret))
1734 "Did not find device %s: %s\n",nvme_show_message(1, "Did not find device %s: %s\n", p, libnvme_strerror
(ret))
1735 p, libnvme_strerror(ret))nvme_show_message(1, "Did not find device %s: %s\n", p, libnvme_strerror
(ret))
;
1736 return ret;
1737 }
1738 ret = dim_operation(c, tas, p);
1739 }
1740 }
1741
1742 return ret;
1743}