Hey Noah,

On Thu, 22 Sep 2011, Noah Watkins wrote:
> Change ceph_parse_ips to take either names given as
> IP addresses or standard hostnames (e.g. localhost).
> The DNS lookup is done using the dns_resolver facility
> similar to its use in AFS, NFS, and CIFS.

Currently the dns resolution is handled by mount.ceph and 'rbd map/unmap'.  
I don't think that will go away (at the very least need to support old 
kernels).  

Allowing this in the raw kernel interface would be nice, but I don't think 
we want make DNS_RESOLVER a strict dependency, since it's new, kind of 
kludgey, and a ripe target for compiling out of small or secure kernels.  
Can you make it build either with or without it?

Thanks!
sage


> 
> Signed-off-by: Noah Watkins <[email protected]>
> ---
>  net/ceph/Kconfig     |    1 +
>  net/ceph/messenger.c |  106 
> ++++++++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 95 insertions(+), 12 deletions(-)
> 
> diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
> index be683f2..aac5fc8 100644
> --- a/net/ceph/Kconfig
> +++ b/net/ceph/Kconfig
> @@ -5,6 +5,7 @@ config CEPH_LIB
>       select CRYPTO_AES
>       select CRYPTO
>       select KEYS
> +     select DNS_RESOLVER
>       default n
>       help
>         Choose Y or M here to include cephlib, which provides the
> diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
> index c340e2e..c22aa58 100644
> --- a/net/ceph/messenger.c
> +++ b/net/ceph/messenger.c
> @@ -11,6 +11,7 @@
>  #include <linux/string.h>
>  #include <linux/bio.h>
>  #include <linux/blkdev.h>
> +#include <linux/dns_resolver.h>
>  #include <net/tcp.h>
> 
>  #include <linux/ceph/libceph.h>
> @@ -1078,6 +1079,93 @@ static void addr_set_port(struct
> sockaddr_storage *ss, int p)
>  }
> 
>  /*
> + * Unlike other *_pton function semantics, zero indicates success.
> + */
> +static int ceph_pton(const char *str, size_t len, struct sockaddr_storage 
> *ss,
> +             char delim, const char **ipend)
> +{
> +     struct sockaddr_in *in4 = (void *)ss;
> +     struct sockaddr_in6 *in6 = (void *)ss;
> +
> +     memset(ss, 0, sizeof(*ss));
> +
> +     if (in4_pton(str, len, (u8 *)&in4->sin_addr.s_addr, delim, ipend)) {
> +             ss->ss_family = AF_INET;
> +             return 0;
> +     }
> +
> +     if (in6_pton(str, len, (u8 *)&in6->sin6_addr.s6_addr, delim, ipend)) {
> +             ss->ss_family = AF_INET6;
> +             return 0;
> +     }
> +
> +     return -EINVAL;
> +}
> +
> +/*
> + * Extract hostname string and resolve using kernel DNS facility.
> + */
> +static int ceph_dns_resolve_name(const char *name, size_t namelen,
> +                     struct sockaddr_storage *ss, char delim, const char 
> **ipend)
> +{
> +     const char *end, *delim_p;
> +     char *colon_p, *ip_addr = NULL;
> +     int ip_len, ret;
> +
> +     /*
> +      * The end of the hostname occurs immediately preceding the delimiter or
> +      * the port marker (':') where the delimiter takes precedence.
> +      */
> +     delim_p = memchr(name, delim, namelen);
> +     colon_p = memchr(name, ':', namelen);
> +
> +     if (delim_p && colon_p)
> +             end = delim_p < colon_p ? delim_p : colon_p;
> +     else if (!delim_p && colon_p)
> +             end = colon_p;
> +     else {
> +             end = delim_p;
> +             if (!end) /* case: hostname:/ */
> +                     end = name + namelen;
> +     }
> +
> +     if (end <= name)
> +             return -EINVAL;
> +
> +     /* do dns_resolve upcall */
> +     ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL);
> +     if (ip_len > 0)
> +             ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL);
> +     else
> +             ret = -ESRCH;
> +
> +     kfree(ip_addr);
> +
> +     *ipend = end;
> +
> +     pr_info("resolve '%.*s' (ret=%d): %s\n", (int)(end - name), name,
> +                     ret, ret ? "failed" : ceph_pr_addr(ss));
> +
> +     return ret;
> +}
> +
> +/*
> + * Parse a server name (IP or hostname). If a valid IP address is not found
> + * then try to extract a hostname to resolve using userspace DNS upcall.
> + */
> +static int ceph_parse_server_name(const char *name, size_t namelen,
> +                     struct sockaddr_storage *ss, char delim, const char 
> **ipend)
> +{
> +     int ret;
> +
> +     ret = ceph_pton(name, namelen, ss, delim, ipend);
> +     if (ret)
> +             ret = ceph_dns_resolve_name(name, namelen, ss, delim, ipend);
> +
> +     return ret;
> +}
> +
> +/*
>   * Parse an ip[:port] list into an addr array.  Use the default
>   * monitor port if a port isn't specified.
>   */
> @@ -1085,15 +1173,13 @@ int ceph_parse_ips(const char *c, const char *end,
>                  struct ceph_entity_addr *addr,
>                  int max_count, int *count)
>  {
> -     int i;
> +     int i, ret = -EINVAL;
>       const char *p = c;
> 
>       dout("parse_ips on '%.*s'\n", (int)(end-c), c);
>       for (i = 0; i < max_count; i++) {
>               const char *ipend;
>               struct sockaddr_storage *ss = &addr[i].in_addr;
> -             struct sockaddr_in *in4 = (void *)ss;
> -             struct sockaddr_in6 *in6 = (void *)ss;
>               int port;
>               char delim = ',';
> 
> @@ -1102,15 +1188,11 @@ int ceph_parse_ips(const char *c, const char *end,
>                       p++;
>               }
> 
> -             memset(ss, 0, sizeof(*ss));
> -             if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr,
> -                          delim, &ipend))
> -                     ss->ss_family = AF_INET;
> -             else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
> -                               delim, &ipend))
> -                     ss->ss_family = AF_INET6;
> -             else
> +             ret = ceph_parse_server_name(p, end - p, ss, delim, &ipend);
> +             if (ret)
>                       goto bad;
> +             ret = -EINVAL;
> +
>               p = ipend;
> 
>               if (delim == ']') {
> @@ -1155,7 +1237,7 @@ int ceph_parse_ips(const char *c, const char *end,
> 
>  bad:
>       pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c);
> -     return -EINVAL;
> +     return ret;
>  }
>  EXPORT_SYMBOL(ceph_parse_ips);
> 
> -- 
> 1.7.6.1
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to