HardenedBSD/sbin/nvmecontrol/disconnect.c
John Baldwin 1058c12197 nvmecontrol: New commands to support Fabrics hosts
- discover: Connects to a remote Discovery controller, fetches its
  Discovery Log Page, and enumerates the remote controllers described
  in the log page.

  The -v option can be used to display the Identify Controller data
  structure for the Discovery controller.  This is only really useful
  for debugging.

- connect: Connects to a remote I/O controller and establishes an
  association of an admin queue and a single I/O queue.  The
  association is handed off to the in-kernel host to create a new
  nvmeX device.

- connect-all: Connects to a Discovery controller and attempts to
  create an association with each I/O controller enumerated in the
  Discovery controller's Discovery Log Page.

- reconnect: Establishes a new association with a remote I/O
  controller for an existing nvmeX device.  This can be used to
  restore access to a remote I/O controller after the loss of a prior
  association due to a transport error, controller reboot, etc.

- disconnect: Deletes one or more nvmeX devices after detaching its
  namespaces and terminating any active associations.  The devices to
  delete can be identified by either a nvmeX device name or the NQN of
  the remote controller.

- disconnect-all: Deletes all active associations with remote
  controllers.

Reviewed by:	imp
Sponsored by:	Chelsio Communications
Differential Revision:	https://reviews.freebsd.org/D44715
2024-05-02 16:30:10 -07:00

83 lines
1.6 KiB
C

/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2023-2024 Chelsio Communications, Inc.
* Written by: John Baldwin <jhb@FreeBSD.org>
*/
#include <err.h>
#include <libnvmf.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
#include "nvmecontrol.h"
static struct options {
const char *dev;
} opt = {
.dev = NULL
};
static const struct args args[] = {
{ arg_string, &opt.dev, "controller-id|namespace-id|SubNQN" },
{ arg_none, NULL, NULL },
};
static void
disconnect(const struct cmd *f, int argc, char *argv[])
{
int error, fd;
char *path;
if (arg_parse(argc, argv, f))
return;
if (nvmf_nqn_valid(opt.dev)) {
error = nvmf_disconnect_host(opt.dev);
if (error != 0)
errc(EX_IOERR, error, "failed to disconnect from %s",
opt.dev);
} else {
open_dev(opt.dev, &fd, 1, 1);
get_nsid(fd, &path, NULL);
close(fd);
error = nvmf_disconnect_host(path);
if (error != 0)
errc(EX_IOERR, error, "failed to disconnect from %s",
path);
}
exit(0);
}
static void
disconnect_all(const struct cmd *f __unused, int argc __unused,
char *argv[] __unused)
{
int error;
error = nvmf_disconnect_all();
if (error != 0)
errc(EX_IOERR, error,
"failed to disconnect from remote controllers");
exit(0);
}
static struct cmd disconnect_cmd = {
.name = "disconnect",
.fn = disconnect,
.descr = "Disconnect from a fabrics controller",
.args = args,
};
static struct cmd disconnect_all_cmd = {
.name = "disconnect-all",
.fn = disconnect_all,
.descr = "Disconnect from all fabrics controllers",
};
CMD_COMMAND(disconnect_cmd);
CMD_COMMAND(disconnect_all_cmd);