1*1058c121SJohn Baldwin /*- 2*1058c121SJohn Baldwin * SPDX-License-Identifier: BSD-2-Clause 3*1058c121SJohn Baldwin * 4*1058c121SJohn Baldwin * Copyright (c) 2023-2024 Chelsio Communications, Inc. 5*1058c121SJohn Baldwin * Written by: John Baldwin <jhb@FreeBSD.org> 6*1058c121SJohn Baldwin */ 7*1058c121SJohn Baldwin 8*1058c121SJohn Baldwin #include <err.h> 9*1058c121SJohn Baldwin #include <libnvmf.h> 10*1058c121SJohn Baldwin #include <stdlib.h> 11*1058c121SJohn Baldwin #include <sysexits.h> 12*1058c121SJohn Baldwin #include <unistd.h> 13*1058c121SJohn Baldwin 14*1058c121SJohn Baldwin #include "nvmecontrol.h" 15*1058c121SJohn Baldwin 16*1058c121SJohn Baldwin static struct options { 17*1058c121SJohn Baldwin const char *dev; 18*1058c121SJohn Baldwin } opt = { 19*1058c121SJohn Baldwin .dev = NULL 20*1058c121SJohn Baldwin }; 21*1058c121SJohn Baldwin 22*1058c121SJohn Baldwin static const struct args args[] = { 23*1058c121SJohn Baldwin { arg_string, &opt.dev, "controller-id|namespace-id|SubNQN" }, 24*1058c121SJohn Baldwin { arg_none, NULL, NULL }, 25*1058c121SJohn Baldwin }; 26*1058c121SJohn Baldwin 27*1058c121SJohn Baldwin static void 28*1058c121SJohn Baldwin disconnect(const struct cmd *f, int argc, char *argv[]) 29*1058c121SJohn Baldwin { 30*1058c121SJohn Baldwin int error, fd; 31*1058c121SJohn Baldwin char *path; 32*1058c121SJohn Baldwin 33*1058c121SJohn Baldwin if (arg_parse(argc, argv, f)) 34*1058c121SJohn Baldwin return; 35*1058c121SJohn Baldwin if (nvmf_nqn_valid(opt.dev)) { 36*1058c121SJohn Baldwin error = nvmf_disconnect_host(opt.dev); 37*1058c121SJohn Baldwin if (error != 0) 38*1058c121SJohn Baldwin errc(EX_IOERR, error, "failed to disconnect from %s", 39*1058c121SJohn Baldwin opt.dev); 40*1058c121SJohn Baldwin } else { 41*1058c121SJohn Baldwin open_dev(opt.dev, &fd, 1, 1); 42*1058c121SJohn Baldwin get_nsid(fd, &path, NULL); 43*1058c121SJohn Baldwin close(fd); 44*1058c121SJohn Baldwin 45*1058c121SJohn Baldwin error = nvmf_disconnect_host(path); 46*1058c121SJohn Baldwin if (error != 0) 47*1058c121SJohn Baldwin errc(EX_IOERR, error, "failed to disconnect from %s", 48*1058c121SJohn Baldwin path); 49*1058c121SJohn Baldwin } 50*1058c121SJohn Baldwin 51*1058c121SJohn Baldwin exit(0); 52*1058c121SJohn Baldwin } 53*1058c121SJohn Baldwin 54*1058c121SJohn Baldwin static void 55*1058c121SJohn Baldwin disconnect_all(const struct cmd *f __unused, int argc __unused, 56*1058c121SJohn Baldwin char *argv[] __unused) 57*1058c121SJohn Baldwin { 58*1058c121SJohn Baldwin int error; 59*1058c121SJohn Baldwin 60*1058c121SJohn Baldwin error = nvmf_disconnect_all(); 61*1058c121SJohn Baldwin if (error != 0) 62*1058c121SJohn Baldwin errc(EX_IOERR, error, 63*1058c121SJohn Baldwin "failed to disconnect from remote controllers"); 64*1058c121SJohn Baldwin 65*1058c121SJohn Baldwin exit(0); 66*1058c121SJohn Baldwin } 67*1058c121SJohn Baldwin 68*1058c121SJohn Baldwin static struct cmd disconnect_cmd = { 69*1058c121SJohn Baldwin .name = "disconnect", 70*1058c121SJohn Baldwin .fn = disconnect, 71*1058c121SJohn Baldwin .descr = "Disconnect from a fabrics controller", 72*1058c121SJohn Baldwin .args = args, 73*1058c121SJohn Baldwin }; 74*1058c121SJohn Baldwin 75*1058c121SJohn Baldwin static struct cmd disconnect_all_cmd = { 76*1058c121SJohn Baldwin .name = "disconnect-all", 77*1058c121SJohn Baldwin .fn = disconnect_all, 78*1058c121SJohn Baldwin .descr = "Disconnect from all fabrics controllers", 79*1058c121SJohn Baldwin }; 80*1058c121SJohn Baldwin 81*1058c121SJohn Baldwin CMD_COMMAND(disconnect_cmd); 82*1058c121SJohn Baldwin CMD_COMMAND(disconnect_all_cmd); 83