Re: [lxc-devel] Change rootfs pinning mechnism

2013-09-16 Thread Jäkel , Guido
Serge:
> Will it use the same name every time?  Will it eventually go away?

I don’t' know but I expect it will get some ID which represents the file 
reference on the NFS server. And it "disappear" (, i.e. it will be deleted in 
the normal way), if the filehandle is closed. Other NFS clients will see this 
"hidden" file and I expect that they even may open it. This emulation of unlink 
by a rename try to simulate the stateful behavior of a local file system.


Serge:
>I really don't want a new switch for this.  If we have to do something
>I'd rather detect nfs and do something different.

This would be even more convenient and save, of course.


Christian:
>The only thing I'm not really sure about:
>
>  - fail if it already exists
> => let's say one has an LXC running somewhere, the power goes out,
>no UPS, the host reboots after some time, tries to auto-start the
>LXC on boot but LXC won't start because .lxc-running exists...
>  - perhaps we could write the pid of the lxc-start process in there, so that 
> it may check whether the container is really running?

Good point. If it will hold open while a container is running, then it's a 
"left-over", if lxc-start detect another ones handle on it. But a file content 
might be more easy to handle by all kind of other programing languages that may 
take use of this file and will also work reliable on a shared file system.

Therefore, if something like the PID is written to the file, please also add 
the hostname, e.g. @

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


[lxc-devel] traffic scheduling from linux containers

2013-09-16 Thread Didi
Hello All,

I have designed an algorithm of how to schedule different traffic from three
linux containers to be transmitted to one receiver. I need help of how and
where to implement it in linux containers. Should I modify the cgroups? if
not where else should I go to implement my algorithm.
Thank you.


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


Re: [lxc-devel] traffic scheduling from linux containers

2013-09-16 Thread Serge Hallyn
Quoting Didi (siyana...@gmail.com):
> Hello All,
> 
> I have designed an algorithm of how to schedule different traffic from three
> linux containers to be transmitted to one receiver. I need help of how and
> where to implement it in linux containers. Should I modify the cgroups? if
> not where else should I go to implement my algorithm.

Perhaps.  You might look into tc.

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


Re: [lxc-devel] [Lxc-users] Working LXC templates?

2013-09-16 Thread Serge Hallyn
Quoting Michael H. Warfield (m...@wittsend.com):
> So, all of this has led Serge to list me on the roster for the
> LinuxPlumbers conference as the LXC "systemd expert".  I'll get even
> with him later next week for that one...

Lol!  Buy you a beer thu night? :)

-serge

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


Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v2

2013-09-16 Thread Stéphane Graber
On Mon, Sep 16, 2013 at 02:54:44PM -0400, S.Çağlar Onur wrote:
> On Mon, Sep 16, 2013 at 2:39 PM, Stéphane Graber wrote:
> 
> > On Mon, Sep 16, 2013 at 02:26:47PM -0400, S.Çağlar Onur wrote:
> > > get_ips accepts an interface name as a parameter but there was no
> > > way to get the interfaces names from the container. This patch
> > > introduces a new get_interfaces call to the API so that users
> > > can obtain the name of the interfaces.
> > >
> > > Signed-off-by: S.Çağlar Onur 
> >
> > I think I'm fine with this version:
> >
> > One quick comment though, wouldn't we expect get_interfaces() to return
> > all the interfaces by default, including loopback, including those
> > without addresses and those that aren't standard packet based IP
> > interfaces?
> >
> > I still think we don't want to list loopback addresses in get_ips(), at
> > least by default, but I think I'd expect get_interfaces to return me all
> > the existing interfaces without filtering. Does that make sense?
> 
> 
> Guess so. I've no objection including loopback in get_interfaces. I
> excluded it thinking that there is no point returning it as get_ips will
> ignore it. What about something like below as a replacement to v2 (this
> version starts to use if_nameindex instead of getifaddrs)?

I'd rather not use if_nameindex unless someone re-implements a bionic
version of it under lxc/includes/ as I just confirmed it doesn't exist
on bionic and so commiting that change would break our Android builds (I
know bionic is a real pain).

It took me a couple of days to find an slightly adapt a reasonable
implementation of getifaddrs for bionic, so I'd like not to have to go
through that again (but don't mind it if someone else contributes a
bionic compatible implementation).

So just to clarify what I think should happen in a perfect worls :)
 1) get_interfaces() would always return all the network interfaces
visible by the guest, so I'd expect those to match the entries from
ifconfig -a (or ip link show)
 2) get_ips() should default to only listing global IP addresses, so by
default ignore the loopback device and only return scope-global for
IPv6 (its current behaviour)
 3) If specifically passed interface="lo", then I'd expect get_ips to
return the loopback IP addresses (not currently the case, but
probably should be the case)

Does that make sense?

> 
> +static char** lxcapi_get_interfaces(struct lxc_container *c)
> +{
> +   int count = 0;
> +   struct if_nameindex *if_ni = NULL, *i;
> +   char **interfaces = NULL, **temp;
> +   int old_netns = -1, new_netns = -1;
> +
> +   if (!enter_to_ns(c, &old_netns, &new_netns))
> +   goto out;
> +
> +   if_ni = if_nameindex();
> +   if (if_ni == NULL) {
> +   SYSERROR("failed to get interfaces list");
> +   goto out;
> +   }
> +
> +for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) {
> +count += 1;
> +temp = realloc(interfaces, count * sizeof(*interfaces));
> +if (!temp) {
> +count -= 1;
> +goto out;
> +}
> +interfaces = temp;
> +interfaces[count - 1] = strdup(i->if_name);
> +}
> +
> +out:
> +   if_freenameindex(if_ni);
> +
> +   exit_from_ns(c, &old_netns, &new_netns);
> +
> +   /* Append NULL to the array */
> +   interfaces = (char **)lxc_append_null_to_array((void **)interfaces,
> count);
> +
> +   return interfaces;
> +}
> 
> And if we need get_ips to return ips then I guess we can always add a flag
> to get_ips as you suggested before?
> 
>  > ---
> > >  src/lxc/lxccontainer.c | 117
> > ++---
> > >  src/lxc/lxccontainer.h |   1 +
> > >  src/lxc/utils.c|  22 +-
> > >  src/lxc/utils.h|   1 +
> > >  4 files changed, 105 insertions(+), 36 deletions(-)
> > >
> > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > > index 79237df..6aa59fc 100644
> > > --- a/src/lxc/lxccontainer.c
> > > +++ b/src/lxc/lxccontainer.c
> > > @@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct
> > lxc_container *c, const char *key)
> > >   return ret == 0;
> > >  }
> > >
> > > -char** lxcapi_get_ips(struct lxc_container *c, char* interface, char*
> > family, int scope)
> > > -{
> > > - int count = 0;
> > > - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> > > - char addressOutputBuffer[INET6_ADDRSTRLEN];
> > > - void *tempAddrPtr = NULL;
> > > - char **addresses = NULL, **temp;
> > > - char *address = NULL;
> > > +static inline void exit_from_ns(struct lxc_container *c, int
> > *old_netns, int *new_netns) {
> > > + /* Switch back to original netns */
> > > + if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
> > > + SYSERROR("failed to setns");
> > > + if (*new_netns >= 0)
> > > + close(*new_netns);
> > > + if (*old_netns >= 0)
> > > +  

Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v2

2013-09-16 Thread S . Çağlar Onur
Hi Stéphane,

On Mon, Sep 16, 2013 at 3:04 PM, Stéphane Graber wrote:

> On Mon, Sep 16, 2013 at 02:54:44PM -0400, S.Çağlar Onur wrote:
> > On Mon, Sep 16, 2013 at 2:39 PM, Stéphane Graber  >wrote:
> >
> > > On Mon, Sep 16, 2013 at 02:26:47PM -0400, S.Çağlar Onur wrote:
> > > > get_ips accepts an interface name as a parameter but there was no
> > > > way to get the interfaces names from the container. This patch
> > > > introduces a new get_interfaces call to the API so that users
> > > > can obtain the name of the interfaces.
> > > >
> > > > Signed-off-by: S.Çağlar Onur 
> > >
> > > I think I'm fine with this version:
> > >
> > > One quick comment though, wouldn't we expect get_interfaces() to return
> > > all the interfaces by default, including loopback, including those
> > > without addresses and those that aren't standard packet based IP
> > > interfaces?
> > >
> > > I still think we don't want to list loopback addresses in get_ips(), at
> > > least by default, but I think I'd expect get_interfaces to return me
> all
> > > the existing interfaces without filtering. Does that make sense?
> >
> >
> > Guess so. I've no objection including loopback in get_interfaces. I
> > excluded it thinking that there is no point returning it as get_ips will
> > ignore it. What about something like below as a replacement to v2 (this
> > version starts to use if_nameindex instead of getifaddrs)?
>
> I'd rather not use if_nameindex unless someone re-implements a bionic
> version of it under lxc/includes/ as I just confirmed it doesn't exist
> on bionic and so commiting that change would break our Android builds (I
> know bionic is a real pain).
>
> It took me a couple of days to find an slightly adapt a reasonable
> implementation of getifaddrs for bionic, so I'd like not to have to go
> through that again (but don't mind it if someone else contributes a
> bionic compatible implementation).
>

Oh right, I completely forget Android. I'll stick to getifaddrs


> So just to clarify what I think should happen in a perfect worls :)
>  1) get_interfaces() would always return all the network interfaces
> visible by the guest, so I'd expect those to match the entries from
> ifconfig -a (or ip link show)
>  2) get_ips() should default to only listing global IP addresses, so by
> default ignore the loopback device and only return scope-global for
> IPv6 (its current behaviour)
>  3) If specifically passed interface="lo", then I'd expect get_ips to
> return the loopback IP addresses (not currently the case, but
> probably should be the case)
>
> Does that make sense?


Yes, it does. I'll work on these and iterate the patch one more time.


>  >
> > +static char** lxcapi_get_interfaces(struct lxc_container *c)
> > +{
> > +   int count = 0;
> > +   struct if_nameindex *if_ni = NULL, *i;
> > +   char **interfaces = NULL, **temp;
> > +   int old_netns = -1, new_netns = -1;
> > +
> > +   if (!enter_to_ns(c, &old_netns, &new_netns))
> > +   goto out;
> > +
> > +   if_ni = if_nameindex();
> > +   if (if_ni == NULL) {
> > +   SYSERROR("failed to get interfaces list");
> > +   goto out;
> > +   }
> > +
> > +for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) {
> > +count += 1;
> > +temp = realloc(interfaces, count * sizeof(*interfaces));
> > +if (!temp) {
> > +count -= 1;
> > +goto out;
> > +}
> > +interfaces = temp;
> > +interfaces[count - 1] = strdup(i->if_name);
> > +}
> > +
> > +out:
> > +   if_freenameindex(if_ni);
> > +
> > +   exit_from_ns(c, &old_netns, &new_netns);
> > +
> > +   /* Append NULL to the array */
> > +   interfaces = (char **)lxc_append_null_to_array((void
> **)interfaces,
> > count);
> > +
> > +   return interfaces;
> > +}
> >
> > And if we need get_ips to return ips then I guess we can always add a
> flag
> > to get_ips as you suggested before?
> >
> >  > ---
> > > >  src/lxc/lxccontainer.c | 117
> > > ++---
> > > >  src/lxc/lxccontainer.h |   1 +
> > > >  src/lxc/utils.c|  22 +-
> > > >  src/lxc/utils.h|   1 +
> > > >  4 files changed, 105 insertions(+), 36 deletions(-)
> > > >
> > > > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > > > index 79237df..6aa59fc 100644
> > > > --- a/src/lxc/lxccontainer.c
> > > > +++ b/src/lxc/lxccontainer.c
> > > > @@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct
> > > lxc_container *c, const char *key)
> > > >   return ret == 0;
> > > >  }
> > > >
> > > > -char** lxcapi_get_ips(struct lxc_container *c, char* interface,
> char*
> > > family, int scope)
> > > > -{
> > > > - int count = 0;
> > > > - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> > > > - char addressOutputBuffer[INET6_ADDRSTRLEN];
> > > > - void *tempAddrPtr = NULL;
> > > > - char

[lxc-devel] [PATCH] add arguments with getopt to concurrent tester

2013-09-16 Thread Dwight Engen
- add ability to run for multiple iterations
- can also run non-threaded for comparison to threaded case

Signed-off-by: Dwight Engen 
---
Hi Guys,

Serge I hope you don't mind I changed this to use getopt since there
are a couple of things I'm using it for at the moment (ie. fixing up
the fd leaks in the new cgroup code, patch for that will follow in a
bit). Having it be able to do a couple iterations is handy for use
with valgrind also.

 src/tests/concurrent.c | 148 ++---
 1 file changed, 116 insertions(+), 32 deletions(-)

diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c
index 7cf86c4..85b423b 100644
--- a/src/tests/concurrent.c
+++ b/src/tests/concurrent.c
@@ -15,14 +15,46 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
+#include 
 #include 
 #include 
+#include 
+#define _GNU_SOURCE
+#include 
 
 #include "../lxc/lxccontainer.h"
 
-#define NTHREADS 5
+static int nthreads = 5;
+static int iterations = 1;
+static int quiet = 0;
+static int delay = 0;
+static const char *template = "busybox";
+
+static struct option options[] = {
+{ "threads", required_argument, NULL, 'j' },
+{ "iterations",  required_argument, NULL, 'i' },
+{ "template",required_argument, NULL, 't' },
+{ "delay",   required_argument, NULL, 'd' },
+{ "quiet",   no_argument,   NULL, 'q' },
+{ "help",no_argument,   NULL, '?' },
+{ 0, 0, 0, 0 },
+};
 
-char *template = "busybox";
+static void usage(void) {
+fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n"
+"Common options :\n"
+"  -j, --threads=N  Threads to run concurrently\n"
+"   (default: 5, use 1 for no threading)\n"
+"  -i, --iterations=N   Number times to run the test (default: 1)\n"
+"  -t, --template=t Template to use (default: busybox)\n"
+"  -d, --delay=NDelay in seconds between start and stop\n"
+"  -q, --quiet  Don't produce any output\n"
+"  -?, --help   Give this help list\n"
+"\n"
+"Mandatory or optional arguments to long options are also mandatory or 
optional\n"
+"for any corresponding short options.\n\n");
+}
 
 struct thread_args {
 int thread_id;
@@ -30,16 +62,21 @@ struct thread_args {
 char *mode;
 };
 
-void * concurrent(void *arguments) {
-char name[4];
+static void do_function(void *arguments)
+{
+char name[NAME_MAX+1];
 struct thread_args *args = arguments;
 struct lxc_container *c;
 
-sprintf(name, "%d", args->thread_id);
+sprintf(name, "lxc-test-concurrent-%d", args->thread_id);
 
+args->return_code = 1;
 c = lxc_container_new(name, NULL);
+if (!c) {
+fprintf(stderr, "Unable to instantiate container (%s)\n", name);
+return;
+}
 
-args->return_code = 1;
 if (strcmp(args->mode, "create") == 0) {
 if (!c->is_defined(c)) {
 if (!c->create(c, template, NULL, NULL, 1, NULL)) {
@@ -58,6 +95,7 @@ void * concurrent(void *arguments) {
 fprintf(stderr, "Waiting the container (%s) to start 
failed...\n", name);
 goto out;
 }
+sleep(delay);
 }
 } else if(strcmp(args->mode, "stop") == 0) {
 if (c->is_defined(c) && c->is_running(c)) {
@@ -81,49 +119,95 @@ void * concurrent(void *arguments) {
 args->return_code = 0;
 out:
 lxc_container_put(c);
-pthread_exit(NULL);
 }
 
+static void *concurrent(void *arguments)
+{
+do_function(arguments);
+pthread_exit(NULL);
+}
 
 int main(int argc, char *argv[]) {
-int i, j;
+int i, j, iter, opt;
 pthread_attr_t attr;
-pthread_t threads[NTHREADS];
-struct thread_args args[NTHREADS];
+pthread_t *threads;
+struct thread_args *args;
 
 char *modes[] = {"create", "start", "stop", "destroy", NULL};
 
-if (argc > 1)
-   template = argv[1];
-
 pthread_attr_init(&attr);
-pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
-for (i = 0; modes[i];i++) {
-printf("Executing (%s) for %d containers...\n", modes[i], NTHREADS);
-for (j = 0; j < NTHREADS; j++) {
-args[j].thread_id = j;
-args[j].mode = modes[i];
-
-if (pthread_create(&threads[j], &attr, concurrent, (void *) 
&args[j]) != 0) {
-perror("pthread_create() error");
-exit(EXIT_FAILURE);
-}
+while ((opt = getopt_long(argc, argv, "j:i:t:d:q", options, NULL)) != -1) {
+switch(opt) {
+case 'j':
+nthreads = atoi(optarg);
+break;
+case 'i':
+iterations = atoi(optarg);
+break;
+case 't':
+template = optarg;
+break;
+case 'd':
+delay = atoi(optarg);
+break;
+

Re: [lxc-devel] [PATCH] make process_lock return void

2013-09-16 Thread Dwight Engen
On Mon, 16 Sep 2013 15:59:45 -0400
Stéphane Graber  wrote:

> On Mon, Sep 16, 2013 at 02:58:51PM -0500, Serge Hallyn wrote:
> > Quoting Serge Hallyn (serge.hal...@ubuntu.com):
> > > pthread_mutex_lock() will only return an error if it was set to
> > > PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
> > > would otherwise have deadlocked).  If that's the case then log a
> > > message for future debugging and exit.  Trying to "recover" at
> > > that point is madness.
> > 
> > Heh, all right this patch doesn't compile.  But assuming noone
> > objects to the spirit of it I'll push one that does compile in
> > a bit.  (It's the base of the more general thread-safety patch
> > I'm working on)
> 
> I'm fine with the idea behind that patch.

+1.

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


[lxc-devel] [PATCH] .gitignore generated Japanese manpages

2013-09-16 Thread Dwight Engen
Signed-off-by: Dwight Engen 
---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitignore b/.gitignore
index 0061609..84c060f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,6 +105,9 @@ config/lt*.m4
 doc/*.1
 doc/*.5
 doc/*.7
+doc/ja/*.1
+doc/ja/*.5
+doc/ja/*.7
 doc/legacy/*.1
 doc/manpage.links
 doc/manpage.refs
-- 
1.8.1.4


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


[lxc-devel] [lxc/lxc] 72899b: .gitignore generated Japanese manpages

2013-09-16 Thread GitHub
  Branch: refs/heads/staging
  Home:   https://github.com/lxc/lxc
  Commit: 72899b34f167e859edfd3b1c60a97ccf41a48cff
  https://github.com/lxc/lxc/commit/72899b34f167e859edfd3b1c60a97ccf41a48cff
  Author: Dwight Engen 
  Date:   2013-09-16 (Mon, 16 Sep 2013)

  Changed paths:
M .gitignore

  Log Message:
  ---
  .gitignore generated Japanese manpages

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



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


[lxc-devel] [PATCH] Add get_interfaces to the API - v2

2013-09-16 Thread S . Çağlar Onur
get_ips accepts an interface name as a parameter but there was no
way to get the interfaces names from the container. This patch
introduces a new get_interfaces call to the API so that users
can obtain the name of the interfaces.

Signed-off-by: S.Çağlar Onur 
---
 src/lxc/lxccontainer.c | 117 ++---
 src/lxc/lxccontainer.h |   1 +
 src/lxc/utils.c|  22 +-
 src/lxc/utils.h|   1 +
 4 files changed, 105 insertions(+), 36 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 79237df..6aa59fc 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct 
lxc_container *c, const char *key)
return ret == 0;
 }
 
-char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, 
int scope)
-{
-   int count = 0;
-   struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
-   char addressOutputBuffer[INET6_ADDRSTRLEN];
-   void *tempAddrPtr = NULL;
-   char **addresses = NULL, **temp;
-   char *address = NULL;
+static inline void exit_from_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+   /* Switch back to original netns */
+   if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
+   SYSERROR("failed to setns");
+   if (*new_netns >= 0)
+   close(*new_netns);
+   if (*old_netns >= 0)
+   close(*old_netns);
+}
+
+static inline bool enter_to_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+   int ret = 0;
char new_netns_path[MAXPATHLEN];
-   int old_netns = -1, new_netns = -1, ret = 0;
 
if (!c->is_running(c))
goto out;
 
/* Save reference to old netns */
-   old_netns = open("/proc/self/ns/net", O_RDONLY);
-   if (old_netns < 0) {
+   *old_netns = open("/proc/self/ns/net", O_RDONLY);
+   if (*old_netns < 0) {
SYSERROR("failed to open /proc/self/ns/net");
goto out;
}
@@ -1205,16 +1208,78 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
interface, char* family, in
if (ret < 0 || ret >= MAXPATHLEN)
goto out;
 
-   new_netns = open(new_netns_path, O_RDONLY);
-   if (new_netns < 0) {
+   *new_netns = open(new_netns_path, O_RDONLY);
+   if (*new_netns < 0) {
SYSERROR("failed to open %s", new_netns_path);
goto out;
}
 
-   if (setns(new_netns, CLONE_NEWNET)) {
+   if (setns(*new_netns, CLONE_NEWNET)) {
SYSERROR("failed to setns");
goto out;
}
+   return true;
+out:
+   exit_from_ns(c, old_netns, new_netns);
+   return false;
+}
+
+static char** lxcapi_get_interfaces(struct lxc_container *c)
+{
+   int count = 0;
+   struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
+   char **interfaces = NULL, **temp;
+   int old_netns = -1, new_netns = -1;
+
+   if (!enter_to_ns(c, &old_netns, &new_netns))
+   goto out;
+
+   /* Grab the list of interfaces */
+   if (getifaddrs(&interfaceArray)) {
+   SYSERROR("failed to get interfaces list");
+   goto out;
+   }
+
+   /* Iterate through the interfaces */
+   for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = 
tempIfAddr->ifa_next) {
+   /* filter out loopback interface */
+   if(tempIfAddr->ifa_addr == NULL || 
tempIfAddr->ifa_addr->sa_family != AF_PACKET || strcmp("lo", 
tempIfAddr->ifa_name) == 0)
+   continue;
+
+count += 1;
+temp = realloc(interfaces, count * sizeof(*interfaces));
+if (!temp) {
+count -= 1;
+goto out;
+}
+interfaces = temp;
+interfaces[count - 1] = strdup(tempIfAddr->ifa_name);
+}
+
+out:
+   if(interfaceArray)
+   freeifaddrs(interfaceArray);
+
+   exit_from_ns(c, &old_netns, &new_netns);
+
+   /* Append NULL to the array */
+   interfaces = (char **)lxc_append_null_to_array((void **)interfaces, 
count);
+
+   return interfaces;
+}
+
+static char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* 
family, int scope)
+{
+   int count = 0;
+   struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
+   char addressOutputBuffer[INET6_ADDRSTRLEN];
+   void *tempAddrPtr = NULL;
+   char **addresses = NULL, **temp;
+   char *address = NULL;
+   int old_netns = -1, new_netns = -1;
+
+   if (!enter_to_ns(c, &old_netns, &new_netns))
+   goto out;
 
/* Grab the list of interfaces */
if (getifaddrs(&interfaceArray)) {
@@ -1243,7 +1308,6 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
interface, char* family, in
continue;
else if (!interface && strcmp("lo", tempIf

[lxc-devel] [PATCH] make process_lock return void

2013-09-16 Thread Serge Hallyn
pthread_mutex_lock() will only return an error if it was set to
PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
would otherwise have deadlocked).  If that's the case then log a
message for future debugging and exit.  Trying to "recover" at
that point is madness.

Signed-off-by: Serge Hallyn 
---
 src/lxc/console.c  | 16 
 src/lxc/lxccontainer.c | 12 
 src/lxc/lxclock.c  |  6 --
 src/lxc/lxclock.h  |  2 +-
 src/lxc/monitor.c  |  2 ++
 5 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/lxc/console.c b/src/lxc/console.c
index e35a811..f503f18 100644
--- a/src/lxc/console.c
+++ b/src/lxc/console.c
@@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state *ts)
 
 void lxc_console_sigwinch(int sig)
 {
-   if (process_lock() == 0) {
-   struct lxc_list *it;
-   struct lxc_tty_state *ts;
+   struct lxc_list *it;
+   struct lxc_tty_state *ts;
 
-   lxc_list_for_each(it, &lxc_ttys) {
-   ts = it->elem;
-   lxc_console_winch(ts);
-   }
-   process_unlock();
+   process_lock();
+
+   lxc_list_for_each(it, &lxc_ttys) {
+   ts = it->elem;
+   lxc_console_winch(ts);
}
+   process_unlock();
 }
 
 static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata,
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 3c51c4a..bb2f226 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -100,8 +100,7 @@ int ongoing_create(struct lxc_container *c)
 
if (!file_exists(path))
return 0;
-   if (process_lock())
-   return -1;
+   process_lock();
if ((fd = open(path, O_RDWR)) < 0) {
// give benefit of the doubt
SYSERROR("Error opening partial file");
@@ -138,8 +137,7 @@ int create_partial(struct lxc_container *c)
ERROR("Error writing partial pathname");
return -1;
}
-   if (process_lock())
-   return -1;
+   process_lock();
if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
SYSERROR("Erorr creating partial file");
process_unlock();
@@ -173,8 +171,7 @@ void remove_partial(struct lxc_container *c, int fd)
ERROR("Error writing partial pathname");
return;
}
-   if (process_lock())
-   return;
+   process_lock();
if (unlink(path) < 0)
SYSERROR("Error unlink partial file %s", path);
process_unlock();
@@ -546,8 +543,7 @@ static bool lxcapi_start(struct lxc_container *c, int 
useinit, char * const argv
return false;
lxc_monitord_spawn(c->config_path);
 
-   if (process_lock())
-   return false;
+   process_lock();
pid_t pid = fork();
if (pid < 0) {
lxc_container_put(c);
diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
index 1d6a86c..3307418 100644
--- a/src/lxc/lxclock.c
+++ b/src/lxc/lxclock.c
@@ -271,12 +271,14 @@ void lxc_putlock(struct lxc_lock *l)
free(l);
 }
 
-int process_lock(void)
+void process_lock(void)
 {
int ret;
ret = pthread_mutex_lock(&thread_mutex);
-   if (ret != 0)
+   if (ret != 0) {
ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret));
+   exit(1);
+   }
return ret;
 }
 
diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
index fae7e4d..dcdf79d 100644
--- a/src/lxc/lxclock.h
+++ b/src/lxc/lxclock.h
@@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock);
 
 extern void lxc_putlock(struct lxc_lock *l);
 
-extern int process_lock(void);
+extern void process_lock(void);
 extern void process_unlock(void);
 struct lxc_container;
 extern int container_mem_lock(struct lxc_container *c);
diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
index 64e9987..747d6ca 100644
--- a/src/lxc/monitor.c
+++ b/src/lxc/monitor.c
@@ -187,7 +187,9 @@ int lxc_monitor_open(const char *lxcpath)
if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
return -1;
 
+   process_lock();
fd = socket(PF_UNIX, SOCK_STREAM, 0);
+   process_unlock();
if (fd < 0) {
ERROR("socket : %s", strerror(errno));
return -1;
-- 
1.8.3.2


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

Re: [lxc-devel] [PATCH] tests: Introduce lxc-test-concurrent for testing basic actions concurrently

2013-09-16 Thread Serge Hallyn
So, the basic lxc-test-concurrent now passes for me with both
busybox and ubuntu templates.  That's because the daemonized
starts are mutexed from each other just fine.  However, I expect
to see problems if we did start in parallel with things like wait.

(I'll play around)

-serge

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


Re: [lxc-devel] [PATCH] .gitignore generated Japanese manpages

2013-09-16 Thread Stéphane Graber
On Mon, Sep 16, 2013 at 04:25:38PM -0400, Dwight Engen wrote:
> Signed-off-by: Dwight Engen 

Acked-by: Stéphane Graber 

> ---
>  .gitignore | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/.gitignore b/.gitignore
> index 0061609..84c060f 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -105,6 +105,9 @@ config/lt*.m4
>  doc/*.1
>  doc/*.5
>  doc/*.7
> +doc/ja/*.1
> +doc/ja/*.5
> +doc/ja/*.7
>  doc/legacy/*.1
>  doc/manpage.links
>  doc/manpage.refs
> -- 
> 1.8.1.4
> 
> 
> --
> LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
> 1,500+ hours of tutorials including VisualStudio 2012, Windows 8, SharePoint
> 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack includes
> Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13. 
> http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
> ___
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel

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


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


Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v2

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

I think I'm fine with this version:

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

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

> ---
>  src/lxc/lxccontainer.c | 117 
> ++---
>  src/lxc/lxccontainer.h |   1 +
>  src/lxc/utils.c|  22 +-
>  src/lxc/utils.h|   1 +
>  4 files changed, 105 insertions(+), 36 deletions(-)
> 
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 79237df..6aa59fc 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct 
> lxc_container *c, const char *key)
>   return ret == 0;
>  }
>  
> -char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* 
> family, int scope)
> -{
> - int count = 0;
> - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> - char addressOutputBuffer[INET6_ADDRSTRLEN];
> - void *tempAddrPtr = NULL;
> - char **addresses = NULL, **temp;
> - char *address = NULL;
> +static inline void exit_from_ns(struct lxc_container *c, int *old_netns, int 
> *new_netns) {
> + /* Switch back to original netns */
> + if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
> + SYSERROR("failed to setns");
> + if (*new_netns >= 0)
> + close(*new_netns);
> + if (*old_netns >= 0)
> + close(*old_netns);
> +}
> +
> +static inline bool enter_to_ns(struct lxc_container *c, int *old_netns, int 
> *new_netns) {
> + int ret = 0;
>   char new_netns_path[MAXPATHLEN];
> - int old_netns = -1, new_netns = -1, ret = 0;
>  
>   if (!c->is_running(c))
>   goto out;
>  
>   /* Save reference to old netns */
> - old_netns = open("/proc/self/ns/net", O_RDONLY);
> - if (old_netns < 0) {
> + *old_netns = open("/proc/self/ns/net", O_RDONLY);
> + if (*old_netns < 0) {
>   SYSERROR("failed to open /proc/self/ns/net");
>   goto out;
>   }
> @@ -1205,16 +1208,78 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
> interface, char* family, in
>   if (ret < 0 || ret >= MAXPATHLEN)
>   goto out;
>  
> - new_netns = open(new_netns_path, O_RDONLY);
> - if (new_netns < 0) {
> + *new_netns = open(new_netns_path, O_RDONLY);
> + if (*new_netns < 0) {
>   SYSERROR("failed to open %s", new_netns_path);
>   goto out;
>   }
>  
> - if (setns(new_netns, CLONE_NEWNET)) {
> + if (setns(*new_netns, CLONE_NEWNET)) {
>   SYSERROR("failed to setns");
>   goto out;
>   }
> + return true;
> +out:
> + exit_from_ns(c, old_netns, new_netns);
> + return false;
> +}
> +
> +static char** lxcapi_get_interfaces(struct lxc_container *c)
> +{
> + int count = 0;
> + struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> + char **interfaces = NULL, **temp;
> + int old_netns = -1, new_netns = -1;
> +
> + if (!enter_to_ns(c, &old_netns, &new_netns))
> + goto out;
> +
> + /* Grab the list of interfaces */
> + if (getifaddrs(&interfaceArray)) {
> + SYSERROR("failed to get interfaces list");
> + goto out;
> + }
> +
> + /* Iterate through the interfaces */
> + for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = 
> tempIfAddr->ifa_next) {
> + /* filter out loopback interface */
> + if(tempIfAddr->ifa_addr == NULL || 
> tempIfAddr->ifa_addr->sa_family != AF_PACKET || strcmp("lo", 
> tempIfAddr->ifa_name) == 0)
> + continue;
> +
> +count += 1;
> +temp = realloc(interfaces, count * sizeof(*interfaces));
> +if (!temp) {
> +count -= 1;
> +goto out;
> +}
> +interfaces = temp;
> +interfaces[count - 1] = strdup(tempIfAddr->ifa_name);
> +}
> +
> +out:
> + if(interfaceArray)
> + freeifaddrs(interfaceArray);
> +
> + exit_from_ns(c, &old_netns, &new_netns);
> +
> + /* Append NULL to the array */
> + interfaces = (char **)lxc_append_null_to_array((void **)interfaces, 
> count);
> +
> + return interfaces;
> +}
> +
> +static char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* 
> family, int

[lxc-devel] [lxc/lxc] beb6d9: add arguments with getopt to concurrent tester

2013-09-16 Thread GitHub
  Branch: refs/heads/staging
  Home:   https://github.com/lxc/lxc
  Commit: beb6d93ee2b449ae2ea53125be2f198d15d8f8e8
  https://github.com/lxc/lxc/commit/beb6d93ee2b449ae2ea53125be2f198d15d8f8e8
  Author: Dwight Engen 
  Date:   2013-09-16 (Mon, 16 Sep 2013)

  Changed paths:
M src/tests/concurrent.c

  Log Message:
  ---
  add arguments with getopt to concurrent tester

- add ability to run for multiple iterations
- can also run non-threaded for comparison to threaded case

Signed-off-by: Dwight Engen 
Acked-by: Serge Hallyn 
Signed-off-by: Serge Hallyn 



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


[lxc-devel] [lxc/lxc] 4d7bcf: ubuntu templates: make pstore fstab entry optional

2013-09-16 Thread GitHub
  Branch: refs/heads/staging
  Home:   https://github.com/lxc/lxc
  Commit: 4d7bcfb638c5c4907e8539aa09d41bb1de08a097
  https://github.com/lxc/lxc/commit/4d7bcfb638c5c4907e8539aa09d41bb1de08a097
  Author: Serge Hallyn 
  Date:   2013-09-16 (Mon, 16 Sep 2013)

  Changed paths:
M templates/lxc-ubuntu-cloud.in
M templates/lxc-ubuntu.in

  Log Message:
  ---
  ubuntu templates: make pstore fstab entry optional

Signed-off-by: Serge Hallyn 



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


Re: [lxc-devel] [PATCH] make process_lock return void

2013-09-16 Thread Stéphane Graber
On Mon, Sep 16, 2013 at 02:58:51PM -0500, Serge Hallyn wrote:
> Quoting Serge Hallyn (serge.hal...@ubuntu.com):
> > pthread_mutex_lock() will only return an error if it was set to
> > PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
> > would otherwise have deadlocked).  If that's the case then log a
> > message for future debugging and exit.  Trying to "recover" at
> > that point is madness.
> 
> Heh, all right this patch doesn't compile.  But assuming noone
> objects to the spirit of it I'll push one that does compile in
> a bit.  (It's the base of the more general thread-safety patch
> I'm working on)

I'm fine with the idea behind that patch.

> 
> > Signed-off-by: Serge Hallyn 
> > ---
> >  src/lxc/console.c  | 16 
> >  src/lxc/lxccontainer.c | 12 
> >  src/lxc/lxclock.c  |  6 --
> >  src/lxc/lxclock.h  |  2 +-
> >  src/lxc/monitor.c  |  2 ++
> >  5 files changed, 19 insertions(+), 19 deletions(-)
> > 
> > diff --git a/src/lxc/console.c b/src/lxc/console.c
> > index e35a811..f503f18 100644
> > --- a/src/lxc/console.c
> > +++ b/src/lxc/console.c
> > @@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state 
> > *ts)
> >  
> >  void lxc_console_sigwinch(int sig)
> >  {
> > -   if (process_lock() == 0) {
> > -   struct lxc_list *it;
> > -   struct lxc_tty_state *ts;
> > +   struct lxc_list *it;
> > +   struct lxc_tty_state *ts;
> >  
> > -   lxc_list_for_each(it, &lxc_ttys) {
> > -   ts = it->elem;
> > -   lxc_console_winch(ts);
> > -   }
> > -   process_unlock();
> > +   process_lock();
> > +
> > +   lxc_list_for_each(it, &lxc_ttys) {
> > +   ts = it->elem;
> > +   lxc_console_winch(ts);
> > }
> > +   process_unlock();
> >  }
> >  
> >  static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata,
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index 3c51c4a..bb2f226 100644
> > --- a/src/lxc/lxccontainer.c
> > +++ b/src/lxc/lxccontainer.c
> > @@ -100,8 +100,7 @@ int ongoing_create(struct lxc_container *c)
> >  
> > if (!file_exists(path))
> > return 0;
> > -   if (process_lock())
> > -   return -1;
> > +   process_lock();
> > if ((fd = open(path, O_RDWR)) < 0) {
> > // give benefit of the doubt
> > SYSERROR("Error opening partial file");
> > @@ -138,8 +137,7 @@ int create_partial(struct lxc_container *c)
> > ERROR("Error writing partial pathname");
> > return -1;
> > }
> > -   if (process_lock())
> > -   return -1;
> > +   process_lock();
> > if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
> > SYSERROR("Erorr creating partial file");
> > process_unlock();
> > @@ -173,8 +171,7 @@ void remove_partial(struct lxc_container *c, int fd)
> > ERROR("Error writing partial pathname");
> > return;
> > }
> > -   if (process_lock())
> > -   return;
> > +   process_lock();
> > if (unlink(path) < 0)
> > SYSERROR("Error unlink partial file %s", path);
> > process_unlock();
> > @@ -546,8 +543,7 @@ static bool lxcapi_start(struct lxc_container *c, int 
> > useinit, char * const argv
> > return false;
> > lxc_monitord_spawn(c->config_path);
> >  
> > -   if (process_lock())
> > -   return false;
> > +   process_lock();
> > pid_t pid = fork();
> > if (pid < 0) {
> > lxc_container_put(c);
> > diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
> > index 1d6a86c..3307418 100644
> > --- a/src/lxc/lxclock.c
> > +++ b/src/lxc/lxclock.c
> > @@ -271,12 +271,14 @@ void lxc_putlock(struct lxc_lock *l)
> > free(l);
> >  }
> >  
> > -int process_lock(void)
> > +void process_lock(void)
> >  {
> > int ret;
> > ret = pthread_mutex_lock(&thread_mutex);
> > -   if (ret != 0)
> > +   if (ret != 0) {
> > ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret));
> > +   exit(1);
> > +   }
> > return ret;
> >  }
> >  
> > diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
> > index fae7e4d..dcdf79d 100644
> > --- a/src/lxc/lxclock.h
> > +++ b/src/lxc/lxclock.h
> > @@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock);
> >  
> >  extern void lxc_putlock(struct lxc_lock *l);
> >  
> > -extern int process_lock(void);
> > +extern void process_lock(void);
> >  extern void process_unlock(void);
> >  struct lxc_container;
> >  extern int container_mem_lock(struct lxc_container *c);
> > diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
> > index 64e9987..747d6ca 100644
> > --- a/src/lxc/monitor.c
> > +++ b/src/lxc/monitor.c
> > @@ -187,7 +187,9 @@ int lxc_monitor_open(const char *lxcpath)
> > if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
> > return -1;
> >  
> > +   process_lock();
> > fd = socket(PF_UNIX, SO

Re: [lxc-devel] [PATCH] make process_lock return void

2013-09-16 Thread Serge Hallyn
Quoting Serge Hallyn (serge.hal...@ubuntu.com):
> pthread_mutex_lock() will only return an error if it was set to
> PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
> would otherwise have deadlocked).  If that's the case then log a
> message for future debugging and exit.  Trying to "recover" at
> that point is madness.

Heh, all right this patch doesn't compile.  But assuming noone
objects to the spirit of it I'll push one that does compile in
a bit.  (It's the base of the more general thread-safety patch
I'm working on)

> Signed-off-by: Serge Hallyn 
> ---
>  src/lxc/console.c  | 16 
>  src/lxc/lxccontainer.c | 12 
>  src/lxc/lxclock.c  |  6 --
>  src/lxc/lxclock.h  |  2 +-
>  src/lxc/monitor.c  |  2 ++
>  5 files changed, 19 insertions(+), 19 deletions(-)
> 
> diff --git a/src/lxc/console.c b/src/lxc/console.c
> index e35a811..f503f18 100644
> --- a/src/lxc/console.c
> +++ b/src/lxc/console.c
> @@ -100,16 +100,16 @@ static void lxc_console_winch(struct lxc_tty_state *ts)
>  
>  void lxc_console_sigwinch(int sig)
>  {
> - if (process_lock() == 0) {
> - struct lxc_list *it;
> - struct lxc_tty_state *ts;
> + struct lxc_list *it;
> + struct lxc_tty_state *ts;
>  
> - lxc_list_for_each(it, &lxc_ttys) {
> - ts = it->elem;
> - lxc_console_winch(ts);
> - }
> - process_unlock();
> + process_lock();
> +
> + lxc_list_for_each(it, &lxc_ttys) {
> + ts = it->elem;
> + lxc_console_winch(ts);
>   }
> + process_unlock();
>  }
>  
>  static int lxc_console_cb_sigwinch_fd(int fd, void *cbdata,
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index 3c51c4a..bb2f226 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -100,8 +100,7 @@ int ongoing_create(struct lxc_container *c)
>  
>   if (!file_exists(path))
>   return 0;
> - if (process_lock())
> - return -1;
> + process_lock();
>   if ((fd = open(path, O_RDWR)) < 0) {
>   // give benefit of the doubt
>   SYSERROR("Error opening partial file");
> @@ -138,8 +137,7 @@ int create_partial(struct lxc_container *c)
>   ERROR("Error writing partial pathname");
>   return -1;
>   }
> - if (process_lock())
> - return -1;
> + process_lock();
>   if ((fd=open(path, O_RDWR | O_CREAT | O_EXCL, 0755)) < 0) {
>   SYSERROR("Erorr creating partial file");
>   process_unlock();
> @@ -173,8 +171,7 @@ void remove_partial(struct lxc_container *c, int fd)
>   ERROR("Error writing partial pathname");
>   return;
>   }
> - if (process_lock())
> - return;
> + process_lock();
>   if (unlink(path) < 0)
>   SYSERROR("Error unlink partial file %s", path);
>   process_unlock();
> @@ -546,8 +543,7 @@ static bool lxcapi_start(struct lxc_container *c, int 
> useinit, char * const argv
>   return false;
>   lxc_monitord_spawn(c->config_path);
>  
> - if (process_lock())
> - return false;
> + process_lock();
>   pid_t pid = fork();
>   if (pid < 0) {
>   lxc_container_put(c);
> diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c
> index 1d6a86c..3307418 100644
> --- a/src/lxc/lxclock.c
> +++ b/src/lxc/lxclock.c
> @@ -271,12 +271,14 @@ void lxc_putlock(struct lxc_lock *l)
>   free(l);
>  }
>  
> -int process_lock(void)
> +void process_lock(void)
>  {
>   int ret;
>   ret = pthread_mutex_lock(&thread_mutex);
> - if (ret != 0)
> + if (ret != 0) {
>   ERROR("pthread_mutex_lock returned:%d %s", ret, strerror(ret));
> + exit(1);
> + }
>   return ret;
>  }
>  
> diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h
> index fae7e4d..dcdf79d 100644
> --- a/src/lxc/lxclock.h
> +++ b/src/lxc/lxclock.h
> @@ -85,7 +85,7 @@ extern int lxcunlock(struct lxc_lock *lock);
>  
>  extern void lxc_putlock(struct lxc_lock *l);
>  
> -extern int process_lock(void);
> +extern void process_lock(void);
>  extern void process_unlock(void);
>  struct lxc_container;
>  extern int container_mem_lock(struct lxc_container *c);
> diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
> index 64e9987..747d6ca 100644
> --- a/src/lxc/monitor.c
> +++ b/src/lxc/monitor.c
> @@ -187,7 +187,9 @@ int lxc_monitor_open(const char *lxcpath)
>   if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
>   return -1;
>  
> + process_lock();
>   fd = socket(PF_UNIX, SOCK_STREAM, 0);
> + process_unlock();
>   if (fd < 0) {
>   ERROR("socket : %s", strerror(errno));
>   return -1;
> -- 
> 1.8.3.2
> 
> 
> --
> LIMITED TIME 

[lxc-devel] [PATCH RFC] split up use of process_lock, and make process_lock return void

2013-09-16 Thread Serge Hallyn
pthread_mutex_lock() will only return an error if it was set to
PTHREAD_MUTEX_ERRORCHECK and we are recursively calling it (and
would otherwise have deadlocked).  If that's the case then log a
message for future debugging and exit.  Trying to "recover" is
nonsense at that point.

process_lock() was held over too long a time in lxcapi_start()
in the daemonize case.  (note the non-daemonized case still needs a
check to enforce that it must NOT be called while threaded).  Add
process_lock() at least across all open/close/socket() calls.

Note that anything after we've done a fork() doesn't need the
locks as it is no longer threaded.

Tested that lp:~serge-hallyn/+junk/lxc-test still works with this
patch.

Signed-off-by: Serge Hallyn 
---
 src/lxc/af_unix.c  |  10 +++
 src/lxc/bdev.c |  80 +---
 src/lxc/commands.c |  10 +++
 src/lxc/console.c  |  16 ++--
 src/lxc/lxccontainer.c | 196 -
 src/lxc/lxclock.c  |   9 ++-
 src/lxc/lxclock.h  |   2 +-
 src/lxc/monitor.c  |  17 -
 src/lxc/state.c|   5 ++
 9 files changed, 254 insertions(+), 91 deletions(-)

diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c
index d6d18ca..333f05e 100644
--- a/src/lxc/af_unix.c
+++ b/src/lxc/af_unix.c
@@ -43,7 +43,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
if (flags & O_TRUNC)
unlink(path);
 
+   process_lock();
fd = socket(PF_UNIX, type, 0);
+   process_unlock();
if (fd < 0)
return -1;
 
@@ -58,7 +60,9 @@ int lxc_af_unix_open(const char *path, int type, int flags)
if (path[0]) {
len = strlen(path);
if (len >= sizeof(addr.sun_path)) {
+   process_lock();
close(fd);
+   process_unlock();
errno = ENAMETOOLONG;
return -1;
}
@@ -67,14 +71,18 @@ int lxc_af_unix_open(const char *path, int type, int flags)
 
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr))) {
int tmp = errno;
+   process_lock();
close(fd);
+   process_unlock();
errno = tmp;
return -1;
}
 
if (type == SOCK_STREAM && listen(fd, 100)) {
int tmp = errno;
+   process_lock();
close(fd);
+   process_unlock();
errno = tmp;
return -1;
}
@@ -91,7 +99,9 @@ int lxc_af_unix_close(int fd)
addr.sun_path[0])
unlink(addr.sun_path);
 
+   process_lock();
close(fd);
+   process_unlock();
 
return 0;
 }
diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c
index b45f2cb..7cec5d8 100644
--- a/src/lxc/bdev.c
+++ b/src/lxc/bdev.c
@@ -93,11 +93,15 @@ static int blk_getsize(struct bdev *bdev, unsigned long 
*size)
if (strcmp(bdev->type, "loop") == 0)
path = bdev->src + 5;
 
+   process_lock();
fd = open(path, O_RDONLY);
+   process_unlock();
if (fd < 0)
return -1;
ret = ioctl(fd, BLKGETSIZE64, size);
+   process_lock();
close(fd);
+   process_unlock();
return ret;
 }
 
@@ -252,16 +256,23 @@ static int detect_fs(struct bdev *bdev, char *type, int 
len)
if (strcmp(bdev->type, "loop") == 0)
srcdev = bdev->src + 5;
 
-   if (pipe(p) < 0)
+   process_lock();
+   ret = pipe(p);
+   process_unlock();
+   if (ret < 0)
return -1;
if ((pid = fork()) < 0)
return -1;
if (pid > 0) {
int status;
+   process_lock();
close(p[1]);
+   process_unlock();
memset(type, 0, len);
ret = read(p[0], type, len-1);
+   process_lock();
close(p[0]);
+   process_unlock();
if (ret < 0) {
SYSERROR("error reading from pipe");
wait(&status);
@@ -488,7 +499,10 @@ static int zfs_list_entry(const char *path, char *output, 
size_t inlen)
FILE *f;
int found=0;
 
-   if ((f = popen("zfs list 2> /dev/null", "r")) == NULL) {
+   process_lock();
+   f = popen("zfs list 2> /dev/null", "r");
+   process_unlock();
+   if (f == NULL) {
SYSERROR("popen failed");
return 0;
}
@@ -498,7 +512,9 @@ static int zfs_list_entry(const char *path, char *output, 
size_t inlen)
break;
}
}
+   process_lock();
(void) pclose(f);
+   process_unlock();
 
return found;
 }
@@ -750,11 +766,15 @@ static int lvm_detect(const char *path)
ERROR("lvm uuid pathname too long");
return 0;
}
+   process_lock();

Re: [lxc-devel] [Lxc-users] Working LXC templates? EUREAKA! I think I've got it!

2013-09-16 Thread Tony Su
Michael,
Considering your substantial existing work, if you'd post on github,
I'd we willing to fork and contribute in that manner (of course, also
opens up ways for others to contribute).

I'd create the original repo myself except that your work should be
credited by you (and contributions managed by you as well).

Tony

On Sun, Sep 15, 2013 at 5:51 PM, Tony Su  wrote:
> After some additional thought,
> If the goal is a template which will execute with minimal issues on
> non-Fedora HostOS,
>
> Besides my observations in my previous post to this,
>
> IMO the vaarious lines which "touch /etc/fstab" also would need to be
> modified since IMO the mount points of current, later versions of
> Fedora can be sometimes downright weird and wouldn't produce the
> desired result when executing that command on other distros.
>
> Tony
>
> On Sun, Sep 15, 2013 at 4:17 PM, Tony Su  wrote:
>> Hello Michael,
>>
>> First a comment on problems with systemd you descrbe.
>> I probably have run into many of the things you itemized, but since my
>> time is usually focused on something I'm trying to use LXC and not LXC
>> itself, I usually just drop any further attempts and move on to find a
>> workaround(eg consoles) or use a different technology(x server issue).
>>
>> Regarding many of the issues you describe though, I wonder if they
>> couldn't be addressed with more strict enforcement of using namespaces
>> (and less often cgroups). I've read how namespaces are supposed to be
>> an extremely powerful means of isolating processes and yet I don't see
>> any obvious indications it's being done consistently... by either
>> prepending to standard process or service names (if the goal is to
>> easily identify the namespace) or using a random string (if the goal
>> is better security so exploits can't anticipate commonly used
>> namespaces).
>>
>> In fact, I think I see this namespace issue in various parts of the
>> template you created. If I understand what is happening, there are
>> numerous places where you create special nodes on the HostOS instead
>> of
>> (a) using the existing HostOS nodes but using namespaces to isolate
>> Container processes
>> (b) creating nodes entirely within the Container which would make the
>> Container entirely portable but lose the benefit perhaps of the better
>> ways nodes are created and mounted today(eg tmpfs in RAM).
>>
>> Diving more into your template code, I applaud your effort, it's
>> significant and no minor effort.
>>
>> As of this moment, I've mainly been perusing what I might call "HostOS
>> Container Pre-Install," the part which precedes the actual
>> installation and relies on components running in the HostOS only. This
>> would be your script approx lines 0-410.
>>
>> 1. I like your method of identifying whether the OS is Fedora, and
>> additionally whether is ARM or not.
>>
>> 2. It looks like you're configuring networking binding directly to
>> eth0. I would recommend instead supporting the use of Linux Bridge
>> devices, make declaration of a bridge device name as one of the early
>> Global Parameters, then if exists to bind to that device by name. Your
>> code to bind to the physical interface is less flexible but can be a
>> default option if no bridge device is specified.
>>
>> 3. Interesting that you include an option for "nm controlled" yet at
>> least initially I don't see where your code might rely on this
>> setting.
>>
>> 4. mknod I'll have to take a closer look whether and why you appear to
>> be setting up various consoles, some /dev/ nodes, an explicit console
>> path, more. I've generally been under the impression that a full
>> install automatically creates these. Peeking a bit ahead of where I've
>> been reading your script, I notice your install method uses a
>> pre-built squashfs image, perhaps these are a special requirement
>> because your chosen squashfs image doesn't include these by default or
>> requires those nodes to already exist?
>>
>> 5. Your use of yum will work in the RH family plus various others like
>> openSUSE but I don't think it's native to distros like the Debian
>> family. IMO there is no special benefit to using a package manager
>> specific to the HostOS to download bootstrap images and packages, they
>> aren't too relevant to the overall apps running in the HostOS and I
>> think we should avoid installing non-native packages in any OS. For
>> that reason, I've been looking at pycurl, curl and wget which are
>> generic apps common to all distros which can accomplish the simple
>> task of retrieving the bootstrap objects. (See the template I included
>> as an attachment which uses pycurl and finds fedora repos rather than
>> installing a pre-built img)
>>
>> A small FYI -
>> Although the Fedora template distributed with openSUSE which I've
>> included as an attachment to this message  it
>> might be useful to see a different way of obtaining and installing
>> Fedora bootstrap packages so I've included it as an attachment to this
>> messag

Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v2

2013-09-16 Thread S . Çağlar Onur
On Mon, Sep 16, 2013 at 2:39 PM, Stéphane Graber wrote:

> On Mon, Sep 16, 2013 at 02:26:47PM -0400, S.Çağlar Onur wrote:
> > get_ips accepts an interface name as a parameter but there was no
> > way to get the interfaces names from the container. This patch
> > introduces a new get_interfaces call to the API so that users
> > can obtain the name of the interfaces.
> >
> > Signed-off-by: S.Çağlar Onur 
>
> I think I'm fine with this version:
>
> One quick comment though, wouldn't we expect get_interfaces() to return
> all the interfaces by default, including loopback, including those
> without addresses and those that aren't standard packet based IP
> interfaces?
>
> I still think we don't want to list loopback addresses in get_ips(), at
> least by default, but I think I'd expect get_interfaces to return me all
> the existing interfaces without filtering. Does that make sense?


Guess so. I've no objection including loopback in get_interfaces. I
excluded it thinking that there is no point returning it as get_ips will
ignore it. What about something like below as a replacement to v2 (this
version starts to use if_nameindex instead of getifaddrs)?

+static char** lxcapi_get_interfaces(struct lxc_container *c)
+{
+   int count = 0;
+   struct if_nameindex *if_ni = NULL, *i;
+   char **interfaces = NULL, **temp;
+   int old_netns = -1, new_netns = -1;
+
+   if (!enter_to_ns(c, &old_netns, &new_netns))
+   goto out;
+
+   if_ni = if_nameindex();
+   if (if_ni == NULL) {
+   SYSERROR("failed to get interfaces list");
+   goto out;
+   }
+
+for (i = if_ni; ! (i->if_index == 0 && i->if_name == NULL); i++) {
+count += 1;
+temp = realloc(interfaces, count * sizeof(*interfaces));
+if (!temp) {
+count -= 1;
+goto out;
+}
+interfaces = temp;
+interfaces[count - 1] = strdup(i->if_name);
+}
+
+out:
+   if_freenameindex(if_ni);
+
+   exit_from_ns(c, &old_netns, &new_netns);
+
+   /* Append NULL to the array */
+   interfaces = (char **)lxc_append_null_to_array((void **)interfaces,
count);
+
+   return interfaces;
+}

And if we need get_ips to return ips then I guess we can always add a flag
to get_ips as you suggested before?

 > ---
> >  src/lxc/lxccontainer.c | 117
> ++---
> >  src/lxc/lxccontainer.h |   1 +
> >  src/lxc/utils.c|  22 +-
> >  src/lxc/utils.h|   1 +
> >  4 files changed, 105 insertions(+), 36 deletions(-)
> >
> > diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> > index 79237df..6aa59fc 100644
> > --- a/src/lxc/lxccontainer.c
> > +++ b/src/lxc/lxccontainer.c
> > @@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct
> lxc_container *c, const char *key)
> >   return ret == 0;
> >  }
> >
> > -char** lxcapi_get_ips(struct lxc_container *c, char* interface, char*
> family, int scope)
> > -{
> > - int count = 0;
> > - struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
> > - char addressOutputBuffer[INET6_ADDRSTRLEN];
> > - void *tempAddrPtr = NULL;
> > - char **addresses = NULL, **temp;
> > - char *address = NULL;
> > +static inline void exit_from_ns(struct lxc_container *c, int
> *old_netns, int *new_netns) {
> > + /* Switch back to original netns */
> > + if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
> > + SYSERROR("failed to setns");
> > + if (*new_netns >= 0)
> > + close(*new_netns);
> > + if (*old_netns >= 0)
> > + close(*old_netns);
> > +}
> > +
> > +static inline bool enter_to_ns(struct lxc_container *c, int *old_netns,
> int *new_netns) {
> > + int ret = 0;
> >   char new_netns_path[MAXPATHLEN];
> > - int old_netns = -1, new_netns = -1, ret = 0;
> >
> >   if (!c->is_running(c))
> >   goto out;
> >
> >   /* Save reference to old netns */
> > - old_netns = open("/proc/self/ns/net", O_RDONLY);
> > - if (old_netns < 0) {
> > + *old_netns = open("/proc/self/ns/net", O_RDONLY);
> > + if (*old_netns < 0) {
> >   SYSERROR("failed to open /proc/self/ns/net");
> >   goto out;
> >   }
> > @@ -1205,16 +1208,78 @@ char** lxcapi_get_ips(struct lxc_container *c,
> char* interface, char* family, in
> >   if (ret < 0 || ret >= MAXPATHLEN)
> >   goto out;
> >
> > - new_netns = open(new_netns_path, O_RDONLY);
> > - if (new_netns < 0) {
> > + *new_netns = open(new_netns_path, O_RDONLY);
> > + if (*new_netns < 0) {
> >   SYSERROR("failed to open %s", new_netns_path);
> >   goto out;
> >   }
> >
> > - if (setns(new_netns, CLONE_NEWNET)) {
> > + if (setns(*new_netns, CLONE_NEWNET)) {
> >   SYSERROR("failed to setns");
> >   goto out;
> >   }
> > + return true;
> > +out:
> > + exit_from_ns(c, old

[lxc-devel] [PATCH] Add get_interfaces to the API - v3

2013-09-16 Thread S . Çağlar Onur
get_ips accepts an interface name as a parameter but there was no
way to get the interfaces names from the container. This patch
introduces a new get_interfaces call to the API so that users
can obtain the name of the interfaces.

Support for python bindings also introduced as a part of this version.

Signed-off-by: S.Çağlar Onur 
---
 src/lxc/lxccontainer.c  | 129 ++--
 src/lxc/lxccontainer.h  |   3 +
 src/lxc/utils.c |  22 +-
 src/lxc/utils.h |   1 +
 src/python-lxc/examples/api_test.py |   5 ++
 src/python-lxc/lxc.c|  60 +++--
 src/python-lxc/lxc/__init__.py  |   8 +++
 7 files changed, 189 insertions(+), 39 deletions(-)

diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 79237df..8621cd8 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -1179,23 +1179,26 @@ static bool lxcapi_clear_config_item(struct 
lxc_container *c, const char *key)
return ret == 0;
 }
 
-char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, 
int scope)
-{
-   int count = 0;
-   struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
-   char addressOutputBuffer[INET6_ADDRSTRLEN];
-   void *tempAddrPtr = NULL;
-   char **addresses = NULL, **temp;
-   char *address = NULL;
+static inline void exit_from_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+   /* Switch back to original netns */
+   if (*old_netns >= 0 && setns(*old_netns, CLONE_NEWNET))
+   SYSERROR("failed to setns");
+   if (*new_netns >= 0)
+   close(*new_netns);
+   if (*old_netns >= 0)
+   close(*old_netns);
+}
+
+static inline bool enter_to_ns(struct lxc_container *c, int *old_netns, int 
*new_netns) {
+   int ret = 0;
char new_netns_path[MAXPATHLEN];
-   int old_netns = -1, new_netns = -1, ret = 0;
 
if (!c->is_running(c))
goto out;
 
/* Save reference to old netns */
-   old_netns = open("/proc/self/ns/net", O_RDONLY);
-   if (old_netns < 0) {
+   *old_netns = open("/proc/self/ns/net", O_RDONLY);
+   if (*old_netns < 0) {
SYSERROR("failed to open /proc/self/ns/net");
goto out;
}
@@ -1205,16 +1208,91 @@ char** lxcapi_get_ips(struct lxc_container *c, char* 
interface, char* family, in
if (ret < 0 || ret >= MAXPATHLEN)
goto out;
 
-   new_netns = open(new_netns_path, O_RDONLY);
-   if (new_netns < 0) {
+   *new_netns = open(new_netns_path, O_RDONLY);
+   if (*new_netns < 0) {
SYSERROR("failed to open %s", new_netns_path);
goto out;
}
 
-   if (setns(new_netns, CLONE_NEWNET)) {
+   if (setns(*new_netns, CLONE_NEWNET)) {
SYSERROR("failed to setns");
goto out;
}
+   return true;
+out:
+   exit_from_ns(c, old_netns, new_netns);
+   return false;
+}
+
+static char** lxcapi_get_interfaces(struct lxc_container *c)
+{
+   int count = 0, i;
+   bool found = false;
+   struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
+   char **interfaces = NULL, **temp;
+   int old_netns = -1, new_netns = -1;
+
+   if (!enter_to_ns(c, &old_netns, &new_netns))
+   goto out;
+
+   /* Grab the list of interfaces */
+   if (getifaddrs(&interfaceArray)) {
+   SYSERROR("failed to get interfaces list");
+   goto out;
+   }
+
+   /* Iterate through the interfaces */
+   for (tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = 
tempIfAddr->ifa_next) {
+   /*
+* WARNING: Following "for" loop does a linear search over the 
interfaces array
+* For the containers with lots of interfaces this may be 
problematic.
+ * I'm not expecting this to be the common usage but if it turns out 
to be
+* than using binary search or a hash table could be more 
elegant solution.
+*/
+   for (i = 0; i < count; i++) {
+   if (strcmp(interfaces[i], tempIfAddr->ifa_name) == 0) {
+   found = true;
+   break;
+   }
+   }
+
+   if (!found) {
+   count += 1;
+   temp = realloc(interfaces, count * sizeof(*interfaces));
+   if (!temp) {
+   count -= 1;
+   goto out;
+   }
+   interfaces = temp;
+   interfaces[count - 1] = strdup(tempIfAddr->ifa_name);
+   }
+   found = false;
+}
+
+out:
+   if (interfaceArray)
+   freeifaddrs(interfaceArray);
+
+   exit_from_ns(c, &old_net

[lxc-devel] [PATCH] cleanup fds, memory in lxc_cgroup_load_meta2()

2013-09-16 Thread Dwight Engen
There are fd leaks in lxc_cgroup_load_meta2() in particular in the success
case. This change attempts to ensure resources are free'd/close'd, but it
is possible there are still some error cases where leaks occur.

Signed-off-by: Dwight Engen 
---
Hi Christian,

These changes fix problems I was seeing with valgrind, but they may not be
how you would do it, so feel free to rework them if I've messed up your
code too bad :) The command I was using:
 valgrind --leak-check=full --track-fds=yes ./lxc-test-concurrent -i 2 -j 1

 src/lxc/cgroup.c | 83 
 1 file changed, 48 insertions(+), 35 deletions(-)

diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
index 9417e77..101998b 100644
--- a/src/lxc/cgroup.c
+++ b/src/lxc/cgroup.c
@@ -124,7 +124,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
size_t token_capacity = 0;
char *line = NULL;
size_t sz = 0;
-   int r, saved_errno = 0;
+   int r, ret = ENOMEM;
 
/* if the subsystem whitelist is not specified, include all
 * hierarchies that contain kernel subsystems by default but
@@ -149,8 +149,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
 
/* Step 1: determine all kernel subsystems */
proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
-   if (!proc_cgroups)
-   goto out_error;
+   if (!proc_cgroups) {
+   ret = errno;
+   goto out1;
+   }
 
while (getline(&line, &sz, proc_cgroups) != -1) {
char *tab1;
@@ -179,10 +181,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
 
r = lxc_grow_array((void ***)&kernel_subsystems, 
&kernel_subsystems_capacity, kernel_subsystems_count + 1, 12);
if (r < 0)
-   goto out_error;
+   goto out2;
kernel_subsystems[kernel_subsystems_count] = strdup(line);
if (!kernel_subsystems[kernel_subsystems_count])
-   goto out_error;
+   goto out2;
kernel_subsystems_count++;
}
 
@@ -198,8 +200,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
 * /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_cgroup)
proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
-   if (!proc_self_cgroup)
-   goto out_error;
+   if (!proc_self_cgroup) {
+   ret = errno;
+   goto out2;
+   }
 
while (getline(&line, &sz, proc_self_cgroup) != -1) {
/* file format: hierarchy:subsystems:group,
@@ -234,25 +238,25 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
*/
r = lxc_grow_array((void ***)&meta_data->hierarchies, 
&hierarchy_capacity, hierarchy_number + 1, 12);
if (r < 0)
-   goto out_error;
+   goto out3;
 
meta_data->maximum_hierarchy = hierarchy_number;
}
 
/* this shouldn't happen, we had this already */
if (meta_data->hierarchies[hierarchy_number])
-   goto out_error;
+   goto out3;
 
h = calloc(1, sizeof(struct cgroup_hierarchy));
if (!h)
-   goto out_error;
+   goto out3;
 
meta_data->hierarchies[hierarchy_number] = h;
 
h->index = hierarchy_number;
h->subsystems = lxc_string_split_and_trim(colon1, ',');
if (!h->subsystems)
-   goto out_error;
+   goto out3;
/* see if this hierarchy should be considered */
if (!all_kernel_subsystems || !all_named_subsystems) {
for (p = h->subsystems; *p; p++) {
@@ -283,8 +287,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
 * /proc/self is not valid, we try /proc/1/cgroup... */
if (!proc_self_mountinfo)
proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
-   if (!proc_self_mountinfo)
-   goto out_error;
+   if (!proc_self_mountinfo) {
+   ret = errno;
+   goto out3;
+   }
 
while (getline(&line, &sz, proc_self_mountinfo) != -1) {
char *token, *saveptr = NULL;
@@ -299,7 +305,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
for (i = 0; (token = strtok_r(line, " ", &saveptr)); line = 
NULL) {
r = lxc_grow_array((void ***)&tokens, &token_capacity, 
i + 1, 64);
if (

[lxc-devel] [PATCH] fix some larger memory leaks in cgroup code

2013-09-16 Thread Dwight Engen
Don't worry about saved_errno since none of the *_free routines will set it

Signed-off-by: Dwight Engen 
---
 src/lxc/cgroup.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
index 101998b..bf7a2a2 100644
--- a/src/lxc/cgroup.c
+++ b/src/lxc/cgroup.c
@@ -293,7 +293,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
}
 
while (getline(&line, &sz, proc_self_mountinfo) != -1) {
-   char *token, *saveptr = NULL;
+   char *token, *line_tok, *saveptr = NULL;
size_t i, j, k;
struct cgroup_mount_point *mount_point;
struct cgroup_hierarchy *h;
@@ -302,7 +302,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
**subsystem_whitelist)
if (line[0] && line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
 
-   for (i = 0; (token = strtok_r(line, " ", &saveptr)); line = 
NULL) {
+   for (i = 0, line_tok = line; (token = strtok_r(line_tok, " ", 
&saveptr)); line_tok = NULL) {
r = lxc_grow_array((void ***)&tokens, &token_capacity, 
i + 1, 64);
if (r < 0)
goto out4;
@@ -441,6 +441,7 @@ struct cgroup_meta_data *lxc_cgroup_put_meta(struct 
cgroup_meta_data *meta_data)
lxc_cgroup_hierarchy_free(meta_data->hierarchies[i]);
}
free(meta_data->hierarchies);
+   free(meta_data);
return NULL;
 }
 
@@ -1067,29 +1068,30 @@ char *lxc_cgroup_get_hierarchy_abs_path(const char 
*subsystem, const char *name,
struct cgroup_process_info *base_info, *info;
struct cgroup_mount_point *mp;
char *result = NULL;
-   int saved_errno;
 
meta = lxc_cgroup_load_meta();
if (!meta)
return NULL;
base_info = lxc_cgroup_get_container_info(name, lxcpath, meta);
if (!base_info)
-   return NULL;
+   goto out1;
info = find_info_for_subsystem(base_info, subsystem);
if (!info)
-   return NULL;
+   goto out2;
if (info->designated_mount_point) {
mp = info->designated_mount_point; 
} else {
mp = lxc_cgroup_find_mount_point(info->hierarchy, 
info->cgroup_path, true);
if (!mp)
-   return NULL;
+   goto out3;
}
result = cgroup_to_absolute_path(mp, info->cgroup_path, NULL);
-   saved_errno = errno;
+out3:
+   lxc_cgroup_process_info_free(info);
+out2:
lxc_cgroup_process_info_free(base_info);
+out1:
lxc_cgroup_put_meta(meta);
-   errno = saved_errno;
return result;
 }
 
-- 
1.8.1.4


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


Re: [lxc-devel] [PATCH] add arguments with getopt to concurrent tester

2013-09-16 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> - add ability to run for multiple iterations
> - can also run non-threaded for comparison to threaded case
> 
> Signed-off-by: Dwight Engen 

Acked-by: Serge E. Hallyn 

> ---
> Hi Guys,
> 
> Serge I hope you don't mind I changed this to use getopt since there
> are a couple of things I'm using it for at the moment (ie. fixing up
> the fd leaks in the new cgroup code, patch for that will follow in a
> bit). Having it be able to do a couple iterations is handy for use
> with valgrind also.
> 
>  src/tests/concurrent.c | 148 
> ++---
>  1 file changed, 116 insertions(+), 32 deletions(-)
> 
> diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c
> index 7cf86c4..85b423b 100644
> --- a/src/tests/concurrent.c
> +++ b/src/tests/concurrent.c
> @@ -15,14 +15,46 @@
>   * with this program; if not, write to the Free Software Foundation, Inc.,
>   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
>   */
> +
> +#include 
>  #include 
>  #include 
> +#include 
> +#define _GNU_SOURCE
> +#include 
>  
>  #include "../lxc/lxccontainer.h"
>  
> -#define NTHREADS 5
> +static int nthreads = 5;
> +static int iterations = 1;
> +static int quiet = 0;
> +static int delay = 0;
> +static const char *template = "busybox";
> +
> +static struct option options[] = {
> +{ "threads", required_argument, NULL, 'j' },
> +{ "iterations",  required_argument, NULL, 'i' },
> +{ "template",required_argument, NULL, 't' },
> +{ "delay",   required_argument, NULL, 'd' },
> +{ "quiet",   no_argument,   NULL, 'q' },
> +{ "help",no_argument,   NULL, '?' },
> +{ 0, 0, 0, 0 },
> +};
>  
> -char *template = "busybox";
> +static void usage(void) {
> +fprintf(stderr, "Usage: lxc-test-concurrent [OPTION]...\n\n"
> +"Common options :\n"
> +"  -j, --threads=N  Threads to run concurrently\n"
> +"   (default: 5, use 1 for no threading)\n"
> +"  -i, --iterations=N   Number times to run the test (default: 1)\n"
> +"  -t, --template=t Template to use (default: busybox)\n"
> +"  -d, --delay=NDelay in seconds between start and stop\n"
> +"  -q, --quiet  Don't produce any output\n"
> +"  -?, --help   Give this help list\n"
> +"\n"
> +"Mandatory or optional arguments to long options are also mandatory 
> or optional\n"
> +"for any corresponding short options.\n\n");
> +}
>  
>  struct thread_args {
>  int thread_id;
> @@ -30,16 +62,21 @@ struct thread_args {
>  char *mode;
>  };
>  
> -void * concurrent(void *arguments) {
> -char name[4];
> +static void do_function(void *arguments)
> +{
> +char name[NAME_MAX+1];
>  struct thread_args *args = arguments;
>  struct lxc_container *c;
>  
> -sprintf(name, "%d", args->thread_id);
> +sprintf(name, "lxc-test-concurrent-%d", args->thread_id);
>  
> +args->return_code = 1;
>  c = lxc_container_new(name, NULL);
> +if (!c) {
> +fprintf(stderr, "Unable to instantiate container (%s)\n", name);
> +return;
> +}
>  
> -args->return_code = 1;
>  if (strcmp(args->mode, "create") == 0) {
>  if (!c->is_defined(c)) {
>  if (!c->create(c, template, NULL, NULL, 1, NULL)) {
> @@ -58,6 +95,7 @@ void * concurrent(void *arguments) {
>  fprintf(stderr, "Waiting the container (%s) to start 
> failed...\n", name);
>  goto out;
>  }
> +sleep(delay);
>  }
>  } else if(strcmp(args->mode, "stop") == 0) {
>  if (c->is_defined(c) && c->is_running(c)) {
> @@ -81,49 +119,95 @@ void * concurrent(void *arguments) {
>  args->return_code = 0;
>  out:
>  lxc_container_put(c);
> -pthread_exit(NULL);
>  }
>  
> +static void *concurrent(void *arguments)
> +{
> +do_function(arguments);
> +pthread_exit(NULL);
> +}
>  
>  int main(int argc, char *argv[]) {
> -int i, j;
> +int i, j, iter, opt;
>  pthread_attr_t attr;
> -pthread_t threads[NTHREADS];
> -struct thread_args args[NTHREADS];
> +pthread_t *threads;
> +struct thread_args *args;
>  
>  char *modes[] = {"create", "start", "stop", "destroy", NULL};
>  
> -if (argc > 1)
> - template = argv[1];
> -
>  pthread_attr_init(&attr);
> -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
>  
> -for (i = 0; modes[i];i++) {
> -printf("Executing (%s) for %d containers...\n", modes[i], NTHREADS);
> -for (j = 0; j < NTHREADS; j++) {
> -args[j].thread_id = j;
> -args[j].mode = modes[i];
> -
> -if (pthread_create(&threads[j], &attr, concurrent, (void *) 
> &args[j]) != 0) {
> -perror("pthread_create() error");
> -exit(EXIT_FAILURE);
> -}
> +while ((opt = getopt_long(arg

[lxc-devel] Linux Plumbers 2013 - Container mini-summit, (hopefully) final schedule

2013-09-16 Thread Stéphane Graber
Hey everyone,

So I just went through everything the other track leads accepted over
the past couple of weeks and split the remaining time as well as
(unfortunately) reduced some of the current time allocation for some of
the talks.

Basically anyone who didn't directly ask for more, now got a 15min time
slot so that we can fit everything in the time that we've got allocated.

The event schedule is at:
http://www.linuxplumbersconf.org/2013/ocw/events/LPC2013/schedule

With our mini-summit there:
http://www.linuxplumbersconf.org/2013/ocw/events/LPC2013/tracks/153

The current schedule is as follow:
== On the road to LXC 1.0 ==
Presented by: Serge Hallyn and Stéphane Graber
Duration: 20 minutes
Excerpt:
 Overview of what features to expect for LXC 1.0 and hints on how to
 help us get there.
 .
 LXC upstream is currently doing a big development push to get LXC 1.0
 out in early 2014.
 We’re now half-way through the planned development time and a lot of
 exciting things have already been done with a whole lot more to come.
 .
 This talk will go through our goal for 1.0, what has been done so far
 and what else will be coming very soon.

== LXC and Android ==
Presented by: Stéphane Graber
Duration: 15 minutes
Excerpt:
 Ever wanted to run Android in a container or run a Linux distro in a
 container on Android?
 .
 This talk will present some of the work I’ve been doing to get LXC to
 run natively on Android, allowing the user to then start a standard
 Linux distro in a container without impacting Android.
 .
 I’ll also cover doing it the other way around, where we instead run
 Android in a container on a standard Linux distro and why that makes
 developing new phone operating systems much easier.

== Let Me Contain That For You! ==
Presented by: Rohit Jnagal
Duration: 20 minutes
Excerpt:
 We’ll demonstrate a redesign of container management solution built for
 use at Google. The talk highlights our design motivation and some of the
 differences from existing container management solutions. We cover some
 lessons learnt during re-design that help us adapt to what we believe
 are the workloads of tomorrow:
 .
  - Larger machine (more cores and memory) which leads to more
containers. This requires a level of concurrency and scalability that
doesn’t exist today.
  - Higher utilization of machines, being able to pack containers more
tightly in order to use every last bit of resources available.
  - Priority bands for containers: Having different guarantees for
containers of different priorities (e.g.: paying customers vs. free
customers, latency sensitive vs. batch)
  - Hierarchical containment: There’s an increasing demand to run
containers inside containers to manage resources allocated to a user by
higher-level allocators e.g.: A container-based PaaS/IaaS letting users
create subcontainers per db query type, nominate sacrificial loads, etc.
 .
  We hope that this talk would help guide the kernel and userspace
  containers support for future resource isolation needs.

== State of CRIU (Checkpoint Restart In Userspace) and integration with LXC ==
Presented by: Pavel Emlianov and Serge Hallyn
Duration: 20 minutes
Excerpt:
 The CRIU project implements ability to take a state-dump of running
 Linux processes and restore them later. This feature allows for such
 things as live-migration, fast kernel update, fast services start and
 others.
 .
 This talk is about to introduce CRIU to the audience by showing its
 basic features and discussing integration with LXC’s checkpoint/restart
 commands.


== TEA BREAK ==
Presented by: Linux Plumbers 2013
Duration: 15 minutes


== Device namespace ==
Presented by: Amir Goldstein and Oren Laadan
Duration: 15 minutes
Excerpt:
 We (cellrox) have been working on bringing lightweight virtualization to
 Linux-based mobile devices like Android (or other Linux-based devices with
 diverse I/O) and want to share our solution: device namespaces.
 .
 Imagine you could run several instances of your favorite mobile OS or other
 distributions in isolated containers, each under the impression of having
 exclusive access to device drivers; Interact and switch between them within
 a blink, no flashing, no reboot.
 .
 Device namespaces are an extension to existing Linux kernel namespaces
 that brings lightweight virtualization to Linux-based end-user devices,
 primarily mobile devices. Device namespaces introduce a private and
 virtual namespace for device drivers to create the illusion for a
 process group that it interacts exclusively with a set of drivers.
 Device namespaces also introduce the concepts of an “active” namespace
 with which a user interacts, vs “non-active” namespaces that run in the
 background, and the ability to switch between them.

== Fedora/systemd on LXC ==
Presented by: Michal H. Warfield
Duration: 15 minutes
Excerpt:
 Discuss plans to ensure systemd-based distros continue to work on lxc.
 .
 Systemd occasionally presents challenges to lxc con

Re: [lxc-devel] [PATCH] cleanup fds, memory in lxc_cgroup_load_meta2()

2013-09-16 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> There are fd leaks in lxc_cgroup_load_meta2() in particular in the success
> case. This change attempts to ensure resources are free'd/close'd, but it
> is possible there are still some error cases where leaks occur.
> 
> Signed-off-by: Dwight Engen 
> ---
> Hi Christian,
> 
> These changes fix problems I was seeing with valgrind, but they may not be
> how you would do it, so feel free to rework them if I've messed up your
> code too bad :) The command I was using:
>  valgrind --leak-check=full --track-fds=yes ./lxc-test-concurrent -i 2 -j 1

Thanks for spotting them.  I think it'd be better to split that function
up first.  Then it should be easier both to spot the leaks and verify
patches.

I can take a stab at that sometime this week if (either of) you don't
have time.

>  src/lxc/cgroup.c | 83 
> 
>  1 file changed, 48 insertions(+), 35 deletions(-)
> 
> diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c
> index 9417e77..101998b 100644
> --- a/src/lxc/cgroup.c
> +++ b/src/lxc/cgroup.c
> @@ -124,7 +124,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const char 
> **subsystem_whitelist)
>   size_t token_capacity = 0;
>   char *line = NULL;
>   size_t sz = 0;
> - int r, saved_errno = 0;
> + int r, ret = ENOMEM;
>  
>   /* if the subsystem whitelist is not specified, include all
>* hierarchies that contain kernel subsystems by default but
> @@ -149,8 +149,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>  
>   /* Step 1: determine all kernel subsystems */
>   proc_cgroups = fopen_cloexec("/proc/cgroups", "r");
> - if (!proc_cgroups)
> - goto out_error;
> + if (!proc_cgroups) {
> + ret = errno;
> + goto out1;
> + }
>  
>   while (getline(&line, &sz, proc_cgroups) != -1) {
>   char *tab1;
> @@ -179,10 +181,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>  
>   r = lxc_grow_array((void ***)&kernel_subsystems, 
> &kernel_subsystems_capacity, kernel_subsystems_count + 1, 12);
>   if (r < 0)
> - goto out_error;
> + goto out2;
>   kernel_subsystems[kernel_subsystems_count] = strdup(line);
>   if (!kernel_subsystems[kernel_subsystems_count])
> - goto out_error;
> + goto out2;
>   kernel_subsystems_count++;
>   }
>  
> @@ -198,8 +200,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>* /proc/self is not valid, we try /proc/1/cgroup... */
>   if (!proc_self_cgroup)
>   proc_self_cgroup = fopen_cloexec("/proc/1/cgroup", "r");
> - if (!proc_self_cgroup)
> - goto out_error;
> + if (!proc_self_cgroup) {
> + ret = errno;
> + goto out2;
> + }
>  
>   while (getline(&line, &sz, proc_self_cgroup) != -1) {
>   /* file format: hierarchy:subsystems:group,
> @@ -234,25 +238,25 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>   */
>   r = lxc_grow_array((void ***)&meta_data->hierarchies, 
> &hierarchy_capacity, hierarchy_number + 1, 12);
>   if (r < 0)
> - goto out_error;
> + goto out3;
>  
>   meta_data->maximum_hierarchy = hierarchy_number;
>   }
>  
>   /* this shouldn't happen, we had this already */
>   if (meta_data->hierarchies[hierarchy_number])
> - goto out_error;
> + goto out3;
>  
>   h = calloc(1, sizeof(struct cgroup_hierarchy));
>   if (!h)
> - goto out_error;
> + goto out3;
>  
>   meta_data->hierarchies[hierarchy_number] = h;
>  
>   h->index = hierarchy_number;
>   h->subsystems = lxc_string_split_and_trim(colon1, ',');
>   if (!h->subsystems)
> - goto out_error;
> + goto out3;
>   /* see if this hierarchy should be considered */
>   if (!all_kernel_subsystems || !all_named_subsystems) {
>   for (p = h->subsystems; *p; p++) {
> @@ -283,8 +287,10 @@ struct cgroup_meta_data *lxc_cgroup_load_meta2(const 
> char **subsystem_whitelist)
>* /proc/self is not valid, we try /proc/1/cgroup... */
>   if (!proc_self_mountinfo)
>   proc_self_mountinfo = fopen_cloexec("/proc/1/mountinfo", "r");
> - if (!proc_self_mountinfo)
> - goto out_error;
> + if (!proc_self_mountinfo) {
> + ret = errno;
> + goto out3;
> + }
>  
>   while (getline(&line, &sz, proc_se

Re: [lxc-devel] [PATCH] lxc-create: conside create succeed when container is already created

2013-09-16 Thread Serge Hallyn
Quoting Qiang Huang (h.huangqi...@huawei.com):
> On 2013/9/16 12:23, Stéphane Graber wrote:
> > On Mon, Sep 16, 2013 at 11:37:02AM +0800, Qiang Huang wrote:
> >> Sometimes we use:
> >> lxc-create -n xxx -f config
> >> to copy config to the default lxcpath with the rootfs already
> >> exist.
> >> But we will get error right now, so fix this.
> > 
> > Hmm, I'm not sure I understand.
> > 
> > Running "lxc-create -n xxx -f config" when xxx already exists is an
> > error and should return an error code so the current code seems
> > perfectly right to me.
> 
> Well, it did works this way in the former lxc_create version.
> 
> We used to use LXC this way:
> - We made a template(rootfs, config and fstab) manually.

>From here, can you just write a script 'lxc-homebrew' which
copies the rootfs+config+fstab into place, and call

lxc-create -t homebrew -n c1

?

If you want to just copy the stuff in by hand, you can
do that.  You don't *have* to run lxc-create if you've done
everything by hand.

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


Re: [lxc-devel] [PATCH] lxc-create: conside create succeed when container is already created

2013-09-16 Thread Qiang Huang
On 2013/9/17 11:27, Serge Hallyn wrote:
> Quoting Qiang Huang (h.huangqi...@huawei.com):
>> On 2013/9/16 12:23, Stéphane Graber wrote:
>>> On Mon, Sep 16, 2013 at 11:37:02AM +0800, Qiang Huang wrote:
 Sometimes we use:
 lxc-create -n xxx -f config
 to copy config to the default lxcpath with the rootfs already
 exist.
 But we will get error right now, so fix this.
>>>
>>> Hmm, I'm not sure I understand.
>>>
>>> Running "lxc-create -n xxx -f config" when xxx already exists is an
>>> error and should return an error code so the current code seems
>>> perfectly right to me.
>>
>> Well, it did works this way in the former lxc_create version.
>>
>> We used to use LXC this way:
>> - We made a template(rootfs, config and fstab) manually.
> 
>>From here, can you just write a script 'lxc-homebrew' which
> copies the rootfs+config+fstab into place, and call
> 
>   lxc-create -t homebrew -n c1
> 
> ?
> 
> If you want to just copy the stuff in by hand, you can
> do that.  You don't *have* to run lxc-create if you've done
> everything by hand.

OK, thanks Serge.

So we are still not supposed to use lxc-create without -t option?
Is lxc-create only used for creating templates?

> 
> 



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