[PATCH rfc 3/6] nvme-tcp: re-resolve traddr upon reconnect in case it is a dns name

Sagi Grimberg sagi at grimberg.me
Mon Jul 24 02:20:19 PDT 2023


In case traddr is a dns name, it may describe a different address
during the controller lifetime. The classic example would be
a discovery-service dns name that may be load-balanced via dns over
multiple addresses.

So try to re-resolve the controller address. There is no dns query
in case the traddr provided is an ip address.

Signed-off-by: Sagi Grimberg <sagi at grimberg.me>
---
 drivers/nvme/host/tcp.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index a47b597ace3e..d44d88d12ea0 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -1917,8 +1917,21 @@ static void nvme_tcp_destroy_admin_queue(struct nvme_ctrl *ctrl, bool remove)
 
 static int nvme_tcp_configure_admin_queue(struct nvme_ctrl *ctrl, bool new)
 {
+	struct nvmf_ctrl_options *opts = ctrl->opts;
 	int error;
 
+	/*
+	 * it is possible that the controller traddr may be a dns name which
+	 * may have changed its ip address since it was last resolved in prior
+	 * connect. Try to re-resolve the address in this case.
+	 */
+	error = nvmf_resolve_ip_address(opts, &to_tcp_ctrl(ctrl)->addr);
+	if (error) {
+		dev_warn(ctrl->device, "unable to resolve address: %s:%s\n",
+			opts->traddr, opts->trsvcid);
+		return error;
+	}
+
 	error = nvme_tcp_alloc_admin_queue(ctrl);
 	if (error)
 		return error;
@@ -2537,13 +2550,6 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev,
 		opts->mask |= NVMF_OPT_TRSVCID;
 	}
 
-	ret = nvmf_resolve_ip_address(opts, &ctrl->addr);
-	if (ret) {
-		pr_err("malformed address passed: %s:%s\n",
-			opts->traddr, opts->trsvcid);
-		goto out_free_ctrl;
-	}
-
 	if (opts->mask & NVMF_OPT_HOST_TRADDR) {
 		ret = inet_pton_with_scope(&init_net, AF_UNSPEC,
 			opts->host_traddr, NULL, &ctrl->src_addr);
-- 
2.41.0




More information about the Linux-nvme mailing list