Re: [lxc-devel] [PATCH 2/2] add statistics to lxc-info

2013-11-05 Thread Dwight Engen
On Mon, 4 Nov 2013 18:12:15 -0500
Stéphane Graber  wrote:

> On Mon, Nov 04, 2013 at 05:35:19PM -0500, Dwight Engen wrote:
> > - added list_all_containers() which returns both defined and
> >   active containers.
> > 
> > - allow lxc-info to show more than one container, using regex for
> > the name
> > 
> 
> Wouldn't it be better to have list_all_containers be similar to
> list_(active|running)_containers and allow the caller to choose
> whether it wants to get a list of names or a list of lxc_container?

Hi Stéphane, yes I think it would be good to have them consistent. I
looked at that briefly, but the existing routines for building the
array might need refactoring or at least another parameter, and I
didn't need the "list" of containers in my use case. Let me look into it
a bit more, I'm sure it can be done :)
 
> > Signed-off-by: Dwight Engen 
> > ---
> >  doc/lxc-info.sgml.in   |  65 -
> >  src/lxc/lxc_info.c | 257
> > +
> > src/lxc/lxccontainer.c |  47 + src/lxc/lxccontainer.h |   2
> > + 4 files changed, 349 insertions(+), 22 deletions(-)
> > 
> > diff --git a/doc/lxc-info.sgml.in b/doc/lxc-info.sgml.in
> > index 819d5ca..791d780 100644
> > --- a/doc/lxc-info.sgml.in
> > +++ b/doc/lxc-info.sgml.in
> > @@ -47,20 +47,22 @@ Foundation, Inc., 51 Franklin Street, Fifth
> > Floor, Boston, MA 02110-1301 USA 
> >  
> >lxc-info
> > -  -n name
> > +  -n name
> >-c KEY
> >-s
> >-p
> >-i
> >-t state
> > +  -S
> > +  -H
> >  
> >
> >  
> >
> >  Description
> >  
> > -  lxc-info queries and shows information
> > about a
> > -  container.
> > +  lxc-info queries and shows information
> > about
> > +  containers.
> >  
> >
> >  
> > @@ -70,11 +72,20 @@ Foundation, Inc., 51 Franklin Street, Fifth
> > Floor, Boston, MA 02110-1301 USA 
> >
> >  
> > -  -n name
> > +  -n
> > name 
> >  
> >
> > -The container name.
> > +The container name. It is interpreted as a regular
> > expression,
> > +so it is possible to get information on all
> > containers, several
> > +of them or just one. See
> > +
> > +
> > regex
> > +7
> > + for regular expression syntax. If not
> > specified,
> > +name will default to '.*'
> > which
> > +will give information on all containers in
> > +lxcpath.
> >
> >  
> >
> > @@ -126,6 +137,41 @@ Foundation, Inc., 51 Franklin Street, Fifth
> > Floor, Boston, MA 02110-1301 USA 
> >
> >  
> > +  -S
> > +
> > +
> > +  
> > +Just print the container's statistics.
> > +Note that for performance reasons the kernel does not
> > account
> > +kernel memory use unless a kernel memory limit is set.
> > If a limit
> > +is not set, lxc-info will display
> > kernel memory
> > +use as 0. A limit can be set by specifying
> > +
> > +lxc.cgroup.memory.kmem.limit_in_bytes =
> > number
> > +
> > +in your container configuration file, see
> > +
> > +  lxc.conf
> > +  5
> > +.
> > +  
> > +
> > +  
> > +
> > +  
> > +
> > +  -H
> > +
> > +
> > +  
> > +Print the container's statistics in raw, non-humanized
> > form. The
> > +default is to print statistics in humanized form.
> > +  
> > +
> > +  
> > +
> > +  
> > +
> >-t
> > state 
> >  
> > @@ -152,6 +198,15 @@ Foundation, Inc., 51 Franklin Street, Fifth
> > Floor, Boston, MA 02110-1301 USA 
> >  
> >
> > +lxc-info -n 'ubuntu.*'
> > +
> > +  
> > +Show information for all containers whose name starts
> > with ubuntu.
> > +  
> > +
> > +  
> > +
> > +  
> >  lxc-info -n foo -t RUNNING
> >  
> >
> > diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c
> > index aeaf9a8..a05d610 100644
> > --- a/src/lxc/lxc_info.c
> > +++ b/src/lxc/lxc_info.c
> > @@ -25,11 +25,14 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> >  
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  
> >  #include "commands.h"
> > @@ -38,6 +41,8 @@
> >  static bool ips;
> >  static bool state;
> >  static bool pid;
> > +static bool stats;
> > +static bool humanize = true;
> >  static char *test_state = NULL;
> >  static char **key = NULL;
> >  static int keys = 0;
> > @@ -53,6 +58,8 @@ static int my_parser(struct lxc_arguments* args,
> > int c, char* arg) case 'i': ips = true; break;
> > case 's': state = true; break;
> > ca

Re: [lxc-devel] [PATCH 1/1] resolve lxcpath and rcfile arguments

2013-11-05 Thread Serge Hallyn
Quoting Stéphane Graber (stgra...@ubuntu.com):
> On Mon, Nov 04, 2013 at 02:44:44PM -0600, Serge Hallyn wrote:
> > So we don't always have to give full paths.
> > 
> > realpath(x,NULL) mallocs memory, but these paths shouldn't get called
> > from the API so not freeing should be ok.
> > 
> 
> What's the reason behind this change?

Simply that as I test unprivileged lxc I'm having to do

lxc-create -t ubuntu-cloud -P /home/serge/lxcbase -f 
/home/serge/lxc.conf -n a1 -- -r saucy
lxc-start -P /home/serge/lxcbase -n a1
lxc-stop -P /home/serge/lxcbase -n a1 -K

and it gets a bit old.  But maybe (in the fresh light of morning) I'm better
off adding a per-user lxc.conf file that specifies default lxcpath and
lxc.conf to use.

> Am I reading this right that this will only affect cases where -P is
> passed and that the default value won't be resolved?
> 
> In any case, I suspect this change is incomplete since we also support
> -P in some of the python tools which wouldn't be resolved, leading to
> lxc-info and others to fail to find the container (if for example
> /var/lib/lxc is a symlink to say /data/containers).
> 
> 
> > Signed-off-by: Serge Hallyn 
> > ---
> >  src/lxc/arguments.c   |  9 -
> >  src/lxc/lxc_execute.c | 10 +++---
> >  src/lxc/lxc_start.c   |  9 +
> >  3 files changed, 24 insertions(+), 4 deletions(-)
> > 
> > diff --git a/src/lxc/arguments.c b/src/lxc/arguments.c
> > index adcf8fe..65b2284 100644
> > --- a/src/lxc/arguments.c
> > +++ b/src/lxc/arguments.c
> > @@ -155,6 +155,7 @@ See the %s man page for further information.\n\n",
> >  static int lxc_arguments_lxcpath_add(struct lxc_arguments *args,
> >  const char *lxcpath)
> >  {
> > +   char *resolved_path = NULL;
> > if (args->lxcpath_additional != -1 &&
> > args->lxcpath_cnt > args->lxcpath_additional) {
> > fprintf(stderr, "This command only accepts %d -P,--lxcpath 
> > arguments\n",
> > @@ -168,7 +169,13 @@ static int lxc_arguments_lxcpath_add(struct 
> > lxc_arguments *args,
> > lxc_error(args, "no memory");
> > return -ENOMEM;
> > }
> > -   args->lxcpath[args->lxcpath_cnt++] = lxcpath;
> > +   resolved_path = realpath(lxcpath, NULL);
> > +   if (!resolved_path) {
> > +   perror("realpath");
> > +   fprintf(stderr, "Error resolving lxcpath %s", lxcpath);
> > +   return -1;
> > +   }
> > +   args->lxcpath[args->lxcpath_cnt++] = resolved_path;
> > return 0;
> >  }
> >  
> > diff --git a/src/lxc/lxc_execute.c b/src/lxc/lxc_execute.c
> > index 6a54bf6..083b5db 100644
> > --- a/src/lxc/lxc_execute.c
> > +++ b/src/lxc/lxc_execute.c
> > @@ -105,9 +105,13 @@ int main(int argc, char *argv[])
> > return -1;
> >  
> > /* rcfile is specified in the cli option */
> > -   if (my_args.rcfile)
> > -   rcfile = (char *)my_args.rcfile;
> > -   else {
> > +   if (my_args.rcfile) {
> > +   rcfile = realpath((char *)my_args.rcfile, NULL);
> > +   if (!rcfile) {
> > +   SYSERROR("Failed to resolve file path: %s", 
> > my_args.rcfile);
> > +   return -1;
> > +   }
> > +   } else {
> > int rc;
> >  
> > rc = asprintf(&rcfile, "%s/%s/config", my_args.lxcpath[0], 
> > my_args.name);
> > diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c
> > index add2542..7eea26a 100644
> > --- a/src/lxc/lxc_start.c
> > +++ b/src/lxc/lxc_start.c
> > @@ -173,6 +173,15 @@ int main(int argc, char *argv[])
> >  
> > const char *lxcpath = my_args.lxcpath[0];
> >  
> > +   if (my_args.rcfile) {
> > +   char *r = realpath(my_args.rcfile, NULL);
> > +   if (!r) {
> > +   SYSERROR("Failure resolving path: %s", my_args.rcfile);
> > +   exit(1);
> > +   }
> > +   my_args.rcfile = r;
> > +   }
> > +
> > /*
> >  * rcfile possibilities:
> >  * 1. rcfile from random path specified in cli option
> > -- 
> > 1.8.1.2
> > 
> > 
> > --
> > November Webinars for C, C++, Fortran Developers
> > Accelerate application performance with scalable programming models. Explore
> > techniques for threading, error checking, porting, and tuning. Get the most 
> > from the latest Intel processors and coprocessors. See abstracts and 
> > register
> > http://pubads.g.doubleclick.net/gampad/clk?id=60136231&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



--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error ch

[lxc-devel] [PATCH v2] fix leak when a veth.pair name is specified

2013-11-05 Thread Dwight Engen
Please do not apply the previous version of this patch, it is wrong. I
didn't take into account that priv is a union, so priv.veth_attr.pair
is only a pointer when netdev type is VETH. The following patch works
when non-veth nics are also present.

--

Signed-off-by: Dwight Engen 
---
 src/lxc/conf.c|  2 ++
 src/lxc/confile.c | 14 +-
 2 files changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 2a47e77..c131259 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -3308,6 +3308,8 @@ static void lxc_remove_nic(struct lxc_list *it)
free(netdev->link);
if (netdev->name)
free(netdev->name);
+   if (netdev->type == LXC_NET_VETH && netdev->priv.veth_attr.pair)
+   free(netdev->priv.veth_attr.pair);
if (netdev->upscript)
free(netdev->upscript);
if (netdev->hwaddr)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index 680d260..0e0b7e8 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -453,19 +453,7 @@ static struct lxc_netdev *network_netdev(const char *key, 
const char *value,
 
 static int network_ifname(char **valuep, const char *value)
 {
-   if (strlen(value) >= IFNAMSIZ) {
-   ERROR("interface name '%s' too long (>%d)\n",
-   value, IFNAMSIZ - 1);
-   return -1;
-   }
-
-   *valuep = strdup(value);
-   if (!*valuep) {
-   ERROR("failed to dup string '%s'", value);
-   return -1;
-   }
-
-   return 0;
+   return config_string_item_max(valuep, value, IFNAMSIZ);
 }
 
 #ifndef MACVLAN_MODE_PRIVATE
-- 
1.8.3.1


--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [lxc/lxc] 650200: allow lxcapi_get_cgroup_item() on lxc-execute cont...

2013-11-05 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: 6502006a44d27a27fe1e2d9d8cac721c0ec8907a
  https://github.com/lxc/lxc/commit/6502006a44d27a27fe1e2d9d8cac721c0ec8907a
  Author: Dwight Engen 
  Date:   2013-11-05 (Tue, 05 Nov 2013)

  Changed paths:
M src/lxc/lxccontainer.c

  Log Message:
  ---
  allow lxcapi_get_cgroup_item() on lxc-execute containers

Containers started with lxc-execute may not have a conf, but
nothing in the implementation of lxcapi_get_cgroup_item()
actually needs/uses it, and it can be useful to get items out
of the containers' cgroup items.

Signed-off-by: Dwight Engen 
Acked-by: Stéphane Graber 


  Commit: 8585f20444203f9fb9970d1b176c38e0efd62ea8
  https://github.com/lxc/lxc/commit/8585f20444203f9fb9970d1b176c38e0efd62ea8
  Author: Dwight Engen 
  Date:   2013-11-05 (Tue, 05 Nov 2013)

  Changed paths:
M src/lua-lxc/core.c
M src/lua-lxc/lxc.lua
M src/lua-lxc/test/apitest.lua

  Log Message:
  ---
  lua: add cmd_get_config_item to API

Signed-off-by: Dwight Engen 
Acked-by: Stéphane Graber 


  Commit: c9bb9a85ef570a4669d188f191e08cdd601d0ee5
  https://github.com/lxc/lxc/commit/c9bb9a85ef570a4669d188f191e08cdd601d0ee5
  Author: Dwight Engen 
  Date:   2013-11-05 (Tue, 05 Nov 2013)

  Changed paths:
M src/lxc/conf.c
M src/lxc/confile.c

  Log Message:
  ---
  fix leak when a veth.pair name is specified

Signed-off-by: Dwight Engen 
Acked-by: Stéphane Graber 


Compare: https://github.com/lxc/lxc/compare/2752ecec3232...c9bb9a85ef57
--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH v2 0/4] add statistics to lxc-info

2013-11-05 Thread Dwight Engen
Hi Stéphane,

I was able to add the ***containers output fairly in a fairly
straightforward manner. I also split out the patch into more discrete
logical changes, adding/refactoring the list.c test and fixing a leak in
list_active_containers() along the way. Serge, hopefully you don't mind
I renamed a couple of variables in there that were confusing me :)

Out of curiosity, I'm wondering why we chose to use an array instead of
a list? I suppose its easier for the caller and it does make it easy
to use qsort, but OTOH I guess we could've done sorted inserts into a
list as well. I was thinking about realloc() with a large number of
containers being eventually slow, but I guess its only a bunch of
pointers so it won't ever be all that large of a chunk for realloc to
move. Anyway, its working fine right now.

--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH v2 2/4] tests list: refactor and add test for list_all_containers()

2013-11-05 Thread Dwight Engen
Signed-off-by: Dwight Engen 
---
 src/tests/list.c | 97 +---
 1 file changed, 36 insertions(+), 61 deletions(-)

diff --git a/src/tests/list.c b/src/tests/list.c
index a061542..af41e7f 100644
--- a/src/tests/list.c
+++ b/src/tests/list.c
@@ -21,90 +21,53 @@
 #include 
 #include 
 
-int main(int argc, char *argv[])
+static void test_list_func(const char *lxcpath, const char *type,
+  int (*func)(const char *path, char ***names,
+  struct lxc_container ***cret))
 {
-   char *lxcpath = NULL;
+   int i, n, n2;
struct lxc_container **clist;
char **names;
-   int i, n, n2;
-
-   if (argc > 1)
-   lxcpath = argv[1];
 
-   printf("Counting defined containers only\n");
-   n = list_defined_containers(lxcpath, NULL, NULL);
-   printf("Found %d defined containers\n", n);
-   printf("Looking for defined containers only\n");
-   n2 = list_defined_containers(lxcpath, NULL, &clist);
+   printf("%-10s Counting containers\n", type);
+   n = func(lxcpath, NULL, NULL);
+   printf("%-10s Counted %d containers\n", type, n);
+   printf("%-10s Get container struct only\n", type);
+   n2 = func(lxcpath, NULL, &clist);
if (n2 != n)
printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; iname);
+   printf("%-10s  Got container struct %s\n", type, c->name);
lxc_container_put(c);
}
-   if (n2 > 0)
+   if (n2 > 0) {
free(clist);
-
-   printf("Looking for defined names only\n");
-   n2 = list_defined_containers(lxcpath, &names, NULL);
-   if (n2 != n)
-   printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; i 0)
-   free(names);
 
-   printf("Looking for defined names and containers\n");
-   n2 = list_defined_containers(lxcpath, &names, &clist);
+   printf("%-10s Get names only\n", type);
+   n2 = func(lxcpath, &names, NULL);
if (n2 != n)
printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; iname, 
names[i]);
+   for (i = 0; i < n2; i++) {
+   printf("%-10s  Got container name %s\n", type, names[i]);
free(names[i]);
-   lxc_container_put(c);
}
if (n2 > 0) {
free(names);
-   free(clist);
+   names = NULL;
}
 
-
-   printf("Counting active containers only\n");
-   n = list_active_containers(lxcpath, NULL, NULL);
-   printf("Found %d active containers\n", n);
-   printf("Looking for active containers only\n");
-   n2 = list_active_containers(lxcpath, NULL, &clist);
+   printf("%-10s Get names and containers\n", type);
+   n2 = func(lxcpath, &names, &clist);
if (n2 != n)
printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; iname);
-   lxc_container_put(clist[i]);
-   }
-   if (n2 > 0)
-   free(clist);
-
-   printf("Looking for active names only\n");
-   n2 = list_active_containers(lxcpath, &names, NULL);
-   if (n2 != n)
-   printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; i 0)
-   free(names);
-
-   printf("Looking for active names and containers\n");
-   n2 = list_active_containers(lxcpath, &names, &clist);
-   if (n2 != n)
-   printf("Warning: first call returned %d, second %d\n", n, n2);
-   for (i=0; iname, 
names[i]);
+   printf("%-10s  Got container struct %s, name %s\n", type, 
c->name, names[i]);
+   if (strcmp(c->name, names[i]))
+   fprintf(stderr, "ERROR: name mismatch!\n");
free(names[i]);
lxc_container_put(c);
}
@@ -112,6 +75,18 @@ int main(int argc, char *argv[])
free(names);
free(clist);
}
+}
+
+int main(int argc, char *argv[])
+{
+   char *lxcpath = NULL;
+
+   if (argc > 1)
+   lxcpath = argv[1];
+
+   test_list_func(lxcpath, "Defined:", list_defined_containers);
+   test_list_func(lxcpath, "Active:", list_active_containers);
+   test_list_func(lxcpath, "All:", list_all_containers);
 
exit(0);
 }
-- 
1.8.3.1


--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@list

[lxc-devel] [PATCH v2 4/4] add statistics to lxc-info

2013-11-05 Thread Dwight Engen
- allow lxc-info to show more than one container, using regex for the name

Signed-off-by: Dwight Engen 
---
 doc/lxc-info.sgml.in |  65 -
 src/lxc/lxc_info.c   | 257 +++
 2 files changed, 300 insertions(+), 22 deletions(-)

diff --git a/doc/lxc-info.sgml.in b/doc/lxc-info.sgml.in
index 819d5ca..791d780 100644
--- a/doc/lxc-info.sgml.in
+++ b/doc/lxc-info.sgml.in
@@ -47,20 +47,22 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA 02110-1301 USA
   
 
   lxc-info
-  -n name
+  -n name
   -c KEY
   -s
   -p
   -i
   -t state
+  -S
+  -H
 
   
 
   
 Description
 
-  lxc-info queries and shows information about a
-  container.
+  lxc-info queries and shows information about
+  containers.
 
   
 
@@ -70,11 +72,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA 02110-1301 USA
 
   
 
-  -n name
+  -n 
name
 
 
   
-The container name.
+The container name. It is interpreted as a regular expression,
+so it is possible to get information on all containers, several
+of them or just one. See
+
+ regex
+7
+ for regular expression syntax. If not specified,
+name will default to '.*' which
+will give information on all containers in
+lxcpath.
   
 
   
@@ -126,6 +137,41 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA 02110-1301 USA
 
   
 
+  -S
+
+
+  
+Just print the container's statistics.
+Note that for performance reasons the kernel does not account
+kernel memory use unless a kernel memory limit is set. If a limit
+is not set, lxc-info will display kernel memory
+use as 0. A limit can be set by specifying
+
+lxc.cgroup.memory.kmem.limit_in_bytes = 
number
+
+in your container configuration file, see
+
+  lxc.conf
+  5
+.
+  
+
+  
+
+  
+
+  -H
+
+
+  
+Print the container's statistics in raw, non-humanized form. The
+default is to print statistics in humanized form.
+  
+
+  
+
+  
+
   -t 
state
 
 
@@ -152,6 +198,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
MA 02110-1301 USA
   
 
   
+lxc-info -n 'ubuntu.*'
+
+  
+Show information for all containers whose name starts with ubuntu.
+  
+
+  
+
+  
 lxc-info -n foo -t RUNNING
 
   
diff --git a/src/lxc/lxc_info.c b/src/lxc/lxc_info.c
index aeaf9a8..ba43f37 100644
--- a/src/lxc/lxc_info.c
+++ b/src/lxc/lxc_info.c
@@ -25,11 +25,14 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 
 #include 
 #include 
+#include 
 #include 
 
 #include "commands.h"
@@ -38,6 +41,8 @@
 static bool ips;
 static bool state;
 static bool pid;
+static bool stats;
+static bool humanize = true;
 static char *test_state = NULL;
 static char **key = NULL;
 static int keys = 0;
@@ -53,6 +58,8 @@ static int my_parser(struct lxc_arguments* args, int c, char* 
arg)
case 'i': ips = true; break;
case 's': state = true; break;
case 'p': pid = true; break;
+   case 'S': stats = true; break;
+   case 'H': humanize = false; break;
case 't': test_state = arg; break;
}
return 0;
@@ -63,6 +70,8 @@ static const struct option my_longopts[] = {
{"ips", no_argument, 0, 'i'},
{"state", no_argument, 0, 's'},
{"pid", no_argument, 0, 'p'},
+   {"stats", no_argument, 0, 'S'},
+   {"no-humanize", no_argument, 0, 'H'},
{"state-is", required_argument, 0, 't'},
LXC_COMMON_OPTIONS,
 };
@@ -79,33 +88,177 @@ Options :\n\
   -c, --config=KEY  show configuration variable KEY from running 
container\n\
   -i, --ips shows the IP addresses\n\
   -p, --pid shows the process id of the init container\n\
+  -S, --stats   shows usage stats\n\
+  -H, --no-humanize shows stats as raw numbers, not humanized\n\
   -s, --state   shows the state of the container\n\
   -t, --state-is=STATE  test if current state is STATE\n\
 returns success if it matches, false otherwise\n",
+   .name = ".*",
.options  = my_longopts,
.parser   = my_parser,
.checker  = NULL,
 };
 
-int main(int argc, char *argv[])
+static void str_chomp(char *buf)
 {
-   struct lxc_container *c;
+   char *ch;
 
-   int i;
+   /* remove trailing whitespace from buf */
+   for(ch = &bu

[lxc-devel] [PATCH v2 3/4] fix leak in list_active_containers()

2013-11-05 Thread Dwight Engen
Found by running the lxc-test-list test with valgrind. The names were
put into a local array, and never freed in the success case where the
caller didn't want the names returned and in the early out failure case.

Note we don't need to check the return from remove_from_array() because
we just successfully added the name above.

Signed-off-by: Dwight Engen 
---
 src/lxc/lxccontainer.c | 72 --
 1 file changed, 35 insertions(+), 37 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index d7d3273..d57b23c 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -19,6 +19,7 @@
  */
 
 #define _GNU_SOURCE
+#include 
 #include 
 #include 
 #include 
@@ -3096,12 +3097,13 @@ free_bad:
return -1;
 }
 
-int list_active_containers(const char *lxcpath, char ***names, struct 
lxc_container ***cret)
+int list_active_containers(const char *lxcpath, char ***nret,
+  struct lxc_container ***cret)
 {
-   int i, cfound = 0, nfound = 0;
+   int i, ret = -1, cret_cnt = 0, ct_name_cnt = 0;
int lxcpath_len;
char *line = NULL;
-   char **unique_names = NULL;
+   char **ct_name = NULL;
size_t len = 0;
struct lxc_container *c;
 
@@ -3111,8 +3113,8 @@ int list_active_containers(const char *lxcpath, char 
***names, struct lxc_contai
 
if (cret)
*cret = NULL;
-   if (names)
-   *names = NULL;
+   if (nret)
+   *nret = NULL;
 
process_lock();
FILE *f = fopen("/proc/net/unix", "r");
@@ -3140,27 +3142,22 @@ int list_active_containers(const char *lxcpath, char 
***names, struct lxc_contai
continue;
*p2 = '\0';
 
-   if (array_contains(&unique_names, p, nfound))
+   if (array_contains(&ct_name, p, ct_name_cnt))
continue;
 
-   if (!add_to_array(&unique_names, p, nfound))
-   goto free_bad;
+   if (!add_to_array(&ct_name, p, ct_name_cnt))
+   goto free_cret_list;
 
-   cfound++;
+   ct_name_cnt++;
 
-   if (!cret) {
-   nfound++;
+   if (!cret)
continue;
-   }
 
c = lxc_container_new(p, lxcpath);
if (!c) {
INFO("Container %s:%s is running but could not be 
loaded",
lxcpath, p);
-   if (names) {
-   if(!remove_from_array(&unique_names, p, 
cfound--))
-   goto free_bad;
-   }
+   remove_from_array(&ct_name, p, ct_name_cnt--);
continue;
}
 
@@ -3170,42 +3167,43 @@ int list_active_containers(const char *lxcpath, char 
***names, struct lxc_contai
 * fact that the command socket exists.
 */
 
-   if (!add_to_clist(cret, c, nfound, true)) {
+   if (!add_to_clist(cret, c, cret_cnt, true)) {
lxc_container_put(c);
-   goto free_bad;
+   goto free_cret_list;
}
-   nfound++;
+   cret_cnt++;
}
 
-   if (names)
-   *names = unique_names;
-
-   if (line)
-   free(line);
-
-   process_lock();
-   fclose(f);
-   process_unlock();
-   return nfound;
+   assert(!nret || !cret || cret_cnt == ct_name_cnt);
+   ret = ct_name_cnt;
+   if (nret)
+   *nret = ct_name;
+   else
+   goto free_ct_name;
+   goto out;
 
-free_bad:
-   if (names && *names) {
-   for (i=0; ihttp://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH v2 1/4] add list_all_containers(), returns defined and active containers

2013-11-05 Thread Dwight Engen
Signed-off-by: Dwight Engen 
---
 src/lxc/lxccontainer.c | 97 +++---
 src/lxc/lxccontainer.h | 10 ++
 2 files changed, 103 insertions(+), 4 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 89b45ed..d7d3273 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1403,7 +1403,7 @@ static bool add_to_array(char ***names, char *cname, int 
pos)
return true;
 }
 
-static bool add_to_clist(struct lxc_container ***list, struct lxc_container 
*c, int pos)
+static bool add_to_clist(struct lxc_container ***list, struct lxc_container 
*c, int pos, bool sort)
 {
struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct 
lxc_container *));
if (!newlist) {
@@ -1415,7 +1415,8 @@ static bool add_to_clist(struct lxc_container ***list, 
struct lxc_container *c,
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);
+   if (sort)
+   qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int 
(*)(const void *,const void *))container_cmp);
 
return true;
 }
@@ -3066,7 +3067,7 @@ int list_defined_containers(const char *lxcpath, char 
***names, struct lxc_conta
continue;
}
 
-   if (!add_to_clist(cret, c, nfound)) {
+   if (!add_to_clist(cret, c, nfound, true)) {
lxc_container_put(c);
goto free_bad;
}
@@ -3169,7 +3170,7 @@ int list_active_containers(const char *lxcpath, char 
***names, struct lxc_contai
 * fact that the command socket exists.
 */
 
-   if (!add_to_clist(cret, c, nfound)) {
+   if (!add_to_clist(cret, c, nfound, true)) {
lxc_container_put(c);
goto free_bad;
}
@@ -3206,3 +3207,91 @@ free_bad:
process_unlock();
return -1;
 }
+
+int list_all_containers(const char *lxcpath, char ***nret,
+   struct lxc_container ***cret)
+{
+   int i, ret, active_cnt, ct_cnt, ct_list_cnt;
+   char **active_name;
+   char **ct_name;
+   struct lxc_container **ct_list = NULL;
+
+   ct_cnt = list_defined_containers(lxcpath, &ct_name, NULL);
+   if (ct_cnt < 0)
+   return ct_cnt;
+
+   active_cnt = list_active_containers(lxcpath, &active_name, NULL);
+   if (active_cnt < 0) {
+   ret = active_cnt;
+   goto free_ct_name;
+   }
+
+   for (i = 0; i < active_cnt; i++) {
+   if (!array_contains(&ct_name, active_name[i], ct_cnt)) {
+   if (!add_to_array(&ct_name, active_name[i], ct_cnt)) {
+   ret = -1;
+   goto free_active_name;
+   }
+   ct_cnt++;
+   }
+   free(active_name[i]);
+   active_name[i] = NULL;
+   }
+   free(active_name);
+   active_name = NULL;
+   active_cnt = 0;
+
+   qsort(ct_name, ct_cnt, sizeof(char *),
+ (int (*)(const void *,const void *))string_cmp);
+
+   for (i = 0, ct_list_cnt = 0; i < ct_cnt && cret; i++) {
+   struct lxc_container *c;
+
+   c = lxc_container_new(ct_name[i], lxcpath);
+   if (!c) {
+   WARN("Container %s:%s could not be loaded", lxcpath, 
ct_name[i]);
+   remove_from_array(&ct_name, ct_name[i], ct_cnt--);
+   continue;
+   }
+
+   if (!add_to_clist(&ct_list, c, ct_list_cnt, false)) {
+   lxc_container_put(c);
+   ret = -1;
+   goto free_ct_list;
+   }
+   ct_list_cnt++;
+   }
+
+   if (cret)
+   *cret = ct_list;
+
+   if (nret)
+   *nret = ct_name;
+   else {
+   ret = ct_cnt;
+   goto free_ct_name;
+   }
+   return ct_cnt;
+
+free_ct_list:
+   for (i = 0; i < ct_list_cnt; i++) {
+   lxc_container_put(ct_list[i]);
+   }
+   if (ct_list)
+   free(ct_list);
+
+free_active_name:
+   for (i = 0; i < active_cnt; i++) {
+   if (active_name[i])
+   free(active_name[i]);
+   }
+   if (active_name)
+   free(active_name);
+
+free_ct_name:
+   for (i = 0; i < ct_cnt; i++) {
+   free(ct_name[i]);
+   }
+   free(ct_name);
+   return ret;
+}
diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h
index 762e1b0..486035a 100644
--- a/src/lxc/lxccontainer.h
+++ b/src/lxc/lxccontainer.h
@@ -277,6 +277,16 @@ int list_defined_containers(const char *lxcpath, char 
***names, 

[lxc-devel] [lxc/lxc] 3da0fe: Only include execinfo.h if MUTEX_DEBUGGING is set

2013-11-05 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: 3da0feef099c7da83352525fe4930dc9f7a3df82
  https://github.com/lxc/lxc/commit/3da0feef099c7da83352525fe4930dc9f7a3df82
  Author: Stéphane Graber 
  Date:   2013-11-05 (Tue, 05 Nov 2013)

  Changed paths:
M src/lxc/utils.c

  Log Message:
  ---
  Only include execinfo.h if MUTEX_DEBUGGING is set

Signed-off-by: Stéphane Graber 



--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [RFC 0/2] Enabling unprivileged containers

2013-11-05 Thread Serge Hallyn
With this patchset I am able to create and run ubuntu-cloud containers
as non-root user.  Note this requires an uptodate ubuntu trusty host to
get a userns-enabled kernel.  The steps:

1. install uidmap
sudo apt-get install uidmap
2. make sure to have a range of allocated subuids, i.e.
sudo usermod -v 10-19 -w 10-19 serge
3. make sure to allocate some nics
echo "serge veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet
4. set yourseulf up in cgroups which you own:
for c in /sys/fs/cgroup/*; do
sudo mkdir $c/serge;
sudo chown -R serge: $c/serge;
if [ `basename $c` = "cpuset" ]; then
echo 0 > $c/serge/cpuset.{cpus,mems}
fi
echo $$ > $c/serge/tasks;
done
5. write a lxc.conf
cat > ~/lxc.conf << EOF
lxc.network.type = veth
lxc.network.link = lxcbr0
lxc.network.flags = up
lxc.id_map = u 0 10 1
lxc.id_map = g 0 10 1
EOF
6. create an lxcpath for yourself
mkdir /home/serge/lxcbase
7. you'll need to make lxc-user-nic setuid-root (as Makefile isn't doing that):
sudo chmod u+s /usr/bin/lxc-user-nic

Now create the container:
lxc-create -P /home/serge/lxcbase -n a1 -f /home/serge/lxc.conf -t 
ubuntu-cloud -- -r saucy
and start it:
lxc-start -P /home/serge/lxcbase -n a1
You can stop it or open a console:
lxc-console -P /home/serge/lxcbase -n a1
lxc-stop -P /home/serge/lxcbase -n a1 -k

You can't yet delete such a container very easily.  (sudo and
lxc-usernsexec being the obvious ways)

It's not complete, but it's a start and doesn't (AFAICS) adversely affect
privileged use.

-serge

--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [RFC 2/2] lxc-user-nic: rename nic inside container to desired name

2013-11-05 Thread Serge Hallyn
To do so we do a quick setns into the container's netns.  This
(unexpectedly) turns out cleaner than trying to rename it from
lxc_setup(), because we don't know the original nic name in
the container until we created it which we do in the parent
after the init has been cloned.

Signed-off-by: Serge Hallyn 
---
 src/lxc/conf.c |   2 +-
 src/lxc/lxc_user_nic.c | 168 +
 2 files changed, 158 insertions(+), 12 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index afdaa14..5e1e18d 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2761,7 +2761,7 @@ int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t 
pid)
 
// Call lxc-user-nic pid type bridge
char pidstr[20];
-   char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, NULL };
+   char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, 
netdev->name, NULL };
snprintf(pidstr, 19, "%lu", (unsigned long) pid);
pidstr[19] = '\0';
execvp("lxc-user-nic", args);
diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
index bc1c268..dc35e55 100644
--- a/src/lxc/lxc_user_nic.c
+++ b/src/lxc/lxc_user_nic.c
@@ -17,6 +17,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#define _GNU_SOURCE /* See feature_test_macros(7) */
 #include 
 #include 
 #include 
@@ -27,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -39,9 +41,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 #include "config.h"
+#include "utils.h"
 
 #ifndef HAVE_GETLINE
 #ifdef HAVE_FGETLN
@@ -49,6 +55,19 @@
 #endif
 #endif
 
+/* Define setns() if missing from the C library */
+#ifndef HAVE_SETNS
+static inline int setns(int fd, int nstype)
+{
+#ifdef __NR_setns
+   return syscall(__NR_setns, fd, nstype);
+#else
+   errno = ENOSYS;
+   return -1;
+#endif
+}
+#endif
+
 #if ISTEST
 #define CONF_FILE "/tmp/lxc-usernet"
 #define DB_FILE "/tmp/nics"
@@ -94,7 +113,8 @@
 
 void usage(char *me, bool fail)
 {
-   fprintf(stderr, "Usage: %s pid type bridge\n", me);
+   fprintf(stderr, "Usage: %s pid type bridge nicname\n", me);
+   fprintf(stderr, " nicname is the name to use inside the container\n");
exit(fail ? 1 : 0);
 }
 
@@ -237,12 +257,13 @@ bool nic_exists(char *nic)
return true;
 }
 
-#if ! ISTEST
 struct link_req {
struct nlmsg nlmsg;
struct ifinfomsg ifinfomsg;
 };
 
+#if ! ISTEST
+
 int lxc_veth_create(const char *name1, const char *name2)
 {
struct nl_handler nlh;
@@ -539,7 +560,7 @@ int lxc_netdev_delete_by_name(const char *name)
 
 #endif
 
-bool create_nic(char *nic, char *br, char *pidstr)
+bool create_nic(char *nic, char *br, char *pidstr, char **cnic)
 {
 #if ISTEST
char path[200];
@@ -559,7 +580,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
 
ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic);
if (ret < 0 || ret >= IFNAMSIZ) {
-   fprintf(stderr, "nic name too long\n");
+   fprintf(stderr, "host nic name too long\n");
exit(1);
}
 
@@ -581,6 +602,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid);
goto out_del;
}
+   *cnic = strdup(veth2buf);
return true;
 
 out_del:
@@ -589,14 +611,19 @@ out_del:
 #endif
 }
 
-void get_new_nicname(char **dest, char *br, char *pid)
+/*
+ * Get a new nic.
+ * *dest will container the name (lxcuser-%d) which is attached
+ * on the host to the lxc bridge
+ */
+void get_new_nicname(char **dest, char *br, char *pid, char **cnic)
 {
int i = 0;
// TODO - speed this up.  For large installations we won't
// want n stats for every nth container startup.
while (1) {
sprintf(*dest, "lxcuser-%d", i);
-   if (!nic_exists(*dest) && create_nic(*dest, br, pid))
+   if (!nic_exists(*dest) && create_nic(*dest, br, pid, cnic))
return;
i++;
}
@@ -672,7 +699,7 @@ int count_entries(char *buf, off_t len, char *me, char *t, 
char *br)
  * The dbfile has lines of the format:
  * user type bridge nicname
  */
-bool get_nic_if_avail(int fd, char *me, char *pid, char *intype, char *br, int 
allowed, char **nicname)
+bool get_nic_if_avail(int fd, char *me, char *pid, char *intype, char *br, int 
allowed, char **nicname, char **cnic)
 {
off_t len, slen;
struct stat sb;
@@ -696,7 +723,7 @@ bool get_nic_if_avail(int fd, char *me, char *pid, char 
*intype, char *br, int a
}
 
 
-   get_new_nicname(nicname, br, pid);
+   get_new_nicname(nicname, br, pid, cnic);
/* me  ' ' intype ' ' br ' ' *nicname + '\n' + '\0' */
slen = strlen(me) + strlen(intype) + strlen(br) + strlen(*nicname) + 5;
newline = alloca(slen);
@@ -743

[lxc-devel] [RFC 1/2] create_run_template: tell the template what caller's uid was mapped to

2013-11-05 Thread Serge Hallyn
conf.c/conf.h: have replaced bool hostid_is_mapped() with int mapped_hostid()
   which returns the mapped uid for the caller's uid on the host, or -1 if
   none

create_run_template: pass caller's uid into template.

lxc-ubuntu-cloud:
1. accept --mapped-uid argument
2. don't write to devices cgroup - not allowed.
3. if running in userns, use $HOME/.cache
4. chown cached files to the uid to which our caller was
   mapped
5. ignore /dev when extracting rootfs in a userns

Signed-off-by: Serge Hallyn 
---
 src/lxc/conf.c|  6 +++---
 src/lxc/conf.h|  2 +-
 src/lxc/lxccontainer.c| 38 ++
 templates/lxc-ubuntu-cloud.in | 25 +++--
 4 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 2a47e77..afdaa14 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2912,7 +2912,7 @@ uid_t get_mapped_rootid(struct lxc_conf *conf)
return (uid_t)-1;
 }
 
-bool hostid_is_mapped(int id, struct lxc_conf *conf)
+int mapped_hostid(int id, struct lxc_conf *conf)
 {
struct lxc_list *it;
struct id_map *map;
@@ -2921,9 +2921,9 @@ bool hostid_is_mapped(int id, struct lxc_conf *conf)
if (map->idtype != ID_TYPE_UID)
continue;
if (id >= map->hostid && id < map->hostid + map->range)
-   return true;
+   return (id - map->hostid) + map->nsid;
}
-   return false;
+   return -1;
 }
 
 int find_unmapped_nsuid(struct lxc_conf *conf)
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 71399b9..940d493 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -362,7 +362,7 @@ extern void lxc_rename_phys_nics_on_shutdown(struct 
lxc_conf *conf);
 
 extern uid_t get_mapped_rootid(struct lxc_conf *conf);
 extern int find_unmapped_nsuid(struct lxc_conf *conf);
-extern bool hostid_is_mapped(int id, struct lxc_conf *conf);
+extern int mapped_hostid(int id, struct lxc_conf *conf);
 extern int chown_mapped_root(char *path, struct lxc_conf *conf);
 extern int ttys_shift_ids(struct lxc_conf *c);
 #endif
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 946133d..594a96d 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -916,20 +916,28 @@ static bool create_run_template(struct lxc_container *c, 
char *tpath, bool quiet
 * If we're running the template in a mapped userns, then
 * we prepend the template command with:
 * lxc-usernsexec <-m map1> ... <-m mapn> --
+* and we append "--mapped-uid x", where x is the mapped uid
+* for our geteuid()
 */
if (geteuid() != 0 && !lxc_list_empty(&conf->id_map)) {
int n2args = 1;
+   char txtuid[20];
char **n2 = malloc(n2args * sizeof(*n2));
struct lxc_list *it;
struct id_map *map;
 
+   if (!n2) {
+   SYSERROR("out of memory");
+   exit(1);
+   }
newargv[0] = tpath;
tpath = "lxc-usernsexec";
n2[0] = "lxc-usernsexec";
lxc_list_for_each(it, &conf->id_map) {
map = it->elem;
n2args += 2;
-   n2 = realloc(n2, n2args * sizeof(*n2));
+   n2 = realloc(n2, n2args * sizeof(char *));
+INFO("allocated %d items to n2", n2args);
if (!n2)
exit(1);
n2[n2args-2] = "-m";
@@ -942,15 +950,15 @@ static bool create_run_template(struct lxc_container *c, 
char *tpath, bool quiet
if (ret < 0 || ret >= 200)
exit(1);
}
-   bool hostid_mapped = hostid_is_mapped(geteuid(), conf);
-   int extraargs = hostid_mapped ?  1 : 3;
-   n2 = realloc(n2, (nargs + n2args + extraargs) * 
sizeof(*n2));
+   int hostid_mapped = mapped_hostid(geteuid(), conf);
+   int extraargs = hostid_mapped >= 0 ?  1 : 3;
+   n2 = realloc(n2, (nargs + n2args + extraargs) * 
sizeof(char *));
if (!n2)
exit(1);
-   if (!hostid_mapped) {
-   int free_id = find_unmapped_nsuid(conf);
+   if (hostid_mapped < 0) {
+   hostid_mapped = find_unmapped_nsuid(conf);
n2[n2args++] = "-m";
-   if (f

Re: [lxc-devel] [RFC 0/2] Enabling unprivileged containers

2013-11-05 Thread Stéphane Graber
On Tue, Nov 05, 2013 at 02:12:58PM -0600, Serge Hallyn wrote:
> With this patchset I am able to create and run ubuntu-cloud containers
> as non-root user.  Note this requires an uptodate ubuntu trusty host to
> get a userns-enabled kernel.  The steps:
> 
> 1. install uidmap
>   sudo apt-get install uidmap
> 2. make sure to have a range of allocated subuids, i.e.
>   sudo usermod -v 10-19 -w 10-19 serge
> 3. make sure to allocate some nics
>   echo "serge veth lxcbr0 2" | sudo tee -a /etc/lxc/lxc-usernet
> 4. set yourseulf up in cgroups which you own:
>   for c in /sys/fs/cgroup/*; do
>   sudo mkdir $c/serge;
>   sudo chown -R serge: $c/serge;
>   if [ `basename $c` = "cpuset" ]; then
>   echo 0 > $c/serge/cpuset.{cpus,mems}
>   fi
>   echo $$ > $c/serge/tasks;
>   done
> 5. write a lxc.conf
>   cat > ~/lxc.conf << EOF
> lxc.network.type = veth
> lxc.network.link = lxcbr0
> lxc.network.flags = up
> lxc.id_map = u 0 10 1
> lxc.id_map = g 0 10 1
> EOF
> 6. create an lxcpath for yourself
>   mkdir /home/serge/lxcbase
> 7. you'll need to make lxc-user-nic setuid-root (as Makefile isn't doing 
> that):
>   sudo chmod u+s /usr/bin/lxc-user-nic

Why isn't the Makefile doing that?

> 
> Now create the container:
>   lxc-create -P /home/serge/lxcbase -n a1 -f /home/serge/lxc.conf -t 
> ubuntu-cloud -- -r saucy
> and start it:
>   lxc-start -P /home/serge/lxcbase -n a1
> You can stop it or open a console:
>   lxc-console -P /home/serge/lxcbase -n a1
>   lxc-stop -P /home/serge/lxcbase -n a1 -k
> 
> You can't yet delete such a container very easily.  (sudo and
> lxc-usernsexec being the obvious ways)
> 
> It's not complete, but it's a start and doesn't (AFAICS) adversely affect
> privileged use.
> 
> -serge
> 
> --
> November Webinars for C, C++, Fortran Developers
> Accelerate application performance with scalable programming models. Explore
> techniques for threading, error checking, porting, and tuning. Get the most 
> from the latest Intel processors and coprocessors. See abstracts and register
> http://pubads.g.doubleclick.net/gampad/clk?id=60136231&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


signature.asc
Description: Digital signature
--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [RFC 1/2] create_run_template: tell the template what caller's uid was mapped to

2013-11-05 Thread Stéphane Graber
On Tue, Nov 05, 2013 at 02:14:33PM -0600, Serge Hallyn wrote:
> conf.c/conf.h: have replaced bool hostid_is_mapped() with int mapped_hostid()
>which returns the mapped uid for the caller's uid on the host, or -1 if
>none
> 
> create_run_template: pass caller's uid into template.
> 
> lxc-ubuntu-cloud:
>   1. accept --mapped-uid argument
>   2. don't write to devices cgroup - not allowed.
>   3. if running in userns, use $HOME/.cache
>   4. chown cached files to the uid to which our caller was
>  mapped
>   5. ignore /dev when extracting rootfs in a userns
> 
> Signed-off-by: Serge Hallyn 

There is just one info statement that looks a bit off a bit below, but
with that one dropped or properly indented:

Acked-by: Stéphane Graber 

> ---
>  src/lxc/conf.c|  6 +++---
>  src/lxc/conf.h|  2 +-
>  src/lxc/lxccontainer.c| 38 ++
>  templates/lxc-ubuntu-cloud.in | 25 +++--
>  4 files changed, 57 insertions(+), 14 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index 2a47e77..afdaa14 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -2912,7 +2912,7 @@ uid_t get_mapped_rootid(struct lxc_conf *conf)
>   return (uid_t)-1;
>  }
>  
> -bool hostid_is_mapped(int id, struct lxc_conf *conf)
> +int mapped_hostid(int id, struct lxc_conf *conf)
>  {
>   struct lxc_list *it;
>   struct id_map *map;
> @@ -2921,9 +2921,9 @@ bool hostid_is_mapped(int id, struct lxc_conf *conf)
>   if (map->idtype != ID_TYPE_UID)
>   continue;
>   if (id >= map->hostid && id < map->hostid + map->range)
> - return true;
> + return (id - map->hostid) + map->nsid;
>   }
> - return false;
> + return -1;
>  }
>  
>  int find_unmapped_nsuid(struct lxc_conf *conf)
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index 71399b9..940d493 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -362,7 +362,7 @@ extern void lxc_rename_phys_nics_on_shutdown(struct 
> lxc_conf *conf);
>  
>  extern uid_t get_mapped_rootid(struct lxc_conf *conf);
>  extern int find_unmapped_nsuid(struct lxc_conf *conf);
> -extern bool hostid_is_mapped(int id, struct lxc_conf *conf);
> +extern int mapped_hostid(int id, struct lxc_conf *conf);
>  extern int chown_mapped_root(char *path, struct lxc_conf *conf);
>  extern int ttys_shift_ids(struct lxc_conf *c);
>  #endif
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 946133d..594a96d 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -916,20 +916,28 @@ static bool create_run_template(struct lxc_container 
> *c, char *tpath, bool quiet
>* If we're running the template in a mapped userns, then
>* we prepend the template command with:
>* lxc-usernsexec <-m map1> ... <-m mapn> --
> +  * and we append "--mapped-uid x", where x is the mapped uid
> +  * for our geteuid()
>*/
>   if (geteuid() != 0 && !lxc_list_empty(&conf->id_map)) {
>   int n2args = 1;
> + char txtuid[20];
>   char **n2 = malloc(n2args * sizeof(*n2));
>   struct lxc_list *it;
>   struct id_map *map;
>  
> + if (!n2) {
> + SYSERROR("out of memory");
> + exit(1);
> + }
>   newargv[0] = tpath;
>   tpath = "lxc-usernsexec";
>   n2[0] = "lxc-usernsexec";
>   lxc_list_for_each(it, &conf->id_map) {
>   map = it->elem;
>   n2args += 2;
> - n2 = realloc(n2, n2args * sizeof(*n2));
> + n2 = realloc(n2, n2args * sizeof(char *));
> +INFO("allocated %d items to n2", n2args);

^ what happened with indentation here?

>   if (!n2)
>   exit(1);
>   n2[n2args-2] = "-m";
> @@ -942,15 +950,15 @@ static bool create_run_template(struct lxc_container 
> *c, char *tpath, bool quiet
>   if (ret < 0 || ret >= 200)
>   exit(1);
>   }
> - bool hostid_mapped = hostid_is_mapped(geteuid(), conf);
> - int extraargs = hostid_mapped ?  1 : 3;
> - n2 = realloc(n2, (nargs + n2args + extraargs) * 
> sizeof(*n2));
> + int hostid_mapped = mapped_hostid(geteuid(), conf);
> + int extraargs = hostid_mapped >= 0 ?  1 : 3;
> + n2 = realloc(n2, (nargs + n2args + extraargs) * 
> sizeof(char *));
>   if (!n2)
> 

Re: [lxc-devel] [RFC 2/2] lxc-user-nic: rename nic inside container to desired name

2013-11-05 Thread Stéphane Graber
On Tue, Nov 05, 2013 at 02:15:00PM -0600, Serge Hallyn wrote:
> To do so we do a quick setns into the container's netns.  This
> (unexpectedly) turns out cleaner than trying to rename it from
> lxc_setup(), because we don't know the original nic name in
> the container until we created it which we do in the parent
> after the init has been cloned.
> 
> Signed-off-by: Serge Hallyn 

I think it may make sense to centralize that setns definition in
something like namespace.h and the new netlinks function may make sense
in network.c, but we can always do that later.

Acked-by: Stéphane Graber 

> ---
>  src/lxc/conf.c |   2 +-
>  src/lxc/lxc_user_nic.c | 168 
> +
>  2 files changed, 158 insertions(+), 12 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index afdaa14..5e1e18d 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -2761,7 +2761,7 @@ int unpriv_assign_nic(struct lxc_netdev *netdev, pid_t 
> pid)
>  
>   // Call lxc-user-nic pid type bridge
>   char pidstr[20];
> - char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, NULL };
> + char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, 
> netdev->name, NULL };
>   snprintf(pidstr, 19, "%lu", (unsigned long) pid);
>   pidstr[19] = '\0';
>   execvp("lxc-user-nic", args);
> diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
> index bc1c268..dc35e55 100644
> --- a/src/lxc/lxc_user_nic.c
> +++ b/src/lxc/lxc_user_nic.c
> @@ -17,6 +17,7 @@
>   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>   */
>  
> +#define _GNU_SOURCE /* See feature_test_macros(7) */
>  #include 
>  #include 
>  #include 
> @@ -27,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -39,9 +41,13 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
> +#include 
> +#include 
>  #include "config.h"
> +#include "utils.h"
>  
>  #ifndef HAVE_GETLINE
>  #ifdef HAVE_FGETLN
> @@ -49,6 +55,19 @@
>  #endif
>  #endif
>  
> +/* Define setns() if missing from the C library */
> +#ifndef HAVE_SETNS
> +static inline int setns(int fd, int nstype)
> +{
> +#ifdef __NR_setns
> + return syscall(__NR_setns, fd, nstype);
> +#else
> + errno = ENOSYS;
> + return -1;
> +#endif
> +}
> +#endif
> +
>  #if ISTEST
>  #define CONF_FILE "/tmp/lxc-usernet"
>  #define DB_FILE "/tmp/nics"
> @@ -94,7 +113,8 @@
>  
>  void usage(char *me, bool fail)
>  {
> - fprintf(stderr, "Usage: %s pid type bridge\n", me);
> + fprintf(stderr, "Usage: %s pid type bridge nicname\n", me);
> + fprintf(stderr, " nicname is the name to use inside the container\n");
>   exit(fail ? 1 : 0);
>  }
>  
> @@ -237,12 +257,13 @@ bool nic_exists(char *nic)
>   return true;
>  }
>  
> -#if ! ISTEST
>  struct link_req {
>   struct nlmsg nlmsg;
>   struct ifinfomsg ifinfomsg;
>  };
>  
> +#if ! ISTEST
> +
>  int lxc_veth_create(const char *name1, const char *name2)
>  {
>   struct nl_handler nlh;
> @@ -539,7 +560,7 @@ int lxc_netdev_delete_by_name(const char *name)
>  
>  #endif
>  
> -bool create_nic(char *nic, char *br, char *pidstr)
> +bool create_nic(char *nic, char *br, char *pidstr, char **cnic)
>  {
>  #if ISTEST
>   char path[200];
> @@ -559,7 +580,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
>  
>   ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic);
>   if (ret < 0 || ret >= IFNAMSIZ) {
> - fprintf(stderr, "nic name too long\n");
> + fprintf(stderr, "host nic name too long\n");
>   exit(1);
>   }
>  
> @@ -581,6 +602,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
>   fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid);
>   goto out_del;
>   }
> + *cnic = strdup(veth2buf);
>   return true;
>  
>  out_del:
> @@ -589,14 +611,19 @@ out_del:
>  #endif
>  }
>  
> -void get_new_nicname(char **dest, char *br, char *pid)
> +/*
> + * Get a new nic.
> + * *dest will container the name (lxcuser-%d) which is attached
> + * on the host to the lxc bridge
> + */
> +void get_new_nicname(char **dest, char *br, char *pid, char **cnic)
>  {
>   int i = 0;
>   // TODO - speed this up.  For large installations we won't
>   // want n stats for every nth container startup.
>   while (1) {
>   sprintf(*dest, "lxcuser-%d", i);
> - if (!nic_exists(*dest) && create_nic(*dest, br, pid))
> + if (!nic_exists(*dest) && create_nic(*dest, br, pid, cnic))
>   return;
>   i++;
>   }
> @@ -672,7 +699,7 @@ int count_entries(char *buf, off_t len, char *me, char 
> *t, char *br)
>   * The dbfile has lines of the format:
>   * user type bridge nicname
>   */
> -bool get_nic_if_avail(int fd, char *me, char *pid, char *intype, char *br, 
> int allowed, char **nicname)
> +bool get_nic_if_avail(int fd, char *m

Re: [lxc-devel] [RFC 2/2] lxc-user-nic: rename nic inside container to desired name

2013-11-05 Thread Serge Hallyn
Quoting Stéphane Graber (stgra...@ubuntu.com):
> On Tue, Nov 05, 2013 at 02:15:00PM -0600, Serge Hallyn wrote:
> > To do so we do a quick setns into the container's netns.  This
> > (unexpectedly) turns out cleaner than trying to rename it from
> > lxc_setup(), because we don't know the original nic name in
> > the container until we created it which we do in the parent
> > after the init has been cloned.
> > 
> > Signed-off-by: Serge Hallyn 
> 
> I think it may make sense to centralize that setns definition in

Actually lxc-user-nic can #include utils.h.

> something like namespace.h and the new netlinks function may make sense
> in network.c, but we can always do that later.

Yes, most of the network stuff can be consolidated.  I'll aim to clean
that up this week.

> Acked-by: Stéphane Graber 
> 
> > ---
> >  src/lxc/conf.c |   2 +-
> >  src/lxc/lxc_user_nic.c | 168 
> > +
> >  2 files changed, 158 insertions(+), 12 deletions(-)
> > 
> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> > index afdaa14..5e1e18d 100644
> > --- a/src/lxc/conf.c
> > +++ b/src/lxc/conf.c
> > @@ -2761,7 +2761,7 @@ int unpriv_assign_nic(struct lxc_netdev *netdev, 
> > pid_t pid)
> >  
> > // Call lxc-user-nic pid type bridge
> > char pidstr[20];
> > -   char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, NULL };
> > +   char *args[] = { "lxc-user-nic", pidstr, "veth", netdev->link, 
> > netdev->name, NULL };
> > snprintf(pidstr, 19, "%lu", (unsigned long) pid);
> > pidstr[19] = '\0';
> > execvp("lxc-user-nic", args);
> > diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c
> > index bc1c268..dc35e55 100644
> > --- a/src/lxc/lxc_user_nic.c
> > +++ b/src/lxc/lxc_user_nic.c
> > @@ -17,6 +17,7 @@
> >   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> >   */
> >  
> > +#define _GNU_SOURCE /* See feature_test_macros(7) */
> >  #include 
> >  #include 
> >  #include 
> > @@ -27,6 +28,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -39,9 +41,13 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >  #include "config.h"
> > +#include "utils.h"
> >  
> >  #ifndef HAVE_GETLINE
> >  #ifdef HAVE_FGETLN
> > @@ -49,6 +55,19 @@
> >  #endif
> >  #endif
> >  
> > +/* Define setns() if missing from the C library */
> > +#ifndef HAVE_SETNS
> > +static inline int setns(int fd, int nstype)
> > +{
> > +#ifdef __NR_setns
> > +   return syscall(__NR_setns, fd, nstype);
> > +#else
> > +   errno = ENOSYS;
> > +   return -1;
> > +#endif
> > +}
> > +#endif
> > +
> >  #if ISTEST
> >  #define CONF_FILE "/tmp/lxc-usernet"
> >  #define DB_FILE "/tmp/nics"
> > @@ -94,7 +113,8 @@
> >  
> >  void usage(char *me, bool fail)
> >  {
> > -   fprintf(stderr, "Usage: %s pid type bridge\n", me);
> > +   fprintf(stderr, "Usage: %s pid type bridge nicname\n", me);
> > +   fprintf(stderr, " nicname is the name to use inside the container\n");
> > exit(fail ? 1 : 0);
> >  }
> >  
> > @@ -237,12 +257,13 @@ bool nic_exists(char *nic)
> > return true;
> >  }
> >  
> > -#if ! ISTEST
> >  struct link_req {
> > struct nlmsg nlmsg;
> > struct ifinfomsg ifinfomsg;
> >  };
> >  
> > +#if ! ISTEST
> > +
> >  int lxc_veth_create(const char *name1, const char *name2)
> >  {
> > struct nl_handler nlh;
> > @@ -539,7 +560,7 @@ int lxc_netdev_delete_by_name(const char *name)
> >  
> >  #endif
> >  
> > -bool create_nic(char *nic, char *br, char *pidstr)
> > +bool create_nic(char *nic, char *br, char *pidstr, char **cnic)
> >  {
> >  #if ISTEST
> > char path[200];
> > @@ -559,7 +580,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
> >  
> > ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic);
> > if (ret < 0 || ret >= IFNAMSIZ) {
> > -   fprintf(stderr, "nic name too long\n");
> > +   fprintf(stderr, "host nic name too long\n");
> > exit(1);
> > }
> >  
> > @@ -581,6 +602,7 @@ bool create_nic(char *nic, char *br, char *pidstr)
> > fprintf(stderr, "Error moving %s to netns %d\n", veth2buf, pid);
> > goto out_del;
> > }
> > +   *cnic = strdup(veth2buf);
> > return true;
> >  
> >  out_del:
> > @@ -589,14 +611,19 @@ out_del:
> >  #endif
> >  }
> >  
> > -void get_new_nicname(char **dest, char *br, char *pid)
> > +/*
> > + * Get a new nic.
> > + * *dest will container the name (lxcuser-%d) which is attached
> > + * on the host to the lxc bridge
> > + */
> > +void get_new_nicname(char **dest, char *br, char *pid, char **cnic)
> >  {
> > int i = 0;
> > // TODO - speed this up.  For large installations we won't
> > // want n stats for every nth container startup.
> > while (1) {
> > sprintf(*dest, "lxcuser-%d", i);
> > -   if (!nic_exists(*dest) && create_nic(*dest, br, pid))
> > +   if (!nic_exists(*de

Re: [lxc-devel] [RFC 1/2] create_run_template: tell the template what caller's uid was mapped to

2013-11-05 Thread Serge Hallyn
Quoting Stéphane Graber (stgra...@ubuntu.com):
> On Tue, Nov 05, 2013 at 02:14:33PM -0600, Serge Hallyn wrote:
> > conf.c/conf.h: have replaced bool hostid_is_mapped() with int 
> > mapped_hostid()
> >which returns the mapped uid for the caller's uid on the host, or -1 if
> >none
> > 
> > create_run_template: pass caller's uid into template.
> > 
> > lxc-ubuntu-cloud:
> > 1. accept --mapped-uid argument
> > 2. don't write to devices cgroup - not allowed.
> > 3. if running in userns, use $HOME/.cache
> > 4. chown cached files to the uid to which our caller was
> >mapped
> > 5. ignore /dev when extracting rootfs in a userns
> > 
> > Signed-off-by: Serge Hallyn 
> 
> There is just one info statement that looks a bit off a bit below, but
> with that one dropped or properly indented:
> 
> Acked-by: Stéphane Graber 
> 
> > ---
> >  src/lxc/conf.c|  6 +++---
> >  src/lxc/conf.h|  2 +-
> >  src/lxc/lxccontainer.c| 38 ++
> >  templates/lxc-ubuntu-cloud.in | 25 +++--
> >  4 files changed, 57 insertions(+), 14 deletions(-)
> > 
> > diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> > index 2a47e77..afdaa14 100644
> > --- a/src/lxc/conf.c
> > +++ b/src/lxc/conf.c
> > @@ -2912,7 +2912,7 @@ uid_t get_mapped_rootid(struct lxc_conf *conf)
> > return (uid_t)-1;
> >  }
> >  
> > -bool hostid_is_mapped(int id, struct lxc_conf *conf)
> > +int mapped_hostid(int id, struct lxc_conf *conf)
> >  {
> > struct lxc_list *it;
> > struct id_map *map;
> > @@ -2921,9 +2921,9 @@ bool hostid_is_mapped(int id, struct lxc_conf *conf)
> > if (map->idtype != ID_TYPE_UID)
> > continue;
> > if (id >= map->hostid && id < map->hostid + map->range)
> > -   return true;
> > +   return (id - map->hostid) + map->nsid;
> > }
> > -   return false;
> > +   return -1;
> >  }
> >  
> >  int find_unmapped_nsuid(struct lxc_conf *conf)
> > diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> > index 71399b9..940d493 100644
> > --- a/src/lxc/conf.h
> > +++ b/src/lxc/conf.h
> > @@ -362,7 +362,7 @@ extern void lxc_rename_phys_nics_on_shutdown(struct 
> > lxc_conf *conf);
> >  
> >  extern uid_t get_mapped_rootid(struct lxc_conf *conf);
> >  extern int find_unmapped_nsuid(struct lxc_conf *conf);
> > -extern bool hostid_is_mapped(int id, struct lxc_conf *conf);
> > +extern int mapped_hostid(int id, struct lxc_conf *conf);
> >  extern int chown_mapped_root(char *path, struct lxc_conf *conf);
> >  extern int ttys_shift_ids(struct lxc_conf *c);
> >  #endif
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index 946133d..594a96d 100644
> > --- a/src/lxc/lxccontainer.c
> > +++ b/src/lxc/lxccontainer.c
> > @@ -916,20 +916,28 @@ static bool create_run_template(struct lxc_container 
> > *c, char *tpath, bool quiet
> >  * If we're running the template in a mapped userns, then
> >  * we prepend the template command with:
> >  * lxc-usernsexec <-m map1> ... <-m mapn> --
> > +* and we append "--mapped-uid x", where x is the mapped uid
> > +* for our geteuid()
> >  */
> > if (geteuid() != 0 && !lxc_list_empty(&conf->id_map)) {
> > int n2args = 1;
> > +   char txtuid[20];
> > char **n2 = malloc(n2args * sizeof(*n2));
> > struct lxc_list *it;
> > struct id_map *map;
> >  
> > +   if (!n2) {
> > +   SYSERROR("out of memory");
> > +   exit(1);
> > +   }
> > newargv[0] = tpath;
> > tpath = "lxc-usernsexec";
> > n2[0] = "lxc-usernsexec";
> > lxc_list_for_each(it, &conf->id_map) {
> > map = it->elem;
> > n2args += 2;
> > -   n2 = realloc(n2, n2args * sizeof(*n2));
> > +   n2 = realloc(n2, n2args * sizeof(char *));
> > +INFO("allocated %d items to n2", n2args);
> 
> ^ what happened with indentation here?

Good question.  That was for debugging - I'll dd it, thanks.

> > if (!n2)
> > exit(1);
> > n2[n2args-2] = "-m";
> > @@ -942,15 +950,15 @@ static bool create_run_template(struct lxc_container 
> > *c, char *tpath, bool quiet
> > if (ret < 0 || ret >= 200)
> > exit(1);
> > }
> > -   bool hostid_mapped = hostid_is_mapped(geteuid(), conf);
> > -   int extraargs = hostid_mapped ?  1 : 3;
> > -   n2 = realloc(n2, (nargs + n2args + extraargs) * 
> > sizeof(*n2));
> > +   int hostid_mapped 

[lxc-devel] [lxc/lxc] 4012c8: Fix tests on Android

2013-11-05 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: 4012c89148c42dc7c15809bec348746681f96edd
  https://github.com/lxc/lxc/commit/4012c89148c42dc7c15809bec348746681f96edd
  Author: Stéphane Graber 
  Date:   2013-11-05 (Tue, 05 Nov 2013)

  Changed paths:
M src/tests/concurrent.c
M src/tests/console.c
M src/tests/reboot.c
M src/tests/snapshot.c

  Log Message:
  ---
  Fix tests on Android

Signed-off-by: Stéphane Graber 



--
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH v2 1/4] add list_all_containers(), returns defined and active containers

2013-11-05 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> Signed-off-by: Dwight Engen 

Hi,

One comment below:

> ---
>  src/lxc/lxccontainer.c | 97 
> +++---
>  src/lxc/lxccontainer.h | 10 ++
>  2 files changed, 103 insertions(+), 4 deletions(-)
> 
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 89b45ed..d7d3273 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -1403,7 +1403,7 @@ static bool add_to_array(char ***names, char *cname, 
> int pos)
>   return true;
>  }
>  
> -static bool add_to_clist(struct lxc_container ***list, struct lxc_container 
> *c, int pos)
> +static bool add_to_clist(struct lxc_container ***list, struct lxc_container 
> *c, int pos, bool sort)
>  {
>   struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct 
> lxc_container *));
>   if (!newlist) {
> @@ -1415,7 +1415,8 @@ static bool add_to_clist(struct lxc_container ***list, 
> struct lxc_container *c,
>   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);
> + if (sort)
> + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int 
> (*)(const void *,const void *))container_cmp);
>  
>   return true;
>  }
> @@ -3066,7 +3067,7 @@ int list_defined_containers(const char *lxcpath, char 
> ***names, struct lxc_conta
>   continue;
>   }
>  
> - if (!add_to_clist(cret, c, nfound)) {
> + if (!add_to_clist(cret, c, nfound, true)) {
>   lxc_container_put(c);
>   goto free_bad;
>   }
> @@ -3169,7 +3170,7 @@ int list_active_containers(const char *lxcpath, char 
> ***names, struct lxc_contai
>* fact that the command socket exists.
>*/
>  
> - if (!add_to_clist(cret, c, nfound)) {
> + if (!add_to_clist(cret, c, nfound, true)) {
>   lxc_container_put(c);
>   goto free_bad;
>   }
> @@ -3206,3 +3207,91 @@ free_bad:
>   process_unlock();
>   return -1;
>  }
> +
> +int list_all_containers(const char *lxcpath, char ***nret,
> + struct lxc_container ***cret)
> +{
> + int i, ret, active_cnt, ct_cnt, ct_list_cnt;
> + char **active_name;
> + char **ct_name;
> + struct lxc_container **ct_list = NULL;
> +
> + ct_cnt = list_defined_containers(lxcpath, &ct_name, NULL);
> + if (ct_cnt < 0)
> + return ct_cnt;
> +
> + active_cnt = list_active_containers(lxcpath, &active_name, NULL);
> + if (active_cnt < 0) {
> + ret = active_cnt;
> + goto free_ct_name;
> + }
> +
> + for (i = 0; i < active_cnt; i++) {
> + if (!array_contains(&ct_name, active_name[i], ct_cnt)) {
> + if (!add_to_array(&ct_name, active_name[i], ct_cnt)) {
> + ret = -1;
> + goto free_active_name;
> + }
> + ct_cnt++;
> + }
> + free(active_name[i]);
> + active_name[i] = NULL;
> + }
> + free(active_name);
> + active_name = NULL;
> + active_cnt = 0;
> +
> + qsort(ct_name, ct_cnt, sizeof(char *),
> +   (int (*)(const void *,const void *))string_cmp);

Is this qsort needed?  list_defined_containers() and the add_to_array()s
above should each be keeping ct_name ordered if I'm thinking right.

> +
> + for (i = 0, ct_list_cnt = 0; i < ct_cnt && cret; i++) {
> + struct lxc_container *c;
> +
> + c = lxc_container_new(ct_name[i], lxcpath);
> + if (!c) {
> + WARN("Container %s:%s could not be loaded", lxcpath, 
> ct_name[i]);
> + remove_from_array(&ct_name, ct_name[i], ct_cnt--);
> + continue;
> + }
> +
> + if (!add_to_clist(&ct_list, c, ct_list_cnt, false)) {
> + lxc_container_put(c);
> + ret = -1;
> + goto free_ct_list;
> + }
> + ct_list_cnt++;
> + }
> +
> + if (cret)
> + *cret = ct_list;
> +
> + if (nret)
> + *nret = ct_name;
> + else {
> + ret = ct_cnt;
> + goto free_ct_name;
> + }
> + return ct_cnt;
> +
> +free_ct_list:
> + for (i = 0; i < ct_list_cnt; i++) {
> + lxc_container_put(ct_list[i]);
> + }
> + if (ct_list)
> + free(ct_list);
> +
> +free_active_name:
> + for (i = 0; i < active_cnt; i++) {
> + if (active_name[i])
> + free(active_name[i]);
> + }
> + if (active_name)
> + free(active_name);
> +
> +free_ct_name:
> + for (i = 0; i < ct_cnt; i++)

Re: [lxc-devel] [PATCH v2 2/4] tests list: refactor and add test for list_all_containers()

2013-11-05 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> Signed-off-by: Dwight Engen 

Acked-by: Serge E. Hallyn 

> ---
>  src/tests/list.c | 97 
> +---
>  1 file changed, 36 insertions(+), 61 deletions(-)
> 
> diff --git a/src/tests/list.c b/src/tests/list.c
> index a061542..af41e7f 100644
> --- a/src/tests/list.c
> +++ b/src/tests/list.c
> @@ -21,90 +21,53 @@
>  #include 
>  #include 
>  
> -int main(int argc, char *argv[])
> +static void test_list_func(const char *lxcpath, const char *type,
> +int (*func)(const char *path, char ***names,
> +struct lxc_container ***cret))
>  {
> - char *lxcpath = NULL;
> + int i, n, n2;
>   struct lxc_container **clist;
>   char **names;
> - int i, n, n2;
> -
> - if (argc > 1)
> - lxcpath = argv[1];
>  
> - printf("Counting defined containers only\n");
> - n = list_defined_containers(lxcpath, NULL, NULL);
> - printf("Found %d defined containers\n", n);
> - printf("Looking for defined containers only\n");
> - n2 = list_defined_containers(lxcpath, NULL, &clist);
> + printf("%-10s Counting containers\n", type);
> + n = func(lxcpath, NULL, NULL);
> + printf("%-10s Counted %d containers\n", type, n);
> + printf("%-10s Get container struct only\n", type);
> + n2 = func(lxcpath, NULL, &clist);
>   if (n2 != n)
>   printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i + for (i = 0; i < n2; i++) {
>   struct lxc_container *c = clist[i];
> - printf("Found defined container %s\n", c->name);
> + printf("%-10s  Got container struct %s\n", type, c->name);
>   lxc_container_put(c);
>   }
> - if (n2 > 0)
> + if (n2 > 0) {
>   free(clist);
> -
> - printf("Looking for defined names only\n");
> - n2 = list_defined_containers(lxcpath, &names, NULL);
> - if (n2 != n)
> - printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i - printf("Found defined container %s\n", names[i]);
> - free(names[i]);
> + clist = NULL;
>   }
> - if (n2 > 0)
> - free(names);
>  
> - printf("Looking for defined names and containers\n");
> - n2 = list_defined_containers(lxcpath, &names, &clist);
> + printf("%-10s Get names only\n", type);
> + n2 = func(lxcpath, &names, NULL);
>   if (n2 != n)
>   printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i - struct lxc_container *c = clist[i];
> - printf("Found defined container %s, name was %s\n", c->name, 
> names[i]);
> + for (i = 0; i < n2; i++) {
> + printf("%-10s  Got container name %s\n", type, names[i]);
>   free(names[i]);
> - lxc_container_put(c);
>   }
>   if (n2 > 0) {
>   free(names);
> - free(clist);
> + names = NULL;
>   }
>  
> -
> - printf("Counting active containers only\n");
> - n = list_active_containers(lxcpath, NULL, NULL);
> - printf("Found %d active containers\n", n);
> - printf("Looking for active containers only\n");
> - n2 = list_active_containers(lxcpath, NULL, &clist);
> + printf("%-10s Get names and containers\n", type);
> + n2 = func(lxcpath, &names, &clist);
>   if (n2 != n)
>   printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i - printf("Found active container %s\n", clist[i]->name);
> - lxc_container_put(clist[i]);
> - }
> - if (n2 > 0)
> - free(clist);
> -
> - printf("Looking for active names only\n");
> - n2 = list_active_containers(lxcpath, &names, NULL);
> - if (n2 != n)
> - printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i - printf("Found active container %s\n", names[i]);
> - free(names[i]);
> - }
> - if (n2 > 0)
> - free(names);
> -
> - printf("Looking for active names and containers\n");
> - n2 = list_active_containers(lxcpath, &names, &clist);
> - if (n2 != n)
> - printf("Warning: first call returned %d, second %d\n", n, n2);
> - for (i=0; i + for (i = 0; i < n2; i++) {
>   struct lxc_container *c = clist[i];
> - printf("Found active container %s, name was %s\n", c->name, 
> names[i]);
> + printf("%-10s  Got container struct %s, name %s\n", type, 
> c->name, names[i]);
> + if (strcmp(c->name, names[i]))
> + fprintf(stderr, "ERROR: name mismatch!\n");
>   free(names[i]);
>   lxc_container_put(c);
>   }
> @@ -112,6 +75,18 @@ int main(int argc, char *argv[])
>   free(names);
>   free(clist);
>   

Re: [lxc-devel] [PATCH v2 3/4] fix leak in list_active_containers()

2013-11-05 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> Found by running the lxc-test-list test with valgrind. The names were
> put into a local array, and never freed in the success case where the
> caller didn't want the names returned and in the early out failure case.
> 
> Note we don't need to check the return from remove_from_array() because
> we just successfully added the name above.
> 
> Signed-off-by: Dwight Engen 

Acked-by: Serge E. Hallyn 

> ---
>  src/lxc/lxccontainer.c | 72 
> --
>  1 file changed, 35 insertions(+), 37 deletions(-)
> 
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index d7d3273..d57b23c 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -19,6 +19,7 @@
>   */
>  
>  #define _GNU_SOURCE
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -3096,12 +3097,13 @@ free_bad:
>   return -1;
>  }
>  
> -int list_active_containers(const char *lxcpath, char ***names, struct 
> lxc_container ***cret)
> +int list_active_containers(const char *lxcpath, char ***nret,
> +struct lxc_container ***cret)
>  {
> - int i, cfound = 0, nfound = 0;
> + int i, ret = -1, cret_cnt = 0, ct_name_cnt = 0;
>   int lxcpath_len;
>   char *line = NULL;
> - char **unique_names = NULL;
> + char **ct_name = NULL;
>   size_t len = 0;
>   struct lxc_container *c;
>  
> @@ -3111,8 +3113,8 @@ int list_active_containers(const char *lxcpath, char 
> ***names, struct lxc_contai
>  
>   if (cret)
>   *cret = NULL;
> - if (names)
> - *names = NULL;
> + if (nret)
> + *nret = NULL;
>  
>   process_lock();
>   FILE *f = fopen("/proc/net/unix", "r");
> @@ -3140,27 +3142,22 @@ int list_active_containers(const char *lxcpath, char 
> ***names, struct lxc_contai
>   continue;
>   *p2 = '\0';
>  
> - if (array_contains(&unique_names, p, nfound))
> + if (array_contains(&ct_name, p, ct_name_cnt))
>   continue;
>  
> - if (!add_to_array(&unique_names, p, nfound))
> - goto free_bad;
> + if (!add_to_array(&ct_name, p, ct_name_cnt))
> + goto free_cret_list;
>  
> - cfound++;
> + ct_name_cnt++;
>  
> - if (!cret) {
> - nfound++;
> + if (!cret)
>   continue;
> - }
>  
>   c = lxc_container_new(p, lxcpath);
>   if (!c) {
>   INFO("Container %s:%s is running but could not be 
> loaded",
>   lxcpath, p);
> - if (names) {
> - if(!remove_from_array(&unique_names, p, 
> cfound--))
> - goto free_bad;
> - }
> + remove_from_array(&ct_name, p, ct_name_cnt--);
>   continue;
>   }
>  
> @@ -3170,42 +3167,43 @@ int list_active_containers(const char *lxcpath, char 
> ***names, struct lxc_contai
>* fact that the command socket exists.
>*/
>  
> - if (!add_to_clist(cret, c, nfound, true)) {
> + if (!add_to_clist(cret, c, cret_cnt, true)) {
>   lxc_container_put(c);
> - goto free_bad;
> + goto free_cret_list;
>   }
> - nfound++;
> + cret_cnt++;
>   }
>  
> - if (names)
> - *names = unique_names;
> -
> - if (line)
> - free(line);
> -
> - process_lock();
> - fclose(f);
> - process_unlock();
> - return nfound;
> + assert(!nret || !cret || cret_cnt == ct_name_cnt);
> + ret = ct_name_cnt;
> + if (nret)
> + *nret = ct_name;
> + else
> + goto free_ct_name;
> + goto out;
>  
> -free_bad:
> - if (names && *names) {
> - for (i=0; i - free((*names)[i]);
> - free(*names);
> - }
> +free_cret_list:
>   if (cret && *cret) {
> - for (i=0; i + for (i = 0; i < cret_cnt; i++)
>   lxc_container_put((*cret)[i]);
>   free(*cret);
>   }
> +
> +free_ct_name:
> + if (ct_name) {
> + for (i = 0; i < ct_name_cnt; i++)
> + free(ct_name[i]);
> + free(ct_name);
> + }
> +
> +out:
>   if (line)
>   free(line);
>  
>   process_lock();
>   fclose(f);
>   process_unlock();
> - return -1;
> + return ret;
>  }
>  
>  int list_all_containers(const char *lxcpath, char ***nret,
> -- 
> 1.8.3.1
> 
> 
> --
> November Webinars for C, C++, Fortran Developers
> Accelerate application performance with scalable programming mo

Re: [lxc-devel] [PATCH v2 1/4] add list_all_containers(), returns defined and active containers

2013-11-05 Thread Serge Hallyn
Quoting Serge Hallyn (serge.hal...@ubuntu.com):
> Quoting Dwight Engen (dwight.en...@oracle.com):
> > Signed-off-by: Dwight Engen 
> 
> Hi,
> 
> One comment below:

fwiw there's no resulting error so

Acked-by: Serge E. Hallyn 

but if you don't see any reason not to i'll pull the qsort out.

> 
> > ---
> >  src/lxc/lxccontainer.c | 97 
> > +++---
> >  src/lxc/lxccontainer.h | 10 ++
> >  2 files changed, 103 insertions(+), 4 deletions(-)
> > 
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index 89b45ed..d7d3273 100644
> > --- a/src/lxc/lxccontainer.c
> > +++ b/src/lxc/lxccontainer.c
> > @@ -1403,7 +1403,7 @@ static bool add_to_array(char ***names, char *cname, 
> > int pos)
> > return true;
> >  }
> >  
> > -static bool add_to_clist(struct lxc_container ***list, struct 
> > lxc_container *c, int pos)
> > +static bool add_to_clist(struct lxc_container ***list, struct 
> > lxc_container *c, int pos, bool sort)
> >  {
> > struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct 
> > lxc_container *));
> > if (!newlist) {
> > @@ -1415,7 +1415,8 @@ static bool add_to_clist(struct lxc_container 
> > ***list, struct lxc_container *c,
> > 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);
> > +   if (sort)
> > +   qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int 
> > (*)(const void *,const void *))container_cmp);
> >  
> > return true;
> >  }
> > @@ -3066,7 +3067,7 @@ int list_defined_containers(const char *lxcpath, char 
> > ***names, struct lxc_conta
> > continue;
> > }
> >  
> > -   if (!add_to_clist(cret, c, nfound)) {
> > +   if (!add_to_clist(cret, c, nfound, true)) {
> > lxc_container_put(c);
> > goto free_bad;
> > }
> > @@ -3169,7 +3170,7 @@ int list_active_containers(const char *lxcpath, char 
> > ***names, struct lxc_contai
> >  * fact that the command socket exists.
> >  */
> >  
> > -   if (!add_to_clist(cret, c, nfound)) {
> > +   if (!add_to_clist(cret, c, nfound, true)) {
> > lxc_container_put(c);
> > goto free_bad;
> > }
> > @@ -3206,3 +3207,91 @@ free_bad:
> > process_unlock();
> > return -1;
> >  }
> > +
> > +int list_all_containers(const char *lxcpath, char ***nret,
> > +   struct lxc_container ***cret)
> > +{
> > +   int i, ret, active_cnt, ct_cnt, ct_list_cnt;
> > +   char **active_name;
> > +   char **ct_name;
> > +   struct lxc_container **ct_list = NULL;
> > +
> > +   ct_cnt = list_defined_containers(lxcpath, &ct_name, NULL);
> > +   if (ct_cnt < 0)
> > +   return ct_cnt;
> > +
> > +   active_cnt = list_active_containers(lxcpath, &active_name, NULL);
> > +   if (active_cnt < 0) {
> > +   ret = active_cnt;
> > +   goto free_ct_name;
> > +   }
> > +
> > +   for (i = 0; i < active_cnt; i++) {
> > +   if (!array_contains(&ct_name, active_name[i], ct_cnt)) {
> > +   if (!add_to_array(&ct_name, active_name[i], ct_cnt)) {
> > +   ret = -1;
> > +   goto free_active_name;
> > +   }
> > +   ct_cnt++;
> > +   }
> > +   free(active_name[i]);
> > +   active_name[i] = NULL;
> > +   }
> > +   free(active_name);
> > +   active_name = NULL;
> > +   active_cnt = 0;
> > +
> > +   qsort(ct_name, ct_cnt, sizeof(char *),
> > + (int (*)(const void *,const void *))string_cmp);
> 
> Is this qsort needed?  list_defined_containers() and the add_to_array()s
> above should each be keeping ct_name ordered if I'm thinking right.
> 
> > +
> > +   for (i = 0, ct_list_cnt = 0; i < ct_cnt && cret; i++) {
> > +   struct lxc_container *c;
> > +
> > +   c = lxc_container_new(ct_name[i], lxcpath);
> > +   if (!c) {
> > +   WARN("Container %s:%s could not be loaded", lxcpath, 
> > ct_name[i]);
> > +   remove_from_array(&ct_name, ct_name[i], ct_cnt--);
> > +   continue;
> > +   }
> > +
> > +   if (!add_to_clist(&ct_list, c, ct_list_cnt, false)) {
> > +   lxc_container_put(c);
> > +   ret = -1;
> > +   goto free_ct_list;
> > +   }
> > +   ct_list_cnt++;
> > +   }
> > +
> > +   if (cret)
> > +   *cret = ct_list;
> > +
> > +   if (nret)
> > +   *nret = ct_name;
> > +   else {
> > +   ret = ct_cnt;
> > +   goto free_ct_name;
> > +   }
> > +   return ct_cnt;
> > +
> > +free_ct_list:
> > +   for (i = 0; i < ct_list_cnt; i++) {
> > +   lxc_container_put(ct_list[i]);
> > +   }
> > +   if (ct_list)
> > +