Bug Summary

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