Re: [lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers (v2)

2013-10-25 Thread Serge Hallyn
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)

2013-10-23 Thread S . Çağlar Onur
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