Re: [lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers (v2)
Quoting S.Çağlar Onur (cag...@10ur.org): list_active_containers parses /proc/net/unix which can contain multiple entries for the same container; : 0002 0001 0001 01 273672 @/var/lib/lxc/6/command : 0002 0001 0001 01 274395 @/var/lib/lxc/5/command : 0002 0001 0001 01 273890 @/var/lib/lxc/4/command : 0002 0001 0001 01 273141 @/var/lib/lxc/3/command : 0002 0001 0001 01 273915 @/var/lib/lxc/2/command : 0002 0001 0001 01 273683 @/var/lib/lxc/1/command : 0002 0001 0001 01 273074 @/var/lib/lxc/0/command : 0002 0001 0001 01 273931 @/var/lib/lxc/9/command : 0002 0001 0001 01 273110 @/var/lib/lxc/8/command : 0002 0001 0001 01 273390 @/var/lib/lxc/7/command : 0003 0001 03 275903 @/var/lib/lxc/8/command : 0003 0001 03 276043 @/var/lib/lxc/1/command : 0003 0001 03 273301 @/var/lib/lxc/0/command : 0003 0001 03 275650 @/var/lib/lxc/4/command On this system list_active_containers returns 14 containers while only 10 containers are running. Following patch; * Introduces array_contains function to do a binary search on given array, * Starts to sort arrays inside the add_to_clist and add_to_names functions, * Consumes array_contains in list_active_containers to eliminate duplicates, * Replaces the linear search code in lxcapi_get_interfaces with the new function. Changes since v1: * Do not load containers if a if a container list is not passed in * Fix possible memory leaks in lxcapi_get_ips and lxcapi_get_interfaces if realloc fails Signed-off-by: S.Çağlar Onur cag...@10ur.org Thanks - this looks great. Acked-by: Serge E. Hallyn serge.hal...@ubuntu.com --- src/lxc/lxccontainer.c | 207 ++--- 1 file changed, 126 insertions(+), 81 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6e6c38c..5b9a14a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1242,12 +1242,81 @@ out: return false; } +// used by qsort and bsearch functions for comparing names +static inline int string_cmp(char **first, char **second) +{ + return strcmp(*first, *second); +} + +// used by qsort and bsearch functions for comparing container names +static inline int container_cmp(struct lxc_container **first, struct lxc_container **second) +{ + return strcmp((*first)-name, (*second)-name); +} + +static bool add_to_array(char ***names, char *cname, int pos) +{ + char **newnames = realloc(*names, (pos+1) * sizeof(char *)); + if (!newnames) { + ERROR(Out of memory); + return false; + } + + *names = newnames; + newnames[pos] = strdup(cname); + if (!newnames[pos]) + return false; + + // sort the arrray as we will use binary search on it + qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + + return true; +} + +static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos) +{ + struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *)); + if (!newlist) { + ERROR(Out of memory); + return false; + } + + *list = newlist; + newlist[pos] = c; + + // sort the arrray as we will use binary search on it + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp); + + return true; +} + +static char** get_from_array(char ***names, char *cname, int size) +{ + return (char **)bsearch(cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp); +} + + +static bool array_contains(char ***names, char *cname, int size) { + if(get_from_array(names, cname, size) != NULL) + return true; + return false; +} + +static bool remove_from_array(char ***names, char *cname, int size) +{ + char **result = get_from_array(names, cname, size); + if (result != NULL) { + free(result); + return true; + } + return false; +} + static char** lxcapi_get_interfaces(struct lxc_container *c) { - int count = 0, i; - bool found = false; + int i, count = 0; struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; - char **interfaces = NULL, **temp; + char **interfaces = NULL; int old_netns = -1, new_netns = -1;
[lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers (v2)
list_active_containers parses /proc/net/unix which can contain multiple entries for the same container; : 0002 0001 0001 01 273672 @/var/lib/lxc/6/command : 0002 0001 0001 01 274395 @/var/lib/lxc/5/command : 0002 0001 0001 01 273890 @/var/lib/lxc/4/command : 0002 0001 0001 01 273141 @/var/lib/lxc/3/command : 0002 0001 0001 01 273915 @/var/lib/lxc/2/command : 0002 0001 0001 01 273683 @/var/lib/lxc/1/command : 0002 0001 0001 01 273074 @/var/lib/lxc/0/command : 0002 0001 0001 01 273931 @/var/lib/lxc/9/command : 0002 0001 0001 01 273110 @/var/lib/lxc/8/command : 0002 0001 0001 01 273390 @/var/lib/lxc/7/command : 0003 0001 03 275903 @/var/lib/lxc/8/command : 0003 0001 03 276043 @/var/lib/lxc/1/command : 0003 0001 03 273301 @/var/lib/lxc/0/command : 0003 0001 03 275650 @/var/lib/lxc/4/command On this system list_active_containers returns 14 containers while only 10 containers are running. Following patch; * Introduces array_contains function to do a binary search on given array, * Starts to sort arrays inside the add_to_clist and add_to_names functions, * Consumes array_contains in list_active_containers to eliminate duplicates, * Replaces the linear search code in lxcapi_get_interfaces with the new function. Changes since v1: * Do not load containers if a if a container list is not passed in * Fix possible memory leaks in lxcapi_get_ips and lxcapi_get_interfaces if realloc fails Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 207 ++--- 1 file changed, 126 insertions(+), 81 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6e6c38c..5b9a14a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1242,12 +1242,81 @@ out: return false; } +// used by qsort and bsearch functions for comparing names +static inline int string_cmp(char **first, char **second) +{ + return strcmp(*first, *second); +} + +// used by qsort and bsearch functions for comparing container names +static inline int container_cmp(struct lxc_container **first, struct lxc_container **second) +{ + return strcmp((*first)-name, (*second)-name); +} + +static bool add_to_array(char ***names, char *cname, int pos) +{ + char **newnames = realloc(*names, (pos+1) * sizeof(char *)); + if (!newnames) { + ERROR(Out of memory); + return false; + } + + *names = newnames; + newnames[pos] = strdup(cname); + if (!newnames[pos]) + return false; + + // sort the arrray as we will use binary search on it + qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + + return true; +} + +static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos) +{ + struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *)); + if (!newlist) { + ERROR(Out of memory); + return false; + } + + *list = newlist; + newlist[pos] = c; + + // sort the arrray as we will use binary search on it + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp); + + return true; +} + +static char** get_from_array(char ***names, char *cname, int size) +{ + return (char **)bsearch(cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp); +} + + +static bool array_contains(char ***names, char *cname, int size) { + if(get_from_array(names, cname, size) != NULL) + return true; + return false; +} + +static bool remove_from_array(char ***names, char *cname, int size) +{ + char **result = get_from_array(names, cname, size); + if (result != NULL) { + free(result); + return true; + } + return false; +} + static char** lxcapi_get_interfaces(struct lxc_container *c) { - int count = 0, i; - bool found = false; + int i, count = 0; struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; - char **interfaces = NULL, **temp; + char **interfaces = NULL; int old_netns = -1, new_netns = -1; if (!enter_to_ns(c, old_netns, new_netns)) @@ -1261,51 +1330,41 @@ static char** lxcapi_get_interfaces(struct lxc_container *c) /* Iterate through the interfaces