Re: [lxc-devel] Change rootfs pinning mechnism
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
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
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?
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
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
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
- 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
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
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
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
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
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
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
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
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
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
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
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
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
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!
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
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
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()
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
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
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
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()
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
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
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