]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
fabrics: Introduce force flag to overwrite persistence logic
authorDaniel Wagner <dwagner@suse.de>
Thu, 24 Mar 2022 18:27:01 +0000 (19:27 +0100)
committerDaniel Wagner <dwagner@suse.de>
Thu, 31 Mar 2022 13:31:49 +0000 (15:31 +0200)
The persistence flag will be overwritten by the built in logic. Allow
the user to overwrite this by providing a force command line option.

While at it make the 'discover_from_config_file' path behave as the
'nvmf_discover' path. The idea here is that whenever a matching
persistent discovery controller is present just use this one. Only
create a new discovery controller when none matching found or
we are asked to do so via --force.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
Documentation/nvme-discover.txt
common.h
fabrics.c

index a63212329a47ff406045d380225912c9970dbbce..e27949bf93eb3bfc29ceb8fa1f2a0fd4dd215da4 100644 (file)
@@ -33,6 +33,7 @@ SYNOPSIS
                [--quiet                  | -S]
                [--dump-config            | -O]
                [--output-format=<fmt>    | -o <fmt>]
+               [--force]
 
 DESCRIPTION
 -----------
@@ -208,6 +209,11 @@ OPTIONS
               Set the reporting format to 'normal', 'json', or
               'binary'. Only one output format can be used at a time.
 
+--force::
+       Disable the built-in persitent discover connection rules.
+       Combined with --persistent flag, always create new
+       persistent discovery connection.
+
 EXAMPLES
 --------
 * Query the Discover Controller with IP4 address 192.168.1.3 for all
index 752bf001b98e61c2ae986a3e1102b816f3973e9c..d69eb1a0800b4b84fc564d470fda427a98154952 100644 (file)
--- a/common.h
+++ b/common.h
@@ -1,6 +1,8 @@
 #ifndef _COMMON_H
 #define _COMMON_H
 
+#include <string.h>
+
 #include "ccan/endian/endian.h"
 
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
index 4224220d79f2014904f95a0dcc3de60542a1b345..9627fca77b1ef62d4ab20ba4bd0fc62527ab244b 100644 (file)
--- a/fabrics.c
+++ b/fabrics.c
@@ -334,6 +334,68 @@ static int __discover(nvme_ctrl_t c, const struct nvme_fabrics_config *defcfg,
        return 0;
 }
 
+/*
+ * Compare two C strings and handle NULL pointers gracefully.
+ * If either of the two strings is NULL, return 0
+ * to let caller ignore the compare.
+ */
+static inline int strcmp0(const char *s1, const char *s2)
+{
+       if (!s1 || !s2)
+               return 0;
+       return strcmp(s1, s2);
+}
+
+/*
+ * Compare two C strings and handle NULL pointers gracefully.
+ * If either of the two strings is NULL, return 0
+ * to let caller ignore the compare.
+ */
+static inline int strcasecmp0(const char *s1, const char *s2)
+{
+       if (!s1 || !s2)
+               return 0;
+       return strcasecmp(s1, s2);
+}
+
+static bool ctrl_config_match(nvme_ctrl_t c, char *transport,
+                             char *traddr, char *host_traddr,
+                             char *host_iface, char *trsvcid)
+{
+       if (!strcmp0(nvme_ctrl_get_transport(c), transport) &&
+           !strcasecmp0(nvme_ctrl_get_traddr(c), traddr) &&
+           !strcmp0(nvme_ctrl_get_trsvcid(c), trsvcid) &&
+           !strcmp0(nvme_ctrl_get_host_traddr(c), host_traddr) &&
+           !strcmp0(nvme_ctrl_get_host_iface(c), host_iface))
+               return true;
+
+       return false;
+}
+
+static nvme_ctrl_t lookup_discover_ctrl(nvme_root_t r, char *transport,
+                                       char *traddr, char *host_traddr,
+                                       char *host_iface, char *trsvcid)
+{
+       nvme_host_t h;
+       nvme_subsystem_t s;
+       nvme_ctrl_t c;
+
+       nvme_for_each_host(r, h) {
+               nvme_for_each_subsystem(h, s) {
+                       nvme_subsystem_for_each_ctrl(s, c) {
+                               if (!nvme_ctrl_is_discovery_ctrl(c))
+                                       continue;
+                               if (ctrl_config_match(c, transport, traddr,
+                                                     host_traddr, host_iface,
+                                                     trsvcid))
+                                       return c;
+                       }
+               }
+       }
+
+       return NULL;
+}
+
 static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
                                   const char *desc, bool connect,
                                   const struct nvme_fabrics_config *defcfg)
@@ -348,6 +410,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
        enum nvme_print_flags flags;
        char *format = "normal";
        struct nvme_fabrics_config cfg;
+       bool force = false;
 
        OPT_ARGS(opts) = {
                NVMF_OPTS(cfg),
@@ -356,6 +419,7 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
                OPT_FLAG("persistent",   'p', &persistent,    "persistent discovery connection"),
                OPT_FLAG("quiet",        'S', &quiet,         "suppress already connected errors"),
                OPT_INCR("verbose",      'v', &verbose,       "Increase logging verbosity"),
+               OPT_FLAG("force",          0, &force,         "Force persistent discovery controller creation"),
                OPT_END()
        };
 
@@ -401,6 +465,17 @@ static int discover_from_conf_file(nvme_root_t r, nvme_host_t h,
 
                set_discovery_kato(&cfg);
 
+               if (!force) {
+                       c = lookup_discover_ctrl(r, transport, traddr,
+                                                cfg.host_traddr, cfg.host_iface,
+                                                trsvcid);
+                       if (c) {
+                               __discover(c, &cfg, raw, connect,
+                                          true, flags);
+                               goto next;
+                       }
+               }
+
                c = nvme_create_ctrl(r, subsysnqn, transport, traddr,
                                     cfg.host_traddr, cfg.host_iface, trsvcid);
                if (!c)
@@ -440,6 +515,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
        char *format = "normal";
        struct nvme_fabrics_config cfg;
        char *device = NULL;
+       bool force = false;
 
        OPT_ARGS(opts) = {
                OPT_STRING("device",   'd', "DEV", &device, "use existing discovery controller device"),
@@ -451,6 +527,7 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
                OPT_STRING("config",     'J', "FILE", &config_file, nvmf_config_file),
                OPT_INCR("verbose",      'v', &verbose,       "Increase logging verbosity"),
                OPT_FLAG("dump-config",  'O', &dump_config,   "Dump configuration file to stdout"),
+               OPT_FLAG("force",          0, &force,         "Force persistent discovery controller creation"),
                OPT_END()
        };
 
@@ -505,25 +582,25 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
                goto out_free;
        }
 
-       if (device) {
+       if (device && !force) {
                c = nvme_scan_ctrl(r, device);
                if (c) {
                        /* Check if device matches command-line options */
-                       if (!nvme_ctrl_is_discovery_ctrl(c) ||
-                           strcmp(nvme_ctrl_get_transport(c), transport) ||
-                           strcasecmp(nvme_ctrl_get_traddr(c), traddr) ||
-                           (cfg.host_traddr && nvme_ctrl_get_host_traddr(c) &&
-                            strcmp(nvme_ctrl_get_host_traddr(c),
-                                   cfg.host_traddr)) ||
-                           (cfg.host_iface && nvme_ctrl_get_host_iface(c) &&
-                            strcmp(nvme_ctrl_get_host_iface(c),
-                                   cfg.host_iface)) ||
-                           (trsvcid && nvme_ctrl_get_trsvcid(c) &&
-                            strcmp(nvme_ctrl_get_trsvcid(c), trsvcid))) {
+                       if (!ctrl_config_match(c, transport, traddr,
+                                              cfg.host_traddr, cfg.host_iface,
+                                              trsvcid)) {
                                fprintf(stderr,
-                                       "ignoring ctrl device %s, "
-                                       "command-line options do not match\n",
+                                       "ctrl device %s found, ignoring "
+                                       "non matching command-line options\n",
                                        device);
+                       }
+
+                       if (!nvme_ctrl_is_discovery_ctrl(c)) {
+                               fprintf(stderr,
+                                       "ctrl device %s found, ignoring "
+                                       "non discovery controller\n",
+                                       device);
+
                                nvme_free_ctrl(c);
                                c = NULL;
                                persistent = false;
@@ -546,6 +623,13 @@ int nvmf_discover(const char *desc, int argc, char **argv, bool connect)
                        persistent = false;
                }
        }
+       if (!c && !force) {
+               c = lookup_discover_ctrl(r, transport, traddr,
+                                        cfg.host_traddr, cfg.host_iface,
+                                        trsvcid);
+               if (c)
+                       persistent = true;
+       }
        if (!c) {
                /* No device or non-matching device, create a new controller */
                c = nvme_create_ctrl(r, subsysnqn, transport, traddr,