[PATCH v2 06/16] monitor: monitor_discovery(): try to reuse existing controllers

mwilck at suse.com mwilck at suse.com
Sat Mar 6 00:36:49 GMT 2021


From: Martin Wilck <mwilck at suse.com>

We need to pass cfg.device to do_discovery() if we want to re-use the
discovery controller device. Remember the instance number when
handling an AEN, and try to reuse this instance if the discovery
needs to be repeated.
---
 monitor.c | 43 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/monitor.c b/monitor.c
index d724f6f..f7517cb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -204,12 +204,14 @@ static int monitor_get_fc_uev_props(struct udev_device *ud,
 }
 
 static int monitor_discovery(const char *transport, const char *traddr,
-			     const char *trsvcid, const char *host_traddr)
+			     const char *trsvcid, const char *host_traddr,
+			     const char *devname)
 {
 	char argstr[BUF_SIZE];
 	pid_t pid;
 	int rc, db_rc;
 	struct nvme_connection *co = NULL;
+	char *device = NULL;
 
 	db_rc = conndb_add(transport, traddr, trsvcid, host_traddr, &co);
 	if (db_rc != 0 && db_rc != -EEXIST)
@@ -230,7 +232,15 @@ static int monitor_discovery(const char *transport, const char *traddr,
 		co->discovery_pending = 0;
 		co->status = CS_DISC_RUNNING;
 		co->discovery_task = pid;
+		if (devname) {
+			int instance = ctrl_instance(devname);
 
+			if (instance < 0) {
+				msg(LOG_ERR, "unexpected devname: %s\n",
+				    devname);
+			} else
+				co->discovery_instance = instance;
+		}
 		return 0;
 	}
 
@@ -238,12 +248,29 @@ static int monitor_discovery(const char *transport, const char *traddr,
 	free_dispatcher(mon_dsp);
 	conndb_free();
 
-	msg(LOG_NOTICE, "starting discovery\n");
+	conn_msg(LOG_NOTICE, co, "starting discovery in state %s\n",
+		 conn_status_str(co->status));
+
+	/*
+	 * Try to re-use existing controller. do_discovery() will check
+	 * if it matches the connection parameters.
+	 * fabrics_cfg.device must be allocated on the heap!
+	 */
+	if (devname)
+		device = strdup(devname);
+	else if (co->discovery_instance >= 0 &&
+		 asprintf(&device, "nvme%d", co->discovery_instance) == -1)
+		device = NULL;
+
+	if (device)
+		msg(LOG_INFO, "using discovery controller %s\n", device);
+
 	fabrics_cfg.nqn = NVME_DISC_SUBSYS_NAME;
 	fabrics_cfg.transport = transport;
 	fabrics_cfg.traddr = traddr;
-	fabrics_cfg.trsvcid = trsvcid;
-	fabrics_cfg.host_traddr = host_traddr;
+	fabrics_cfg.trsvcid = trsvcid && *trsvcid ? trsvcid : NULL;
+	fabrics_cfg.host_traddr = host_traddr && *host_traddr ? host_traddr : NULL;
+	fabrics_cfg.device = device;
 	/* Without the following, the kernel returns EINVAL */
 	fabrics_cfg.tos = -1;
 	fabrics_cfg.persistent = true;
@@ -252,6 +279,7 @@ static int monitor_discovery(const char *transport, const char *traddr,
 	msg(LOG_DEBUG, "%s\n", argstr);
 	rc = do_discover(argstr, mon_cfg.autoconnect, NORMAL);
 
+	free(device);
 	exit(-rc);
 	/* not reached */
 	return rc;
@@ -270,7 +298,7 @@ static void monitor_handle_fc_uev(struct udev_device *ud)
 				     host_traddr, sizeof(host_traddr)))
 		return;
 
-	monitor_discovery("fc", traddr, NULL, host_traddr);
+	monitor_discovery("fc", traddr, NULL, host_traddr, NULL);
 }
 
 static int monitor_get_nvme_uev_props(struct udev_device *ud,
@@ -338,7 +366,8 @@ static void monitor_handle_nvme_uev(struct udev_device *ud)
 		return;
 
 	monitor_discovery(transport, traddr,
-			  strcmp(trsvcid, "none") ? trsvcid : NULL, host_traddr);
+			  strcmp(trsvcid, "none") ? trsvcid : NULL, host_traddr,
+			  udev_device_get_sysname(ud));
 }
 
 static void monitor_handle_udevice(struct udev_device *ud)
@@ -433,7 +462,7 @@ static int handle_epoll_err(int errcode)
 		if (co->discovery_pending) {
 			msg(LOG_NOTICE, "new discovery pending - restarting\n");
 			monitor_discovery(co->transport, co->traddr,
-					  co->trsvcid, co->host_traddr);
+					  co->trsvcid, co->host_traddr, NULL);
 		}
 	};
 
-- 
2.29.2




More information about the Linux-nvme mailing list