From 9da606b4afcc1e47f4b3cdc30578e508bd6aa2f9 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Wed, 1 Apr 2020 14:53:44 -0700 Subject: [PATCH] fabrics: allow traddr to be host name for ip based transports Some users would like to use well known hostnames instead of remembering ip addresses. So, allow users to set traddr to be a host name and we will attempt to resolve against a DNS. This applies for IP based transports only (e.g. tcp, rdma) while fc and loop will ignore this distinction. Signed-off-by: Sagi Grimberg --- fabrics.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/fabrics.c b/fabrics.c index 372bc1d..e73d6ad 100644 --- a/fabrics.c +++ b/fabrics.c @@ -33,6 +33,10 @@ #include #include +#include +#include +#include + #include "util/parser.h" #include "nvme-ioctl.h" #include "nvme-status.h" @@ -857,6 +861,63 @@ static int build_options(char *argstr, int max_len, bool discover) return 0; } +static bool traddr_is_hostname(struct config *cfg) +{ + char addrstr[NVMF_TRADDR_SIZE]; + + if (!cfg->traddr) + return false; + if (strcmp(cfg->transport, "tcp") && strcmp(cfg->transport, "rdma")) + return false; + if (inet_pton(AF_INET, cfg->traddr, addrstr) > 0 || + inet_pton(AF_INET6, cfg->traddr, addrstr) > 0) + return false; + return true; +} + +static int hostname2traddr(struct config *cfg) +{ + struct addrinfo *host_info, hints = {.ai_family = AF_UNSPEC}; + char addrstr[NVMF_TRADDR_SIZE]; + const char *p; + int ret; + + ret = getaddrinfo(cfg->traddr, NULL, &hints, &host_info); + if (ret) { + fprintf(stderr, "failed to resolve host %s info\n", cfg->traddr); + return ret; + } + + switch (host_info->ai_family) { + case AF_INET: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in *)host_info->ai_addr)->sin_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + case AF_INET6: + p = inet_ntop(host_info->ai_family, + &(((struct sockaddr_in6 *)host_info->ai_addr)->sin6_addr), + addrstr, NVMF_TRADDR_SIZE); + break; + default: + fprintf(stderr, "unrecognized address family (%d) %s\n", + host_info->ai_family, cfg->traddr); + ret = -EINVAL; + goto free_addrinfo; + } + + if (!p) { + fprintf(stderr, "failed to get traddr for %s\n", cfg->traddr); + ret = -errno; + goto free_addrinfo; + } + cfg->traddr = strdup(addrstr); + +free_addrinfo: + freeaddrinfo(host_info); + return ret; +} + static int connect_ctrl(struct nvmf_disc_rsp_page_entry *e) { char argstr[BUF_SIZE], *p; @@ -1230,6 +1291,12 @@ static int discover_from_conf_file(const char *desc, char *argstr, if (cfg.persistent && !cfg.keep_alive_tmo) cfg.keep_alive_tmo = NVMF_DEF_DISC_TMO; + if (traddr_is_hostname(&cfg)) { + ret = hostname2traddr(&cfg); + if (ret) + goto out; + } + err = build_options(argstr, BUF_SIZE, true); if (err) { ret = err; @@ -1294,6 +1361,13 @@ int fabrics_discover(const char *desc, int argc, char **argv, bool connect) } else { if (cfg.persistent && !cfg.keep_alive_tmo) cfg.keep_alive_tmo = NVMF_DEF_DISC_TMO; + + if (traddr_is_hostname(&cfg)) { + ret = hostname2traddr(&cfg); + if (ret) + goto out; + } + ret = build_options(argstr, BUF_SIZE, true); if (ret) goto out; @@ -1338,6 +1412,12 @@ int fabrics_connect(const char *desc, int argc, char **argv) if (ret) goto out; + if (traddr_is_hostname(&cfg)) { + ret = hostname2traddr(&cfg); + if (ret) + goto out; + } + ret = build_options(argstr, BUF_SIZE, false); if (ret) goto out; -- 2.49.0