]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
Add --host-iface option
authorMartin Belanger <martin.belanger@dell.com>
Thu, 20 May 2021 17:49:44 +0000 (13:49 -0400)
committerKeith Busch <kbusch@kernel.org>
Wed, 2 Jun 2021 21:46:30 +0000 (15:46 -0600)
Documentation/nvme-connect-all.txt
Documentation/nvme-connect.txt
Documentation/nvme-discover.txt
etc/discovery.conf.in
fabrics.c
fabrics.h
nvme.h

index 820dd6c6eb2c9e848b5019ac9039d64f24698a86..1cb7822b4f5e15fd9543edb89149f2c0c180f31e 100644 (file)
@@ -13,6 +13,7 @@ SYNOPSIS
                [--traddr=<traddr>        | -a <traddr>]
                [--trsvcid=<trsvcid>      | -s <trsvcid>]
                [--host-traddr=<traddr>   | -w <traddr>]
+               [--host-iface=<iface>     | -f <iface>]
                [--hostnqn=<hostnqn>      | -q <hostnqn>]
                [--hostid=<hostid>        | -I <hostid>]
                [--raw=<filename>         | -r <filename>]
@@ -77,7 +78,14 @@ OPTIONS
 -w <traddr>::
 --host-traddr=<traddr>::
        This field specifies the network address used on the host to connect
-       to the Discovery Controller.
+       to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+       This field specifies the network interface used on the host to connect
+       to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+       the connection to be made on a specific interface instead of letting
+       the system decide.
 
 -q <hostnqn>::
 --hostnqn=<hostnqn>::
index 757e3d02001edad7a3b507bf65cc35102f845333..4d7bb52b978fa3e953eaf543da80a0b0be194f57 100644 (file)
@@ -14,6 +14,7 @@ SYNOPSIS
                [--traddr=<traddr>        | -a <traddr>]
                [--trsvcid=<trsvcid>      | -s <trsvcid>]
                [--host-traddr=<traddr>   | -w <traddr>]
+               [--host-iface=<iface>     | -f <iface>]
                [--hostnqn=<hostnqn>      | -q <hostnqn>]
                [--hostid=<hostid>        | -I <hostid>]
                [--nr-io-queues=<#>       | -i <#>]
@@ -69,7 +70,14 @@ OPTIONS
 -w <traddr>::
 --host-traddr=<traddr>::
        This field specifies the network address used on the host to connect
-       to the Controller.
+       to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+       This field specifies the network interface used on the host to connect
+       to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+       the connection to be made on a specific interface instead of letting
+       the system decide.
 
 -q <hostnqn>::
 --hostnqn=<hostnqn>::
index 74add74c6d834636b0d5d5d6ece06632076391ed..d0a281a98eb05f2d13c72e58d1e170174caeed74 100644 (file)
@@ -13,6 +13,7 @@ SYNOPSIS
                [--traddr=<traddr>        | -a <traddr>]
                [--trsvcid=<trsvcid>      | -s <trsvcid>]
                [--host-traddr=<traddr>   | -w <traddr>]
+               [--host-iface=<iface>     | -f <iface>]
                [--hostnqn=<hostnqn>      | -q <hostnqn>]
                [--hostid=<hostid>        | -I <hostid>]
                [--raw=<filename>         | -r <filename>]
@@ -35,7 +36,7 @@ DESCRIPTION
 Send one or more Get Log Page requests to a NVMe-over-Fabrics Discovery
 Controller.
 
-If no parameters are given, then 'nvme discover' will attempt to 
+If no parameters are given, then 'nvme discover' will attempt to
 find a /etc/nvme/discovery.conf file to use to supply a list of
 Discovery commands to run.  If no /etc/nvme/discovery.conf file
 exists, the command will quit with an error.
@@ -46,7 +47,7 @@ request will then be sent to the specified Discovery Controller.
 
 BACKGROUND
 ----------
-The NVMe-over-Fabrics specification defines the concept of a 
+The NVMe-over-Fabrics specification defines the concept of a
 Discovery Controller that an NVMe Host can query on a fabric
 network to discover NVMe subsystems contained in NVMe Targets
 which it can connect to on the network.  The Discovery Controller
@@ -66,7 +67,7 @@ resources are allocated to the NVMe Host for a connection.
 A Discovery Controller has it's own NQN defined in the NVMe-over-Fabrics
 specification, *nqn.2014-08.org.nvmexpress.discovery*.  All Discovery
 Controllers must use this NQN name. This NQN is used by default by
-nvme-cli for the 'discover' command. 
+nvme-cli for the 'discover' command.
 
 OPTIONS
 -------
@@ -99,11 +100,18 @@ OPTIONS
 -w <traddr>::
 --host-traddr=<traddr>::
        This field specifies the network address used on the host to connect
-       to the Discovery Controller.
+       to the Controller. For TCP, this sets the source address on the socket.
+
+-f <iface>::
+--host-iface=<iface>::
+       This field specifies the network interface used on the host to connect
+       to the Controller (e.g. IP eth1, enp2s0, enx78e7d1ea46da). This forces
+       the connection to be made on a specific interface instead of letting
+       the system decide.
+
 -q <hostnqn>::
 --hostnqn=<hostnqn>::
-       Overrides the default host NQN that identifies the NVMe Host.  
+       Overrides the default host NQN that identifies the NVMe Host.
        If this option is not specified, the default is read from
        /etc/nvme/hostnqn first. If that does not exist, the autogenerated
        NQN value from the NVMe Host kernel module is used next.
index 14e0d9c3dcbf4363c049c6191fde01f6f5f3a515..cfdac1ea88cd2dcc122593ac1f7dcafe44a96f8e 100644 (file)
@@ -1,4 +1,4 @@
 # Used for extracting default parameters for discovery
 #
 # Example:
-# --transport=<trtype> --traddr=<traddr> --trsvcid=<trsvcid> --host-traddr=<host-traddr>
+# --transport=<trtype> --traddr=<traddr> --trsvcid=<trsvcid> --host-traddr=<host-traddr> --host-iface=<host-iface>
index 77eb8f4efc9b5fab6222a6806ea9fb5826ca4fc4..db42ddbd6d9b3d9a0db3521ea32ed3c948a7fed6 100644 (file)
--- a/fabrics.c
+++ b/fabrics.c
@@ -66,6 +66,7 @@ const char *conarg_transport = "transport";
 const char *conarg_traddr = "traddr";
 const char *conarg_trsvcid = "trsvcid";
 const char *conarg_host_traddr = "host_traddr";
+const char *conarg_host_iface = "host_iface";
 
 struct fabrics_config fabrics_cfg = {
        .ctrl_loss_tmo = -1,
@@ -79,6 +80,7 @@ struct connect_args {
        char *traddr;
        char *trsvcid;
        char *host_traddr;
+       char *host_iface;
        struct connect_args *next;
        struct connect_args *tail;
 };
@@ -301,6 +303,7 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
        cargs.traddr = parse_conn_arg(addr, ' ', conarg_traddr);
        cargs.trsvcid = parse_conn_arg(addr, ' ', conarg_trsvcid);
        cargs.host_traddr = parse_conn_arg(addr, ' ', conarg_host_traddr);
+       cargs.host_iface = parse_conn_arg(addr, ' ', conarg_host_iface);
 
        if (!strcmp(cargs.subsysnqn, NVME_DISC_SUBSYS_NAME)) {
                char *kato_str = nvme_get_ctrl_attr(path, "kato"), *p;
@@ -332,7 +335,9 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
            (!strcmp(cargs.trsvcid, args->trsvcid) ||
             !strcmp(args->trsvcid, "none")) &&
            (!strcmp(cargs.host_traddr, args->host_traddr) ||
-            !strcmp(args->host_traddr, "none")))
+            !strcmp(args->host_traddr, "none")) &&
+           (!strcmp(cargs.host_iface, args->host_iface) ||
+            !strcmp(args->host_iface, "none")))
                found = true;
 
        free(cargs.subsysnqn);
@@ -340,6 +345,7 @@ static bool ctrl_matches_connectargs(const char *name, struct connect_args *args
        free(cargs.traddr);
        free(cargs.trsvcid);
        free(cargs.host_traddr);
+       free(cargs.host_iface);
        free(addr);
        free(path);
 
@@ -395,6 +401,7 @@ static struct connect_args *extract_connect_args(char *argstr)
        cargs->traddr = parse_conn_arg(argstr, ',', conarg_traddr);
        cargs->trsvcid = parse_conn_arg(argstr, ',', conarg_trsvcid);
        cargs->host_traddr = parse_conn_arg(argstr, ',', conarg_host_traddr);
+       cargs->host_iface = parse_conn_arg(argstr, ',', conarg_host_iface);
        return cargs;
 }
 
@@ -405,6 +412,7 @@ static void destruct_connect_args(struct connect_args *cargs)
        free(cargs->traddr);
        free(cargs->trsvcid);
        free(cargs->host_traddr);
+       free(cargs->host_iface);
 }
 
 static void free_connect_args(struct connect_args *cargs)
@@ -983,6 +991,7 @@ int build_options(char *argstr, int max_len, bool discover)
        if (add_argument(&argstr, &max_len, "transport", fabrics_cfg.transport) ||
            add_argument(&argstr, &max_len, "traddr", fabrics_cfg.traddr) ||
            add_argument(&argstr, &max_len, "host_traddr", fabrics_cfg.host_traddr) ||
+           add_argument(&argstr, &max_len, "host_iface", fabrics_cfg.host_iface) ||
            add_argument(&argstr, &max_len, "trsvcid", fabrics_cfg.trsvcid) ||
            ((fabrics_cfg.hostnqn || nvmf_hostnqn_file()) &&
                    add_argument(&argstr, &max_len, "hostnqn", fabrics_cfg.hostnqn)) ||
@@ -1174,6 +1183,13 @@ retry:
                p+= len;
        }
 
+       if (fabrics_cfg.host_iface && strcmp(fabrics_cfg.host_iface, "none")) {
+               len = sprintf(p, ",host_iface=%s", fabrics_cfg.host_iface);
+               if (len < 0)
+                       return -EINVAL;
+               p+= len;
+       }
+
        if (fabrics_cfg.reconnect_delay) {
                len = sprintf(p, ",reconnect_delay=%d", fabrics_cfg.reconnect_delay);
                if (len < 0)
@@ -1313,6 +1329,7 @@ static bool cargs_match_found(struct nvmf_disc_rsp_page_entry *entry)
        cargs.subsysnqn = strdup(entry->subnqn);
        cargs.trsvcid = strdup(entry->trsvcid);
        cargs.host_traddr = strdup(fabrics_cfg.host_traddr ?: "\0");
+       cargs.host_iface = strdup(fabrics_cfg.host_iface ?: "\0");
 
        /* check if we have a match in the discovery recursion */
        while (c) {
@@ -1320,7 +1337,8 @@ static bool cargs_match_found(struct nvmf_disc_rsp_page_entry *entry)
                    !strcmp(cargs.transport, c->transport) &&
                    !strcmp(cargs.traddr, c->traddr) &&
                    !strcmp(cargs.trsvcid, c->trsvcid) &&
-                   !strcmp(cargs.host_traddr, c->host_traddr))
+                   !strcmp(cargs.host_traddr, c->host_traddr) &&
+                   !strcmp(cargs.host_iface, c->host_iface))
                        return true;
                c = c->next;
        }
@@ -1550,7 +1568,8 @@ free_and_continue:
                free(all_args);
                free(argv);
                fabrics_cfg.transport = fabrics_cfg.traddr =
-                       fabrics_cfg.trsvcid = fabrics_cfg.host_traddr = NULL;
+                       fabrics_cfg.trsvcid = fabrics_cfg.host_traddr =
+                       fabrics_cfg.host_iface = NULL;
        }
 
 out:
@@ -1569,7 +1588,8 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
                OPT_LIST("transport",      't', &fabrics_cfg.transport,       "transport type"),
                OPT_LIST("traddr",         'a', &fabrics_cfg.traddr,          "transport address"),
                OPT_LIST("trsvcid",        's', &fabrics_cfg.trsvcid,         "transport service id (e.g. IP port)"),
-               OPT_LIST("host-traddr",    'w', &fabrics_cfg.host_traddr,     "host traddr (e.g. FC WWN's)"),
+               OPT_LIST("host-traddr",    'w', &fabrics_cfg.host_traddr,     "host traddr (e.g. FC WWN's or IP source address)"),
+               OPT_LIST("host-iface",     'f', &fabrics_cfg.host_iface,      "host transport interface (e.g. IP eth1, enp2s0)"),
                OPT_LIST("hostnqn",        'q', &fabrics_cfg.hostnqn,         "user-defined hostnqn (if default not used)"),
                OPT_LIST("hostid",         'I', &fabrics_cfg.hostid,          "user-defined hostid (if default not used)"),
                OPT_LIST("raw",            'r', &fabrics_cfg.raw,             "raw output file"),
@@ -1586,7 +1606,7 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect)
                OPT_INT("nr-poll-queues",  'P', &fabrics_cfg.nr_poll_queues,  "number of poll queues to use (default 0)"),
                OPT_INT("queue-size",      'Q', &fabrics_cfg.queue_size,      "number of io queue elements to use (default 128)"),
                OPT_FLAG("persistent",     'p', &fabrics_cfg.persistent,      "persistent discovery connection"),
-               OPT_FLAG("quiet",          'S', &quiet,               "suppress already connected errors"),
+               OPT_FLAG("quiet",          'S', &quiet,                       "suppress already connected errors"),
                OPT_FLAG("matching",       'm', &fabrics_cfg.matching_only,   "connect only records matching the traddr"),
                OPT_FMT("output-format",   'o', &fabrics_cfg.output_format,   output_format),
                OPT_END()
@@ -1651,7 +1671,8 @@ int fabrics_connect(const char *desc, int argc, char **argv)
                OPT_LIST("nqn",               'n', &fabrics_cfg.nqn,               "nqn name"),
                OPT_LIST("traddr",            'a', &fabrics_cfg.traddr,            "transport address"),
                OPT_LIST("trsvcid",           's', &fabrics_cfg.trsvcid,           "transport service id (e.g. IP port)"),
-               OPT_LIST("host-traddr",       'w', &fabrics_cfg.host_traddr,       "host traddr (e.g. FC WWN's)"),
+               OPT_LIST("host-traddr",       'w', &fabrics_cfg.host_traddr,       "host traddr (e.g. FC WWN's or IP source address)"),
+               OPT_LIST("host-iface",        'f', &fabrics_cfg.host_iface,        "host transport interface (e.g. IP eth1, enp2s0)"),
                OPT_LIST("hostnqn",           'q', &fabrics_cfg.hostnqn,           "user-defined hostnqn"),
                OPT_LIST("hostid",            'I', &fabrics_cfg.hostid,            "user-defined hostid (if default not used)"),
                OPT_INT("nr-io-queues",       'i', &fabrics_cfg.nr_io_queues,      "number of io queues to use (default is core count)"),
index b98f6b0d09044cad89d716ab5e582bc9b492dfe9..9b2554eb0d8b282205143bd5eb7966f5d9f7b16c 100644 (file)
--- a/fabrics.h
+++ b/fabrics.h
@@ -20,6 +20,7 @@ struct fabrics_config {
        const char *traddr;
        const char *trsvcid;
        const char *host_traddr;
+       const char *host_iface;
        const char *hostnqn;
        const char *hostid;
        int  nr_io_queues;
diff --git a/nvme.h b/nvme.h
index e33094d096d7305986d13384e231ede73f36e7e9..3b733675bb9ee48919e29b66a9cda1e75748d037 100644 (file)
--- a/nvme.h
+++ b/nvme.h
@@ -82,6 +82,7 @@ struct nvme_ctrl {
        char *traddr;
        char *trsvcid;
        char *host_traddr;
+       char *host_iface;
        char *hostnqn;
        char *hostid;