On Mon, Sep 16, 2013 at 02:26:47PM -0400, S.Çağlar Onur wrote:
> get_ips accepts an interface name as a parameter but there was no
> way to get the interfaces names from the container. This patch
> introduces a new get_interfaces call to the API so that users
> can obtain the name of the interfaces.
> 
> Signed-off-by: S.Çağlar Onur <cag...@10ur.org>

I think I'm fine with this version:

One quick comment though, wouldn't we expect get_interfaces() to return
all the interfaces by default, including loopback, including those
without addresses and those that aren't standard packet based IP
interfaces?

I still think we don't want to list loopback addresses in get_ips(), at
least by default, but I think I'd expect get_interfaces to return me all
the existing interfaces without filtering. Does that make sense?

> ---
>  src/lxc/lxccontainer.c | 117 
> ++++++++++++++++++++++++++++++++++---------------
>  src/lxc/lxccontainer.h |   1 +
>  src/lxc/utils.c        |  22 +++++++++-
>  src/lxc/utils.h        |   1 +
>  4 files changed, 105 insertions(+), 36 deletions(-)
> 
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 79237df..6aa59fc 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct 
> lxc_container *c, const char *key)
>       return ret == 0;
>  }
>  
> -char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* 
> family, int scope)
> -{
> -     int count = 0;
> -     struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> -     char addressOutputBuffer[INET6_ADDRSTRLEN];
> -     void *tempAddrPtr = NULL;
> -     char **addresses = NULL, **temp;
> -     char *address = NULL;
> +static inline void exit_from_ns(struct lxc_container *c, int *old_netns, int 
> *new_netns) {
> +     /* Switch back to original netns */
> +     if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
> +             SYSERROR("failed to setns");
> +     if (*new_netns >= 0)
> +             close(*new_netns);
> +     if (*old_netns >= 0)
> +             close(*old_netns);
> +}
> +
> +static inline bool enter_to_ns(struct lxc_container *c, int *old_netns, int 
> *new_netns) {
> +     int ret = 0;
>       char new_netns_path[MAXPATHLEN];
> -     int old_netns = -1, new_netns = -1, ret = 0;
>  
>       if (!c->is_running(c))
>               goto out;
>  
>       /* Save reference to old netns */
> -     old_netns = open("/proc/self/ns/net", O_RDONLY);
> -     if (old_netns < 0) {
> +     *old_netns = open("/proc/self/ns/net", O_RDONLY);
> +     if (*old_netns < 0) {
>               SYSERROR("failed to open /proc/self/ns/net");
>               goto out;
>       }
> @@ -1205,16 +1208,78 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
> interface, char* family, in
>       if (ret < 0 || ret >= MAXPATHLEN)
>               goto out;
>  
> -     new_netns = open(new_netns_path, O_RDONLY);
> -     if (new_netns < 0) {
> +     *new_netns = open(new_netns_path, O_RDONLY);
> +     if (*new_netns < 0) {
>               SYSERROR("failed to open %s", new_netns_path);
>               goto out;
>       }
>  
> -     if (setns(new_netns, CLONE_NEWNET)) {
> +     if (setns(*new_netns, CLONE_NEWNET)) {
>               SYSERROR("failed to setns");
>               goto out;
>       }
> +     return true;
> +out:
> +     exit_from_ns(c, old_netns, new_netns);
> +     return false;
> +}
> +
> +static char** lxcapi_get_interfaces(struct lxc_container *c)
> +{
> +     int count = 0;
> +     struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> +     char **interfaces = NULL, **temp;
> +     int old_netns = -1, new_netns = -1;
> +
> +     if (!enter_to_ns(c, &old_netns, &new_netns))
> +             goto out;
> +
> +     /* Grab the list of interfaces */
> +     if (getifaddrs(&interfaceArray)) {
> +             SYSERROR("failed to get interfaces list");
> +             goto out;
> +     }
> +
> +     /* Iterate through the interfaces */
> +     for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = 
> tempIfAddr->ifa_next) {
> +             /* filter out loopback interface */
> +             if(tempIfAddr->ifa_addr == NULL || 
> tempIfAddr->ifa_addr->sa_family != AF_PACKET || strcmp("lo", 
> tempIfAddr->ifa_name) == 0)
> +                     continue;
> +
> +        count += 1;
> +        temp = realloc(interfaces, count * sizeof(*interfaces));
> +        if (!temp) {
> +            count -= 1;
> +            goto out;
> +        }
> +        interfaces = temp;
> +        interfaces[count - 1] = strdup(tempIfAddr->ifa_name);
> +    }
> +
> +out:
> +     if(interfaceArray)
> +             freeifaddrs(interfaceArray);
> +
> +     exit_from_ns(c, &old_netns, &new_netns);
> +
> +     /* Append NULL to the array */
> +     interfaces = (char **)lxc_append_null_to_array((void **)interfaces, 
> count);
> +
> +     return interfaces;
> +}
> +
> +static char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* 
> family, int scope)
> +{
> +     int count = 0;
> +     struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> +     char addressOutputBuffer[INET6_ADDRSTRLEN];
> +     void *tempAddrPtr = NULL;
> +     char **addresses = NULL, **temp;
> +     char *address = NULL;
> +     int old_netns = -1, new_netns = -1;
> +
> +     if (!enter_to_ns(c, &old_netns, &new_netns))
> +             goto out;
>  
>       /* Grab the list of interfaces */
>       if (getifaddrs(&interfaceArray)) {
> @@ -1243,7 +1308,6 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
> interface, char* family, in
>                       continue;
>               else if (!interface && strcmp("lo", tempIfAddr->ifa_name) == 0)
>                       continue;
> -
>               address = (char *)inet_ntop(tempIfAddr->ifa_addr->sa_family,
>                                          tempAddrPtr,
>                                          addressOutputBuffer,
> @@ -1265,28 +1329,10 @@ out:
>       if(interfaceArray)
>               freeifaddrs(interfaceArray);
>  
> -     /* Switch back to original netns */
> -     if (old_netns >= 0 && setns(old_netns, CLONE_NEWNET))
> -             SYSERROR("failed to setns");
> -     if (new_netns >= 0)
> -             close(new_netns);
> -     if (old_netns >= 0)
> -             close(old_netns);
> +     exit_from_ns(c, &old_netns, &new_netns);
>  
>       /* Append NULL to the array */
> -     if (count) {
> -             count++;
> -             temp = realloc(addresses, count * sizeof(*addresses));
> -             if (!temp) {
> -                     int i;
> -                     for (i = 0; i < count-1; i++)
> -                             free(addresses[i]);
> -                     free(addresses);
> -                     return NULL;
> -             }
> -             addresses = temp;
> -             addresses[count - 1] = NULL;
> -     }
> +     addresses = (char **)lxc_append_null_to_array((void **)addresses, 
> count);
>  
>       return addresses;
>  }
> @@ -2576,6 +2622,7 @@ struct lxc_container *lxc_container_new(const char 
> *name, const char *configpath
>       c->get_config_path = lxcapi_get_config_path;
>       c->set_config_path = lxcapi_set_config_path;
>       c->clone = lxcapi_clone;
> +     c->get_interfaces = lxcapi_get_interfaces;
>       c->get_ips = lxcapi_get_ips;
>       c->attach = lxcapi_attach;
>       c->attach_run_wait = lxcapi_attach_run_wait;
> diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
> index f9ae43b..f17d975 100644
> --- a/src/lxc/lxccontainer.h
> +++ b/src/lxc/lxccontainer.h
> @@ -90,6 +90,7 @@ struct lxc_container {
>        * the length which was our would be printed. */
>       int (*get_config_item)(struct lxc_container *c, const char *key, char 
> *retv, int inlen);
>       int (*get_keys)(struct lxc_container *c, const char *key, char *retv, 
> int inlen);
> +     char** (*get_interfaces)(struct lxc_container *c);
>       char** (*get_ips)(struct lxc_container *c, char* interface, char* 
> family, int scope);
>       /*
>        * get_cgroup_item returns the number of bytes read, or an error (<0).
> diff --git a/src/lxc/utils.c b/src/lxc/utils.c
> index 78b234d..924cc19 100644
> --- a/src/lxc/utils.c
> +++ b/src/lxc/utils.c
> @@ -852,7 +852,7 @@ int lxc_write_to_file(const char *filename, const void* 
> buf, size_t count, bool
>               return -1;
>       ret = lxc_write_nointr(fd, buf, count);
>       if (ret < 0)
> -             goto out_error; 
> +             goto out_error;
>       if ((size_t)ret != count)
>               goto out_error;
>       if (add_newline) {
> @@ -899,3 +899,23 @@ int lxc_read_from_file(const char *filename, void* buf, 
> size_t count)
>       errno = saved_errno;
>       return ret;
>  }
> +
> +void **lxc_append_null_to_array(void **array, size_t count)
> +{
> +     void **temp;
> +
> +     /* Append NULL to the array */
> +     if (count) {
> +             temp = realloc(array, (count + 1) * sizeof(*array));
> +             if (!temp) {
> +                     int i;
> +                     for (i = 0; i < count; i++)
> +                             free(array[i]);
> +                     free(array);
> +                     return NULL;
> +             }
> +             array = temp;
> +             array[count] = NULL;
> +     }
> +     return array;
> +}
> diff --git a/src/lxc/utils.h b/src/lxc/utils.h
> index ba7cfb3..55f98fa 100644
> --- a/src/lxc/utils.h
> +++ b/src/lxc/utils.h
> @@ -236,4 +236,5 @@ extern void lxc_free_array(void **array, lxc_free_fn 
> element_free_fn);
>  extern size_t lxc_array_len(void **array);
>  extern void **lxc_dup_array(void **array, lxc_dup_fn element_dup_fn, 
> lxc_free_fn element_free_fn);
>  
> +extern void **lxc_append_null_to_array(void **array, size_t count);
>  #endif
> -- 
> 1.8.1.2
> 
> 
> ------------------------------------------------------------------------------
> LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
> 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
> 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
> Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
> http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com

Attachment: signature.asc
Description: Digital signature

------------------------------------------------------------------------------
LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to