[lxc-devel] [PATCH] use /var/lock/subsys/lxc-centos instead of /var/lock/subsys/lxc as a lock name
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- templates/lxc-centos.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/lxc-centos.in b/templates/lxc-centos.in index 6000cf2..95802dc 100644 --- a/templates/lxc-centos.in +++ b/templates/lxc-centos.in @@ -376,7 +376,7 @@ install_centos() return 0 -) 200/var/lock/subsys/lxc +) 200/var/lock/subsys/lxc-centos return $? } @@ -457,7 +457,7 @@ clean() rm --preserve-root --one-file-system -rf $cache echo Done. || exit 1 exit 0 -) 200/var/lock/subsys/lxc +) 200/var/lock/subsys/lxc-centos } usage() -- 1.8.3.2 -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ lxc-devel mailing list lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] use $LOCALSTATEDIR/lock/subsys/lxc-ubuntu$release as lock filename
Otherwise one cannot create two containers with different releases (let's say saucy [cached] and raring [not caced]) if both are not cached on the local filesystem already. The lock blocks cached one to move forward until not cached one finishes it's downloads. Fix that by seperating locks using release names Signed-off-by: S.Çağlar Onur cag...@10ur.org --- templates/lxc-ubuntu.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in index 3dcc93a..d8ac22d 100644 --- a/templates/lxc-ubuntu.in +++ b/templates/lxc-ubuntu.in @@ -369,7 +369,7 @@ install_ubuntu() return 0 -) 200$LOCALSTATEDIR/lock/subsys/lxc-ubuntu +) 200$LOCALSTATEDIR/lock/subsys/lxc-ubuntu$release return $? } -- 1.8.3.2 -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ lxc-devel mailing list lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] add comments about running unconfined or nesting containers back to ubuntu.common.conf
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- config/templates/ubuntu.common.conf.in | 7 +++ 1 file changed, 7 insertions(+) diff --git a/config/templates/ubuntu.common.conf.in b/config/templates/ubuntu.common.conf.in index 8c61033..1195175 100644 --- a/config/templates/ubuntu.common.conf.in +++ b/config/templates/ubuntu.common.conf.in @@ -17,6 +17,13 @@ lxc.pts = 1024 # Default capabilities lxc.cap.drop = sys_module mac_admin mac_override sys_time +# When using LXC with apparmor, uncomment the next line to run unconfined: +#lxc.aa_profile = unconfined + +# To support container nesting on an Ubuntu host, uncomment next two lines: +#lxc.aa_profile = lxc-container-default-with-nesting +#lxc.hook.mount = /usr/share/lxc/hooks/mountcgroups + # Default cgroup limits lxc.cgroup.devices.deny = a ## Allow any mknod (but not using the node) -- 1.8.3.2 -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ lxc-devel mailing list lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] ubuntu: Fix regression in post-process
Hi Dwight, On Wed, Dec 4, 2013 at 3:47 PM, Dwight Engen dwight.en...@oracle.com wrote: On Tue, 3 Dec 2013 23:34:43 -0500 S.Çağlar Onur cag...@10ur.org wrote: Hi, On Tue, Dec 3, 2013 at 6:53 PM, Stéphane Graber stgra...@ubuntu.com wrote: On Tue, Dec 03, 2013 at 05:43:47PM -0600, Serge Hallyn wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Hey Stéphane, On Wed, Nov 27, 2013 at 7:49 PM, Stéphane Graber stgra...@ubuntu.com wrote: THe recent reorg of lxc-ubuntu introduced some package installation in post-process but without first disabling service startup. As a result, if the cache is a bit out of date and a ssh update is available, post-process will apply that update (as it does apt-get install ssh vim) which in turn will attemp to start sshd. This will either lead to ssh on the host being restarted or if there's no sshd on the host, will fail the container creation as the postinst will get an error from upstart. The fix is very simply to add the same policy-rc.d trick when running post-process. I'm not sure whether this is the desired outcome (I haven't taken a look at it yet) but it looks like after this change lxc-create -n t -t ubuntu started to take more time (order of couple of minutes) to Can you reproduce this at will - revert the change and it's faster, reapply and it's slower? -serge Yes, lxc-ubuntu is now slower when creating a container as an extra apt-get update run and installation of vim was moved from being done when creating the cache to being done at container creation time. That change was caused by the addition of --packages which allows users to specify extra packages that should be available in the container. I believe at least one problem with that is that ssh is apt-get install'ed both at cache creation time and at container creation time. In most cases this would be a no-op, but if the cache is outdated, then ssh and openssh-server will get upgraded at container creation time, creating an extra delay. I think we should just be dropping ssh from the list of packages installed at creation time (since it's already in the original install) and I'd be happy to change the behaviour so that vim is always installed (as it used to be) and that this extra apt-get update + apt-get install run would only happen when extra packages are actually passed on the command line. To be honest that would be my preference otherwise creating containers in different times will produce different results and it might not be a good thing depending on how you look :) I believe we should be accepting the cache as the authoritative state over what distro provides on its repositories. Users can upgrade their containers or install/uninstall packages after the initial creation as they wish (or using this new --packages parameter) or could invalidate the cache by flushing it. One of the reasons I didn't do the cache thing in the Oracle template (for lxc-create it always fetches pkgs from upstream) was so that if you for example say lxc-create -n ol -t oracle -- -R 6.latest you actually get a container based on latest. My thought was that if you want faster creates, then you can do the create once and then just use lxc-clone after that. This also avoids any cache coherency problems that could crop up. I understand this desire but then question becomes why do we bother to keep a cache if we are going to download stuff from internet and loose that time? IMHO only a freshly created cache can help avoid downloading stuff from internet in this case. If your cache is let's say Oracle 6.3 and latest points to 6.5 then I bet you will end up downloading same if not more stuff from the internet while trying to create the container. And if we think cloning is the way to go then there is no need to do caching at all. Of course this is just a gut feeling and I have no empirical data to prove that. And just to be clear, I'm not opposing this behavior but just saying that I was expecting create to be an disconnected operation as long as there is a cache on FS backing that distro/release/arch. -- Stéphane Graber Ubuntu developer http://www.ubuntu.com Cheers, -- S.Çağlar Onur cag...@10ur.org -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ lxc-devel mailing list lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] add destroy option to lxc-snapshot
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxc_snapshot.c | 22 +++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/lxc/lxc_snapshot.c b/src/lxc/lxc_snapshot.c index f80afe5..1de5671 100644 --- a/src/lxc/lxc_snapshot.c +++ b/src/lxc/lxc_snapshot.c @@ -41,6 +41,7 @@ char *snapshot; #define DO_SNAP 0 #define DO_LIST 1 #define DO_RESTORE 2 +#define DO_DESTROY 3 int action; int print_comments; char *commentfile; @@ -100,7 +101,7 @@ int do_list_snapshots(struct lxc_container *c) return 0; } -int do_restore_snapshots(struct lxc_container *c, char *snap, char *new) +int do_restore_snapshots(struct lxc_container *c) { if (c-snapshot_restore(c, snapshot, newname)) return 0; @@ -109,11 +110,21 @@ int do_restore_snapshots(struct lxc_container *c, char *snap, char *new) return -1; } +int do_destroy_snapshots(struct lxc_container *c) +{ + if (c-snapshot_destroy(c, snapshot)) + return 0; + + ERROR(Error destroying snapshot %s, snapshot); + return -1; +} + static int my_parser(struct lxc_arguments* args, int c, char* arg) { switch (c) { case 'L': action = DO_LIST; break; case 'r': snapshot = arg; action = DO_RESTORE; break; + case 'd': snapshot = arg; action = DO_DESTROY; break; case 'c': commentfile = arg; break; case 'C': print_comments = true; break; } @@ -123,6 +134,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) static const struct option my_longopts[] = { {list, no_argument, 0, 'L'}, {restore, required_argument, 0, 'r'}, + {destroy, required_argument, 0, 'd'}, {comment, required_argument, 0, 'c'}, {showcomments, no_argument, 0, 'C'}, LXC_COMMON_OPTIONS @@ -141,7 +153,8 @@ Options :\n\ -L, --list list snapshots\n\ -C, --showcomments show snapshot comments in list\n\ -c, --comment=file add file as a comment\n\ - -r, --restore=name restore snapshot name, i.e. 'snap0'\n, + -r, --restore=name restore snapshot name, i.e. 'snap0'\n\ + -d, --destroy=name destroy snapshot name, i.e. 'snap0'\n, .options = my_longopts, .parser = my_parser, .checker = NULL, @@ -202,7 +215,10 @@ int main(int argc, char *argv[]) ret = do_list_snapshots(c); break; case DO_RESTORE: - ret = do_restore_snapshots(c, snapshot, newname); + ret = do_restore_snapshots(c); + break; + case DO_DESTROY: + ret = do_destroy_snapshots(c); break; } -- 1.8.3.2 -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] ubuntu: Fix regression in post-process
Hi, On Tue, Dec 3, 2013 at 6:53 PM, Stéphane Graber stgra...@ubuntu.com wrote: On Tue, Dec 03, 2013 at 05:43:47PM -0600, Serge Hallyn wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Hey Stéphane, On Wed, Nov 27, 2013 at 7:49 PM, Stéphane Graber stgra...@ubuntu.com wrote: THe recent reorg of lxc-ubuntu introduced some package installation in post-process but without first disabling service startup. As a result, if the cache is a bit out of date and a ssh update is available, post-process will apply that update (as it does apt-get install ssh vim) which in turn will attemp to start sshd. This will either lead to ssh on the host being restarted or if there's no sshd on the host, will fail the container creation as the postinst will get an error from upstart. The fix is very simply to add the same policy-rc.d trick when running post-process. I'm not sure whether this is the desired outcome (I haven't taken a look at it yet) but it looks like after this change lxc-create -n t -t ubuntu started to take more time (order of couple of minutes) to Can you reproduce this at will - revert the change and it's faster, reapply and it's slower? -serge Yes, lxc-ubuntu is now slower when creating a container as an extra apt-get update run and installation of vim was moved from being done when creating the cache to being done at container creation time. That change was caused by the addition of --packages which allows users to specify extra packages that should be available in the container. I believe at least one problem with that is that ssh is apt-get install'ed both at cache creation time and at container creation time. In most cases this would be a no-op, but if the cache is outdated, then ssh and openssh-server will get upgraded at container creation time, creating an extra delay. I think we should just be dropping ssh from the list of packages installed at creation time (since it's already in the original install) and I'd be happy to change the behaviour so that vim is always installed (as it used to be) and that this extra apt-get update + apt-get install run would only happen when extra packages are actually passed on the command line. To be honest that would be my preference otherwise creating containers in different times will produce different results and it might not be a good thing depending on how you look :) I believe we should be accepting the cache as the authoritative state over what distro provides on its repositories. Users can upgrade their containers or install/uninstall packages after the initial creation as they wish (or using this new --packages parameter) or could invalidate the cache by flushing it. -- Stéphane Graber Ubuntu developer http://www.ubuntu.com -- S.Çağlar Onur cag...@10ur.org -- Sponsored by Intel(R) XDK Develop, test and display web and hybrid apps with a single code base. Download it for free now! http://pubads.g.doubleclick.net/gampad/clk?id=111408631iu=/4140/ostg.clktrk ___ lxc-devel mailing list lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] ubuntu: Fix regression in post-process
Hey Stéphane, On Wed, Nov 27, 2013 at 7:49 PM, Stéphane Graber stgra...@ubuntu.com wrote: THe recent reorg of lxc-ubuntu introduced some package installation in post-process but without first disabling service startup. As a result, if the cache is a bit out of date and a ssh update is available, post-process will apply that update (as it does apt-get install ssh vim) which in turn will attemp to start sshd. This will either lead to ssh on the host being restarted or if there's no sshd on the host, will fail the container creation as the postinst will get an error from upstart. The fix is very simply to add the same policy-rc.d trick when running post-process. I'm not sure whether this is the desired outcome (I haven't taken a look at it yet) but it looks like after this change lxc-create -n t -t ubuntu started to take more time (order of couple of minutes) to complete. This wasn't the case couple of weeks ago, when I last tried creating an ubuntu container. I flushed the cache thinking that it's age is the problem but it didn't change anything, container still tries to install (or maybe upgrade) additional packages (I think vim and ssh) via apt. Is there a reason not to include those additional packages in the initial bootstrap phase? Signed-off-by: Stéphane Graber stgra...@ubuntu.com --- templates/lxc-ubuntu.in | 10 ++ 1 file changed, 10 insertions(+) diff --git a/templates/lxc-ubuntu.in b/templates/lxc-ubuntu.in index ac39ed2..4e6a54f 100644 --- a/templates/lxc-ubuntu.in +++ b/templates/lxc-ubuntu.in @@ -467,6 +467,13 @@ post_process() release=$2 packages=$3 +# Disable service startup +cat $rootfs/usr/sbin/policy-rc.d EOF +#!/bin/sh +exit 101 +EOF +chmod +x $rootfs/usr/sbin/policy-rc.d + if [ ! -f $rootfs/etc/init/container-detect.conf ]; then # Make sure we have a working resolv.conf cresolvonf=${rootfs}/etc/resolv.conf @@ -538,6 +545,9 @@ post_process() mv $rootfs/dev/shm $rootfs/dev/shm.bak ln -s /run/shm $rootfs/dev/shm fi + +# Re-enable service startup +rm $rootfs/usr/sbin/policy-rc.d } do_bindhome() -- 1.8.4.4 -- Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] Add LXC version information to version.h
So that applications can get the LXC version number at compile time. This can be used to make applications/bindings that support compiling against multiple versions of LXC. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 1 + configure.ac | 7 ++- src/lxc/version.h| 31 --- src/lxc/version.h.in | 36 4 files changed, 43 insertions(+), 32 deletions(-) delete mode 100644 src/lxc/version.h create mode 100644 src/lxc/version.h.in diff --git a/.gitignore b/.gitignore index 65d9a77..a38ceb0 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ src/lxc/lxc-version src/lxc/lxc-wait src/lxc/legacy/lxc-ls src/lxc/lxc-user-nic +src/lxc/version.h src/python-lxc/build/ src/python-lxc/lxc/__pycache__/ diff --git a/configure.ac b/configure.ac index e9d3128..7b3da91 100644 --- a/configure.ac +++ b/configure.ac @@ -14,6 +14,11 @@ AC_INIT([lxc], [lxc_version]) AC_SUBST(LXC_VERSION_BASE, lxc_version_base) AC_SUBST(LXC_VERSION_BETA, lxc_version_beta) +AC_SUBST([LXC_VERSION_MAJOR], [lxc_version_major]) +AC_SUBST([LXC_VERSION_MINOR], [lxc_version_minor]) +AC_SUBST([LXC_VERSION_MICRO], [lxc_version_micro]) +AC_SUBST([LXC_VERSION], [lxc_version]) + AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_HEADERS([src/config.h]) @@ -554,7 +559,7 @@ AC_CONFIG_FILES([ src/lxc/lxc-start-ephemeral src/lxc/legacy/lxc-ls src/lxc/lxc.functions - + src/lxc/version.h src/python-lxc/Makefile src/lua-lxc/Makefile diff --git a/src/lxc/version.h b/src/lxc/version.h deleted file mode 100644 index e2b0fc4..000 --- a/src/lxc/version.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * lxc: linux Container library - * - * (C) Copyright IBM Corp. 2007, 2008 - * - * Authors: - * Daniel Lezcano daniel.lezcano at free.fr - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef _version_h -#define _version_h - -/* - * Returns the version number of the library - */ -extern const char *lxc_version(void); - -#endif diff --git a/src/lxc/version.h.in b/src/lxc/version.h.in new file mode 100644 index 000..6867b6e --- /dev/null +++ b/src/lxc/version.h.in @@ -0,0 +1,36 @@ +/* + * lxc: linux Container library + * + * (C) Copyright IBM Corp. 2007, 2008 + * + * Authors: + * Daniel Lezcano daniel.lezcano at free.fr + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef _VERSION_H +#define _VERSION_H + +#define LXC_VERSION_MAJOR @LXC_VERSION_MAJOR@ +#define LXC_VERSION_MINOR @LXC_VERSION_MINOR@ +#define LXC_VERSION_MICRO @LXC_VERSION_MICRO@ +#define LXC_VERSION @LXC_VERSION@ + +/* + * Returns the version number of the library + */ +extern const char *lxc_version(void); + +#endif -- 1.8.3.2 -- Rapidly troubleshoot problems before they affect your business. Most IT organizations don't have a clear picture of how application performance affects their revenue. With AppDynamics, you get 100% visibility into your Java,.NET, PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro! http://pubads.g.doubleclick.net/gampad/clk?id=84349351iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Allow unsetting daemonize and close_fds
On Fri, Nov 29, 2013 at 2:34 PM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting Stéphane Graber (stgra...@ubuntu.com): As mentioned in a previous commit, this does two changes: - Make want_daemonize return a bool (false on failure, true on success) - Make both want_daemonize and want_close_all_fds take a state argument so the user can choose to unset those flags. This commit also updates all occurences of those two functions. Signed-off-by: Stéphane Graber stgra...@ubuntu.com Two comments below. With that and James' comments addressed, Acked-by: Serge E. Hallyn serge.hal...@ubuntu.com --- src/lua-lxc/core.c | 2 +- src/lxc/lxc_start.c| 4 ++-- src/lxc/lxccontainer.c | 20 +--- src/lxc/lxccontainer.h | 4 ++-- src/python-lxc/lxc.c | 10 -- src/tests/attach.c | 2 +- src/tests/cgpath.c | 2 +- src/tests/concurrent.c | 2 +- src/tests/console.c| 2 +- src/tests/containertests.c | 2 +- src/tests/createtest.c | 2 +- src/tests/shutdowntest.c | 2 +- 12 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/lua-lxc/core.c b/src/lua-lxc/core.c index 9492c07..04f2f1d 100644 --- a/src/lua-lxc/core.c +++ b/src/lua-lxc/core.c @@ -156,7 +156,7 @@ static int container_start(lua_State *L) argv[j] = NULL; } -c-want_daemonize(c); +c-want_daemonize(c, 1); lua_pushboolean(L, !!c-start(c, useinit, argv)); return 1; } diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index e537846..2a833a6 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -325,7 +325,7 @@ int main(int argc, char *argv[]) } if (my_args.daemonize) { - c-want_daemonize(c); + c-want_daemonize(c, 1); } if (pid_fp != NULL) { @@ -337,7 +337,7 @@ int main(int argc, char *argv[]) } if (my_args.close_all_fds) - c-want_close_all_fds(c); + c-want_close_all_fds(c, 1); err = c-start(c, 0, args) ? 0 : -1; diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 283fbb5..4234760 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -455,29 +455,35 @@ static bool lxcapi_load_config(struct lxc_container *c, const char *alt_file) return ret; } -static void lxcapi_want_daemonize(struct lxc_container *c) +static bool lxcapi_want_daemonize(struct lxc_container *c, int state) { + if (state 1) What about 0? Why we are not passing a bool instead of int? + return false; if (!c || !c-lxc_conf) - return; + return false; if (container_mem_lock(c)) { ERROR(Error getting mem lock); - return; + return false; } - c-daemonize = 1; + c-daemonize = state; /* daemonize implies close_all_fds so set it */ - c-lxc_conf-close_all_fds = 1; + if (state == 1) + c-lxc_conf-close_all_fds = 1; container_mem_unlock(c); + return true; } -static bool lxcapi_want_close_all_fds(struct lxc_container *c) +static bool lxcapi_want_close_all_fds(struct lxc_container *c, int state) { + if (state 1) Same. + return false; if (!c || !c-lxc_conf) return false; if (container_mem_lock(c)) { ERROR(Error getting mem lock); return false; } - c-lxc_conf-close_all_fds = 1; + c-lxc_conf-close_all_fds = state; container_mem_unlock(c); return true; } diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 6044f4d..8333610 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -209,7 +209,7 @@ struct lxc_container { * * \return \c true if container wants to be daemonised, else \c false. */ - void (*want_daemonize)(struct lxc_container *c); + bool (*want_daemonize)(struct lxc_container *c, int state); /*! * \brief Determine whether container wishes all file descriptors @@ -220,7 +220,7 @@ struct lxc_container { * \return \c true if container wants all file descriptors closed, * else \c false. */ - bool (*want_close_all_fds)(struct lxc_container *c); + bool (*want_close_all_fds)(struct lxc_container *c, int state); /*! * \brief Return current config file name. diff --git a/src/python-lxc/lxc.c b/src/python-lxc/lxc.c index b4f1da3..92d79f9 100644 --- a/src/python-lxc/lxc.c +++ b/src/python-lxc/lxc.c @@ -1301,11 +1301,17 @@ Container_start(Container *self, PyObject *args, PyObject *kwds) } if (close_fds close_fds == Py_True) { -self-container-want_close_all_fds(self-container); +self-container-want_close_all_fds(self-container, 1); +} +else { +self-container-want_close_all_fds(self-container, 0); }
[lxc-devel] [PATCH] add lxc-usernsexec to .gitignore
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 82b144a..b3eff27 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,7 @@ src/lxc/lxc-start-ephemeral src/lxc/lxc-stop src/lxc/lxc-unfreeze src/lxc/lxc-unshare +src/lxc/lxc-usernsexec src/lxc/lxc-version src/lxc/lxc-wait src/lxc/legacy/lxc-ls -- 1.8.3.2 -- Shape the Mobile Experience: Free Subscription Software experts and developers: Be at the forefront of tech innovation. Intel(R) Software Adrenaline delivers strategic insight and game-changing conversations that shape the rapidly evolving mobile landscape. Sign up now. http://pubads.g.doubleclick.net/gampad/clk?id=63431311iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] fix memory leaks reported by cppcheck in src/lxc/lxc_usernsexec.c
Free previously allocated memory if realloc fails. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxc_usernsexec.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lxc/lxc_usernsexec.c b/src/lxc/lxc_usernsexec.c index 9416f27..2957dd5 100644 --- a/src/lxc/lxc_usernsexec.c +++ b/src/lxc/lxc_usernsexec.c @@ -201,6 +201,7 @@ static int read_default_map(char *fnam, char which, char *username) if (line) free(line); fclose(fin); + free(newmap); return 0; } @@ -241,6 +242,7 @@ static int run_cmd(char **argv) static int map_child_uids(int pid, struct id_map *map) { char **uidargs = NULL, **gidargs = NULL; + char **newuidargs = NULL, **newgidargs = NULL; int i, nuargs = 2, ngargs = 2; struct id_map *m; @@ -263,9 +265,12 @@ static int map_child_uids(int pid, struct id_map *map) for (m=map; m; m = m-next) { if (m-which == 'b' || m-which == 'u') { nuargs += 3; - uidargs = realloc(uidargs, (nuargs+1) * sizeof(*uidargs)); - if (!uidargs) + newuidargs = realloc(uidargs, (nuargs+1) * sizeof(*uidargs)); + if (!newuidargs) { + free(uidargs) return -1; + } + uidargs = newuidargs; uidargs[nuargs - 3] = malloc(21); uidargs[nuargs - 2] = malloc(21); uidargs[nuargs - 1] = malloc(21); @@ -278,9 +283,12 @@ static int map_child_uids(int pid, struct id_map *map) } if (m-which == 'b' || m-which == 'g') { ngargs += 3; - gidargs = realloc(gidargs, (ngargs+1) * sizeof(*gidargs)); - if (!gidargs) + newgidargs = realloc(gidargs, (ngargs+1) * sizeof(*gidargs)); + if (!newgidargs){ + free(gidargs); return -1; + } + gidargs = newgidargs; gidargs[ngargs - 3] = malloc(21); gidargs[ngargs - 2] = malloc(21); gidargs[ngargs - 1] = malloc(21); -- 1.8.3.2 -- Shape the Mobile Experience: Free Subscription Software experts and developers: Be at the forefront of tech innovation. Intel(R) Software Adrenaline delivers strategic insight and game-changing conversations that shape the rapidly evolving mobile landscape. Sign up now. http://pubads.g.doubleclick.net/gampad/clk?id=63431311iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] fix memory leaks reported by cppcheck in src/lxc/conf.c, this also fixes possible crashes due to passing NULL to strlen
Hi Serge, On Mon, Nov 18, 2013 at 10:52 AM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Signed-off-by: S.Çağlar Onur cag...@10ur.org Hi, please try to keep a single, one-line description as the subject, with the longer patch description in the body. It will keep git history much neater. Sure, will do! One question below, --- src/lxc/conf.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index dec1c05..1af50e2 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2425,23 +2425,26 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd return -1; } veth1 = mkifname(veth1buf); + if (!veth1) { + ERROR(failed to allocate a temporary name); + return -1; + } /* store away for deconf */ memcpy(netdev-priv.veth_attr.veth1, veth1, IFNAMSIZ); } snprintf(veth2buf, sizeof(veth2buf), vethXX); veth2 = mkifname(veth2buf); - - if (!strlen(veth1) || !strlen(veth2)) { + if (!veth2) { ERROR(failed to allocate a temporary name); - return -1; + goto out_delete; } err = lxc_veth_create(veth1, veth2); if (err) { ERROR(failed to create %s-%s : %s, veth1, veth2, strerror(-err)); - return -1; + goto out_delete; } /* changing the high byte of the mac address to 0xfe, the bridge interface @@ -2500,6 +2503,10 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd out_delete: lxc_netdev_delete_by_name(veth1); + if (!netdev-priv.veth_attr.pair veth2) Did you mean to check for veth1 here? Ah yes it suppose to be veth1, do you want me to send a new version? + free(veth1); + if(veth2) + free(veth2); return -1; } @@ -2537,7 +2544,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n return -1; peer = mkifname(peerbuf); - if (!strlen(peer)) { + if (!peer) { ERROR(failed to make a temporary name); return -1; } @@ -2547,27 +2554,30 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n if (err) { ERROR(failed to create macvlan interface '%s' on '%s' : %s, peer, netdev-link, strerror(-err)); - return -1; + goto out; } netdev-ifindex = if_nametoindex(peer); if (!netdev-ifindex) { ERROR(failed to retrieve the index for %s, peer); - lxc_netdev_delete_by_name(peer); - return -1; + goto out; } if (netdev-upscript) { err = run_script(handler-name, net, netdev-upscript, up, macvlan, netdev-link, (char*) NULL); if (err) - return -1; + goto out; } DEBUG(instanciated macvlan '%s', index is '%d' and mode '%d', peer, netdev-ifindex, netdev-priv.macvlan_attr.mode); return 0; +out: +lxc_netdev_delete_by_name(peer); +free(peer); + return -1; } static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev) -- 1.8.3.2 -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] fix memory leaks reported by cppcheck in src/lxc/conf.c (v2)
This also fixes possible crashes due to passing NULL to strlen function Changes since v1; * Fixed a typo spotted by Serge Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/conf.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index dec1c05..caf92c4 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2425,23 +2425,26 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd return -1; } veth1 = mkifname(veth1buf); + if (!veth1) { + ERROR(failed to allocate a temporary name); + return -1; + } /* store away for deconf */ memcpy(netdev-priv.veth_attr.veth1, veth1, IFNAMSIZ); } snprintf(veth2buf, sizeof(veth2buf), vethXX); veth2 = mkifname(veth2buf); - - if (!strlen(veth1) || !strlen(veth2)) { + if (!veth2) { ERROR(failed to allocate a temporary name); - return -1; + goto out_delete; } err = lxc_veth_create(veth1, veth2); if (err) { ERROR(failed to create %s-%s : %s, veth1, veth2, strerror(-err)); - return -1; + goto out_delete; } /* changing the high byte of the mac address to 0xfe, the bridge interface @@ -2500,6 +2503,10 @@ static int instanciate_veth(struct lxc_handler *handler, struct lxc_netdev *netd out_delete: lxc_netdev_delete_by_name(veth1); + if (!netdev-priv.veth_attr.pair veth1) + free(veth1); + if(veth2) + free(veth2); return -1; } @@ -2537,7 +2544,7 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n return -1; peer = mkifname(peerbuf); - if (!strlen(peer)) { + if (!peer) { ERROR(failed to make a temporary name); return -1; } @@ -2547,27 +2554,30 @@ static int instanciate_macvlan(struct lxc_handler *handler, struct lxc_netdev *n if (err) { ERROR(failed to create macvlan interface '%s' on '%s' : %s, peer, netdev-link, strerror(-err)); - return -1; + goto out; } netdev-ifindex = if_nametoindex(peer); if (!netdev-ifindex) { ERROR(failed to retrieve the index for %s, peer); - lxc_netdev_delete_by_name(peer); - return -1; + goto out; } if (netdev-upscript) { err = run_script(handler-name, net, netdev-upscript, up, macvlan, netdev-link, (char*) NULL); if (err) - return -1; + goto out; } DEBUG(instanciated macvlan '%s', index is '%d' and mode '%d', peer, netdev-ifindex, netdev-priv.macvlan_attr.mode); return 0; +out: + lxc_netdev_delete_by_name(peer); + free(peer); + return -1; } static int shutdown_macvlan(struct lxc_handler *handler, struct lxc_netdev *netdev) -- 1.8.3.2 -- Shape the Mobile Experience: Free Subscription Software experts and developers: Be at the forefront of tech innovation. Intel(R) Software Adrenaline delivers strategic insight and game-changing conversations that shape the rapidly evolving mobile landscape. Sign up now. http://pubads.g.doubleclick.net/gampad/clk?id=63431311iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] Sorry for the git mess
Hey Stéphane, On Fri, Nov 15, 2013 at 4:12 PM, Stéphane Graber stgra...@ubuntu.com wrote: Hey everyone, Sorry for the github flood, apparently one should mix up --all and --tags when doing a release or you end up with a dozen extra branch in a matter of seconds... Anyway, that's all fixed and alpha3 has been tagged. Enjoy! It looks like you forgot to push configure.ac change (dceb6c80186aceb150a26456343610a43dfddc63) to master [caglar@oOo:~/Projects/lxc(master)] git diff lxc-1.0.0.alpha3..upstream/master diff --git a/configure.ac b/configure.ac index e85e558..6004b35 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ m4_define([lxc_version_major], 1) m4_define([lxc_version_minor], 0) m4_define([lxc_version_micro], 0) -m4_define([lxc_version_beta], [alpha3]) +m4_define([lxc_version_beta], [alpha2]) m4_define([lxc_version_base], [lxc_version_major.lxc_version_minor.lxc_version_micro]) m4_define([lxc_version], -- Stéphane Graber Ubuntu developer http://www.ubuntu.com -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] fix memory leaks reported by cppcheck in src/lxc/bdev.c
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/bdev.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index c7e5e5e..6acd29a 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -962,8 +962,10 @@ static int lvm_snapshot(const char *orig, const char *path, unsigned long size) // check if the original lv is backed by a thin pool, in which case we // cannot specify a size that's different from the original size. ret = lvm_is_thin_volume(orig); - if (ret == -1) + if (ret == -1) { + free(pathdup); return -1; + } if (!ret) { ret = execlp(lvcreate, lvcreate, -s, -L, sz, -n, lv, orig, (char *)NULL); @@ -1282,6 +1284,7 @@ static int btrfs_subvolume_create(const char *path) p = strrchr(newfull, '/'); if (!p) { ERROR(bad path: %s, path); + free(newfull); return -1; } *p = '\0'; @@ -1418,6 +1421,7 @@ static int btrfs_destroy(struct bdev *orig) p = strrchr(newfull, '/'); if (!p) { ERROR(bad path: %s, path); + free(newfull); return -1; } *p = '\0'; -- 1.8.3.2 -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] add missing paranthesis
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lsm/apparmor.c | 1 + src/lxc/lxccontainer.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c index aaf8056..a8d36c1 100644 --- a/src/lxc/lsm/apparmor.c +++ b/src/lxc/lsm/apparmor.c @@ -90,6 +90,7 @@ again: sz += 1024; buf = realloc(buf, sz); if (!buf) { + free(buf); ERROR(out of memory); process_lock(); fclose(f); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 3cabf0d..11e70cb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2958,9 +2958,9 @@ static bool add_remove_device_node(struct lxc_container *c, char *src_path, char goto out; /* continue if path is character device or block device */ - if S_ISCHR(st.st_mode) + if (S_ISCHR(st.st_mode)) ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); - else if S_ISBLK(st.st_mode) + else if (S_ISBLK(st.st_mode)) ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); else goto out; -- 1.8.3.2 -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/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 missing paranthesis
Please don't apply this as it contains an unrelated chunk in it. Correct one will hit the list in a minute. On Thu, Nov 14, 2013 at 11:21 PM, S.Çağlar Onur cag...@10ur.org wrote: Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lsm/apparmor.c | 1 + src/lxc/lxccontainer.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c index aaf8056..a8d36c1 100644 --- a/src/lxc/lsm/apparmor.c +++ b/src/lxc/lsm/apparmor.c @@ -90,6 +90,7 @@ again: sz += 1024; buf = realloc(buf, sz); if (!buf) { + free(buf); ERROR(out of memory); process_lock(); fclose(f); diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 3cabf0d..11e70cb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2958,9 +2958,9 @@ static bool add_remove_device_node(struct lxc_container *c, char *src_path, char goto out; /* continue if path is character device or block device */ - if S_ISCHR(st.st_mode) + if (S_ISCHR(st.st_mode)) ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); - else if S_ISBLK(st.st_mode) + else if (S_ISBLK(st.st_mode)) ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); else goto out; -- 1.8.3.2 -- S.Çağlar Onur cag...@10ur.org -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] add missing paranthesis (v2)
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 3cabf0d..11e70cb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2958,9 +2958,9 @@ static bool add_remove_device_node(struct lxc_container *c, char *src_path, char goto out; /* continue if path is character device or block device */ - if S_ISCHR(st.st_mode) + if (S_ISCHR(st.st_mode)) ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); - else if S_ISBLK(st.st_mode) + else if (S_ISBLK(st.st_mode)) ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); else goto out; -- 1.8.3.2 -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] free previously allocated memory if realloc fails in src/lxc/lsm/apparmor.c
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lsm/apparmor.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c index aaf8056..f7f2ff9 100644 --- a/src/lxc/lsm/apparmor.c +++ b/src/lxc/lsm/apparmor.c @@ -68,7 +68,7 @@ static char *apparmor_process_label_get(pid_t pid) { char path[100], *space; int ret; - char *buf = NULL; + char *buf = NULL, *newbuf; int sz = 0; FILE *f; @@ -88,14 +88,16 @@ again: return NULL; } sz += 1024; - buf = realloc(buf, sz); - if (!buf) { + newbuf = realloc(buf, sz); + if (!newbuf) { + free(buf); ERROR(out of memory); process_lock(); fclose(f); process_unlock(); return NULL; } + buf = newbuf; memset(buf, 0, sz); ret = fread(buf, 1, sz - 1, f); process_lock(); -- 1.8.3.2 -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] gather all locking related code into src/lxc/lxclock.c
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxclock.c | 74 +-- src/lxc/lxclock.h | 3 +++ src/lxc/utils.c | 57 +- 3 files changed, 65 insertions(+), 69 deletions(-) diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c index 3857ff0..64823d2 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c @@ -31,6 +31,10 @@ #include lxc/log.h #include lxc/lxccontainer.h +#ifdef MUTEX_DEBUGGING +#include execinfo.h +#endif + #define OFLAG (O_CREAT | O_RDWR) #define SEMMODE 0660 #define SEMVALUE 1 @@ -40,10 +44,55 @@ lxc_log_define(lxc_lock, lxc); #ifdef MUTEX_DEBUGGING pthread_mutex_t thread_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +pthread_mutex_t static_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + +inline void dump_stacktrace(void) +{ + void *array[MAX_STACKDEPTH]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, MAX_STACKDEPTH); + strings = backtrace_symbols(array, size); + + // Using fprintf here as our logging module is not thread safe + fprintf(stderr, \tObtained %zd stack frames.\n, size); + + for (i = 0; i size; i++) + fprintf(stderr, \t\t%s\n, strings[i]); + + free (strings); +} #else pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; + +inline void dump_stacktrace(void) {;} #endif +void lock_mutex(pthread_mutex_t *l) +{ + int ret; + + if ((ret = pthread_mutex_lock(l)) != 0) { + fprintf(stderr, pthread_mutex_lock returned:%d %s, ret, strerror(ret)); + dump_stacktrace(); + exit(1); + } +} + +void unlock_mutex(pthread_mutex_t *l) +{ + int ret; + + if ((ret = pthread_mutex_unlock(l)) != 0) { + fprintf(stderr, pthread_mutex_lock returned:%d %s, ret, strerror(ret)); + dump_stacktrace(); + exit(1); + } +} + static char *lxclock_name(const char *p, const char *n) { int ret; @@ -267,24 +316,23 @@ void lxc_putlock(struct lxc_lock *l) void process_lock(void) { - int ret; - - if ((ret = pthread_mutex_lock(thread_mutex)) != 0) { - ERROR(pthread_mutex_lock returned:%d %s, ret, strerror(ret)); - dump_stacktrace(); - exit(1); - } + lock_mutex(thread_mutex); } void process_unlock(void) { - int ret; + unlock_mutex(thread_mutex); +} - if ((ret = pthread_mutex_unlock(thread_mutex)) != 0) { - ERROR(pthread_mutex_unlock returned:%d %s, ret, strerror(ret)); - dump_stacktrace(); - exit(1); - } +/* Protects static const values inside the lxc_global_config_value funtion */ +void static_lock(void) +{ + lock_mutex(static_mutex); +} + +void static_unlock(void) +{ + unlock_mutex(static_mutex); } int container_mem_lock(struct lxc_container *c) diff --git a/src/lxc/lxclock.h b/src/lxc/lxclock.h index dcdf79d..12ba827 100644 --- a/src/lxc/lxclock.h +++ b/src/lxc/lxclock.h @@ -87,6 +87,9 @@ extern void lxc_putlock(struct lxc_lock *l); extern void process_lock(void); extern void process_unlock(void); +extern void static_lock(void); +extern void static_unlock(void); + struct lxc_container; extern int container_mem_lock(struct lxc_container *c); extern void container_mem_unlock(struct lxc_container *c); diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 4bc2c35..3fab9ae 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -39,11 +39,6 @@ #include sys/types.h #include sys/wait.h #include assert.h -#include pthread.h - -#ifdef MUTEX_DEBUGGING -#include execinfo.h -#endif #ifndef HAVE_GETLINE #ifdef HAVE_FGETLN @@ -59,57 +54,6 @@ lxc_log_define(lxc_utils, lxc); - -#ifdef MUTEX_DEBUGGING -static pthread_mutex_t static_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; - -inline void dump_stacktrace(void) -{ - void *array[MAX_STACKDEPTH]; - size_t size; - char **strings; - size_t i; - - size = backtrace(array, MAX_STACKDEPTH); - strings = backtrace_symbols(array, size); - - // Using fprintf here as our logging module is not thread safe - fprintf(stderr, \tObtained %zd stack frames.\n, size); - - for (i = 0; i size; i++) - fprintf(stderr, \t\t%s\n, strings[i]); - - free (strings); -} -#else -static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER; - -inline void dump_stacktrace(void) {;} -#endif - -/* Protects static const values inside the lxc_global_config_value funtion */ -static void static_lock(void) -{ - int ret; - - if ((ret = pthread_mutex_lock(static_mutex)) != 0) { - ERROR(pthread_mutex_lock returned:%d %s, ret, strerror(ret)); - dump_stacktrace(); - exit(1); - } -} - -static void
Re: [lxc-devel] [PATCH] replace redundant creat() with open()
On Nov 8, 2013 5:20 PM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Hey Serge, On Fri, Nov 8, 2013 at 4:06 PM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC Hi, I'm confused - what is redundant in the use of creat()? If there is an improvement here then I don't understand what it is. Otherwise I'd argue creat() is more concise and clearer about its intent. There is no improvement other than a syntactic change (assuming creat() is also protected by glibc like open()). I saw them while trying to come up with a list of functions protected by process_lock and replaced them with open() without checking what glibc does. If you think creat is also protected than please feel free to drop this :) int __libc_creat (file, mode) const char *file; mode_t mode; { return __open (file, O_WRONLY|O_CREAT|O_TRUNC, mode); } Eheh see, redundant as well as missing a letter :P :) -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Protect global variables in log module via mutex
Hi Serge, On Mon, Nov 11, 2013 at 4:04 PM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Log module contains multiple global variables so protect them introducing a new mutex and serialize accessing log functions. Also gather all locking related code into src/lxc/lxclock.c Signed-off-by: S.Çağlar Onur cag...@10ur.org Really the log stuff should be re-thought. What should happen right now if two threads both call lxcapi_start() on containers with lxc.logfile entries? Perhaps we need two sets of log info. One for the program being used, and one for the running container. Anything done after src/lxc/start.c:lxc_start() logs to the container log info - that's anyhthing relating to container setup, container monitor stuff, hooks, and the running of the container. Anything else is done to the global log info - as that'll be shared by all threads. Agreed. Hopefully someone finds this interesting enough to write a patch :) In the meantime - the infrastructure of this patch seems good, but I don't think it really achieves protection of those variables. log_fname and lxc_log_fd especially, because __lxc_log_set_file() can close/free them concurrent with other __lxc_log_set_file() runs and concurrent with lxc_log_get_file(). What do you think would be the best way to achieve that? Hmmm just an idea without giving lots of thought but considering the objective above what about storing those variables in container struct, adding a new method to API like c-log(c, MESSAGE, LEVEL) (or some helpers like APIERROR(c, MESSAGE), APIWARNING etc) and re-using parts of the log module there. Come to think of it, do we really need to have a global/shared logging at all? What do you think making the whole logging thing to container specific? --- src/lxc/log.c | 16 ++ src/lxc/log.h | 4 +++ src/lxc/lxclock.c | 87 ++- src/lxc/lxclock.h | 5 src/lxc/utils.c | 57 +--- 5 files changed, 100 insertions(+), 69 deletions(-) diff --git a/src/lxc/log.c b/src/lxc/log.c index d6ce361..8a5c511 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -265,11 +265,15 @@ static int __lxc_log_set_file(const char *fname, int create_dirs) return -1; } + log_lock(); lxc_log_fd = log_open(fname); + log_unlock(); if (lxc_log_fd == -1) return -1; + log_lock(); log_fname = strdup(fname); + log_unlock(); return 0; } @@ -306,15 +310,19 @@ extern int lxc_log_init(const char *name, const char *file, return -1; } + log_lock(); lxc_loglevel_specified = 1; lxc_priority = lxc_log_priority_to_int(priority); + log_unlock(); } + log_lock(); lxc_log_category_lxc.priority = lxc_priority; lxc_log_category_lxc.appender = log_appender_logfile; if (!quiet) lxc_log_category_lxc.appender-next = log_appender_stderr; + log_unlock(); if (prefix) lxc_log_set_prefix(prefix); @@ -322,7 +330,9 @@ extern int lxc_log_init(const char *name, const char *file, if (file) { if (strcmp(file, none) == 0) return 0; + log_lock(); lxc_logfile_specified = 1; + log_unlock(); ret = __lxc_log_set_file(file, 1); } else { ret = -1; @@ -368,8 +378,10 @@ extern int lxc_log_set_level(int level) ERROR(invalid log priority %d, level); return -1; } + log_lock(); lxc_loglevel_specified = 1; lxc_log_category_lxc.priority = level; + log_unlock(); return 0; } @@ -397,7 +409,9 @@ extern int lxc_log_set_file(const char *fname) { if (lxc_logfile_specified) return 0; + log_lock(); lxc_logfile_specified = 1; + log_unlock(); return __lxc_log_set_file(fname, 0); } @@ -408,8 +422,10 @@ extern const char *lxc_log_get_file(void) extern void lxc_log_set_prefix(const char *prefix) { + log_lock(); strncpy(log_prefix, prefix, sizeof(log_prefix)); log_prefix[sizeof(log_prefix) - 1] = 0; + log_unlock(); } extern const char *lxc_log_get_prefix(void) diff --git a/src/lxc/log.h b/src/lxc/log.h index d3c40fb..59e8dd6 100644 --- a/src/lxc/log.h +++ b/src/lxc/log.h @@ -30,6 +30,8 @@ #include string.h #include stdbool.h +#include lxclock.h + #ifndef O_CLOEXEC #define O_CLOEXEC 0200 #endif @@ -183,6 +185,7 @@ static inline void LXC_##PRIORITY(struct lxc_log_locinfo *, \ static inline void LXC_##PRIORITY(struct lxc_log_locinfo* locinfo, \ const char* format, ...) \ {
Re: [lxc-devel] [PATCH] fix multithreaded create()
On Tue, Nov 12, 2013 at 2:04 PM, Dwight Engen dwight.en...@oracle.com wrote: We were calling save_config() twice within the create() flow, each from a different process. Depending on order of scheduling, sometimes the data from the first save_config() (which was just the stuff from LXC_DEFAULT_CONFIG) would overwrite the config we wanted (the full config), causing a truncated config file which would then cause lxc to segfault once it read it back in because no rootfs.path was set. This fixes it by only calling save_config() once in the create() flow. A rejected alternative was to call fsync(fileno(fout)) before the fclose in save_config. Signed-off-by: Dwight Engen dwight.en...@oracle.com Great news; This solved the concurrent create problems for me Bad news; I started to observe destroy() failures (see below) [caglar@qp:~/go/src/github.com/caglar10ur/lxc/examples] sudo ./concurrent_stress -iteration=100 -count=10 lxc_container: Error destroying rootfs for 5 2013/11/12 14:31:43 [ERROR] ERROR: destroying the container 5 failed 2013/11/12 14:31:43 [ERROR] ERROR: container 5 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:32:10 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:32:10 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:32:25 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:32:25 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 7 2013/11/12 14:32:30 [ERROR] ERROR: destroying the container 7 failed 2013/11/12 14:32:30 [ERROR] ERROR: container 7 already defined lxc_container: Error destroying rootfs for 4 2013/11/12 14:33:25 [ERROR] ERROR: destroying the container 4 failed 2013/11/12 14:33:25 [ERROR] ERROR: container 4 already defined lxc_container: Error destroying rootfs for 0 2013/11/12 14:33:40 [ERROR] ERROR: destroying the container 0 failed 2013/11/12 14:33:40 [ERROR] ERROR: container 0 already defined lxc_container: Error destroying rootfs for 0 2013/11/12 14:33:45 [ERROR] ERROR: destroying the container 0 failed 2013/11/12 14:33:45 [ERROR] ERROR: container 0 already defined lxc_container: Error destroying rootfs for 8 2013/11/12 14:33:55 [ERROR] ERROR: destroying the container 8 failed 2013/11/12 14:33:55 [ERROR] ERROR: container 8 already defined lxc_container: Error destroying rootfs for 2 2013/11/12 14:34:40 [ERROR] ERROR: destroying the container 2 failed 2013/11/12 14:34:40 [ERROR] ERROR: container 2 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:34:45 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:34:45 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 9 2013/11/12 14:35:00 [ERROR] ERROR: destroying the container 9 failed 2013/11/12 14:35:01 [ERROR] ERROR: container 9 already defined [caglar@qp:~/go/src/github.com/caglar10ur/lxc/examples] but since the original problem is gone now Acked-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index c7b2f5e..05ca643 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1192,16 +1192,19 @@ static bool lxcapi_create(struct lxc_container *c, const char *t, if (lxcapi_is_defined(c) c-lxc_conf c-lxc_conf-rootfs.path access(c-lxc_conf-rootfs.path, F_OK) == 0 tpath) { ERROR(Container %s:%s already exists, c-config_path, c-name); - free(tpath); - return false; + goto free_tpath; } - /* Save the loaded configuration to disk */ - if (!c-save_config(c, NULL)) { - ERROR(failed to save starting configuration for %s\n, c-name); - goto out; + if (!c-lxc_conf) { + if (!c-load_config(c, LXC_DEFAULT_CONFIG)) { + ERROR(Error loading default configuration file %s\n, LXC_DEFAULT_CONFIG); + goto free_tpath; + } } + if (!create_container_dir(c)) + goto free_tpath; + /* * either template or rootfs.path should be set. * if both template and rootfs.path are set, template is setup as rootfs.path. @@ -1290,10 +1293,11 @@ out_unlock: if (partial_fd = 0) remove_partial(c, partial_fd); out: - if
Re: [lxc-devel] [PATCH] fix multithreaded create()
Hi Dwight, On Tue, Nov 12, 2013 at 3:31 PM, Dwight Engen dwight.en...@oracle.com wrote: On Tue, 12 Nov 2013 14:35:58 -0500 S.Çağlar Onur cag...@10ur.org wrote: On Tue, Nov 12, 2013 at 2:04 PM, Dwight Engen dwight.en...@oracle.com wrote: We were calling save_config() twice within the create() flow, each from a different process. Depending on order of scheduling, sometimes the data from the first save_config() (which was just the stuff from LXC_DEFAULT_CONFIG) would overwrite the config we wanted (the full config), causing a truncated config file which would then cause lxc to segfault once it read it back in because no rootfs.path was set. This fixes it by only calling save_config() once in the create() flow. A rejected alternative was to call fsync(fileno(fout)) before the fclose in save_config. Signed-off-by: Dwight Engen dwight.en...@oracle.com Great news; This solved the concurrent create problems for me Bad news; I started to observe destroy() failures (see below) Hmm, you are testing through the go binding correct? I ran these two without error: ./src/tests/lxc-test-concurrent -i 200 -j 8 create,destroy ./src/tests/lxc-test-concurrent -i 100 -j 8 I wonder if lxc-test-concurrent will fail for you? Hmm will try ASAP. Also I remembered that I started to use best bdev option on my desktop machine which uses btrfs so maybe it has something to do with it. I'll revert back to dir type on Go bindings and try that again as well. Will report back as soon as I have something! [caglar@qp:~/go/src/github.com/caglar10ur/lxc/examples] sudo ./concurrent_stress -iteration=100 -count=10 lxc_container: Error destroying rootfs for 5 2013/11/12 14:31:43 [ERROR] ERROR: destroying the container 5 failed 2013/11/12 14:31:43 [ERROR] ERROR: container 5 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:32:10 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:32:10 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:32:25 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:32:25 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 7 2013/11/12 14:32:30 [ERROR] ERROR: destroying the container 7 failed 2013/11/12 14:32:30 [ERROR] ERROR: container 7 already defined lxc_container: Error destroying rootfs for 4 2013/11/12 14:33:25 [ERROR] ERROR: destroying the container 4 failed 2013/11/12 14:33:25 [ERROR] ERROR: container 4 already defined lxc_container: Error destroying rootfs for 0 2013/11/12 14:33:40 [ERROR] ERROR: destroying the container 0 failed 2013/11/12 14:33:40 [ERROR] ERROR: container 0 already defined lxc_container: Error destroying rootfs for 0 2013/11/12 14:33:45 [ERROR] ERROR: destroying the container 0 failed 2013/11/12 14:33:45 [ERROR] ERROR: container 0 already defined lxc_container: Error destroying rootfs for 8 2013/11/12 14:33:55 [ERROR] ERROR: destroying the container 8 failed 2013/11/12 14:33:55 [ERROR] ERROR: container 8 already defined lxc_container: Error destroying rootfs for 2 2013/11/12 14:34:40 [ERROR] ERROR: destroying the container 2 failed 2013/11/12 14:34:40 [ERROR] ERROR: container 2 already defined lxc_container: Error destroying rootfs for 1 2013/11/12 14:34:45 [ERROR] ERROR: destroying the container 1 failed 2013/11/12 14:34:45 [ERROR] ERROR: container 1 already defined lxc_container: Error destroying rootfs for 9 2013/11/12 14:35:00 [ERROR] ERROR: destroying the container 9 failed 2013/11/12 14:35:01 [ERROR] ERROR: container 9 already defined [caglar@qp:~/go/src/github.com/caglar10ur/lxc/examples] but since the original problem is gone now Acked-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 20 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index c7b2f5e..05ca643 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1192,16 +1192,19 @@ static bool lxcapi_create(struct lxc_container *c, const char *t, if (lxcapi_is_defined(c) c-lxc_conf c-lxc_conf-rootfs.path access(c-lxc_conf-rootfs.path, F_OK) == 0 tpath) { ERROR(Container %s:%s already exists, c-config_path, c-name); - free(tpath); - return false; + goto free_tpath; } - /* Save the loaded configuration to disk */ - if (!c-save_config(c, NULL)) { -
[lxc-devel] [PATCH] introduce lxcapi_add_device_node and lxcapi_remove_device_node to API (v2)
Adding block/char devices to running container is a common operation so provide a common implementation for users to consume. changes since v2; * removed duplicated code Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 84 ++ src/lxc/lxccontainer.h | 9 ++ 2 files changed, 93 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 05ca643..c21bc96 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -62,6 +62,8 @@ #endif #endif +#define MAX_BUFFER 4096 + lxc_log_define(lxc_container, lxc); static bool file_exists(char *f) @@ -2920,6 +2922,86 @@ static bool lxcapi_may_control(struct lxc_container *c) return lxc_try_cmd(c-name, c-config_path) == 0; } +static bool add_remove_device_node(struct lxc_container *c, char *src_path, bool add) +{ + int ret; + struct stat st; + char value[MAX_BUFFER]; + char dest_path[MAXPATHLEN]; + + /* make sure container is running */ + if (!c-is_running(c)) { + ERROR(container is not running); + return false; + } + + /* prepare dest_path */ + ret = snprintf(dest_path, MAXPATHLEN, /proc/%d/root%s, c-init_pid(c), src_path); + if (ret 0 || ret = MAXPATHLEN) + return false; + + if (add) { + /* make sure that we can access src_path */ + if(access(src_path, F_OK) 0 || stat(src_path, st) 0) + return false; + } else { + /* make sure that we can access dest_path */ + if(access(dest_path, F_OK) 0 || stat(dest_path, st) 0) + return false; + } + + /* continue if path is character device or block device */ + if S_ISCHR(st.st_mode) + ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else if S_ISBLK(st.st_mode) + ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else + return false; + + /* check snprintf return code */ + if (ret 0 || ret = MAX_BUFFER) + return false; + + /* remove dest_path if it exists */ + if(access(dest_path, F_OK) == 0) { + if (unlink(dest_path) 0) { + ERROR(unlink failed); + return false; + } + } + + if (add) { + /* create the device node */ + if (mknod(dest_path, st.st_mode, st.st_rdev) 0) { + ERROR(mknod failed); + return false; + } + + /* add to device list */ + if (!c-set_cgroup_item(c, devices.allow, value)) { + ERROR(set_cgroup_item failed while adding the device node); + return false; + } + } else { + /* remove from device list */ + if (!c-set_cgroup_item(c, devices.deny, value)) { + ERROR(set_cgroup_item failed while removing the device node); + return false; + } + } + return true; +} + +static bool lxcapi_add_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, true); +} + +static bool lxcapi_remove_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, false); +} + static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) { va_list ap; @@ -3041,6 +3123,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c-snapshot_restore = lxcapi_snapshot_restore; c-snapshot_destroy = lxcapi_snapshot_destroy; c-may_control = lxcapi_may_control; + c-add_device_node = lxcapi_add_device_node; + c-remove_device_node = lxcapi_remove_device_node; /* we'll allow the caller to update these later */ if (lxc_log_init(NULL, none, NULL, lxc_container, 0, c-config_path)) { diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 486035a..a94de9a 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -236,6 +236,15 @@ struct lxc_container { * and the caller may not access it. Return true otherwise. */ bool (*may_control)(struct lxc_container *c); + + /* +* Returns true if given device succesfully added to container +*/ + bool (*add_device_node)(struct lxc_container *c, char *path); + /* +* Returns true if given device succesfully removed from container +*/ + bool (*remove_device_node)(struct lxc_container *c, char *path); }; struct lxc_snapshot { -- 1.8.3.2
Re: [lxc-devel] [PATCH] introduce lxcapi_add_device_node and lxcapi_remove_device_node to API (v2)
Hi Stéphane, On Tue, Nov 12, 2013 at 10:51 PM, Stéphane Graber stgra...@ubuntu.com wrote: On Tue, Nov 12, 2013 at 10:47:06PM -0500, S.Çağlar Onur wrote: Adding block/char devices to running container is a common operation so provide a common implementation for users to consume. changes since v2; * removed duplicated code lxc-device which currently implements something like that as a tool in python also lets the user set an alternate path inside the container. Can we have the C API offer the same feature so I can use the new API instead of keeping my own implementation? Sure thing, in fact lxc-device is the reason why I come up with this patch. I wanted to provide the same functionality to Go users and implemented it in Go first but then I thought we can have this in the C API and all bindings (and users) can use it. I'll try to add alternate path to it and will re-send, assuming having this in the API is acceptable. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 84 ++ src/lxc/lxccontainer.h | 9 ++ 2 files changed, 93 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 05ca643..c21bc96 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -62,6 +62,8 @@ #endif #endif +#define MAX_BUFFER 4096 + lxc_log_define(lxc_container, lxc); static bool file_exists(char *f) @@ -2920,6 +2922,86 @@ static bool lxcapi_may_control(struct lxc_container *c) return lxc_try_cmd(c-name, c-config_path) == 0; } +static bool add_remove_device_node(struct lxc_container *c, char *src_path, bool add) +{ + int ret; + struct stat st; + char value[MAX_BUFFER]; + char dest_path[MAXPATHLEN]; + + /* make sure container is running */ + if (!c-is_running(c)) { + ERROR(container is not running); + return false; + } + + /* prepare dest_path */ + ret = snprintf(dest_path, MAXPATHLEN, /proc/%d/root%s, c-init_pid(c), src_path); + if (ret 0 || ret = MAXPATHLEN) + return false; + + if (add) { + /* make sure that we can access src_path */ + if(access(src_path, F_OK) 0 || stat(src_path, st) 0) + return false; + } else { + /* make sure that we can access dest_path */ + if(access(dest_path, F_OK) 0 || stat(dest_path, st) 0) + return false; + } + + /* continue if path is character device or block device */ + if S_ISCHR(st.st_mode) + ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else if S_ISBLK(st.st_mode) + ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else + return false; + + /* check snprintf return code */ + if (ret 0 || ret = MAX_BUFFER) + return false; + + /* remove dest_path if it exists */ + if(access(dest_path, F_OK) == 0) { + if (unlink(dest_path) 0) { + ERROR(unlink failed); + return false; + } + } + + if (add) { + /* create the device node */ + if (mknod(dest_path, st.st_mode, st.st_rdev) 0) { + ERROR(mknod failed); + return false; + } + + /* add to device list */ + if (!c-set_cgroup_item(c, devices.allow, value)) { + ERROR(set_cgroup_item failed while adding the device node); + return false; + } + } else { + /* remove from device list */ + if (!c-set_cgroup_item(c, devices.deny, value)) { + ERROR(set_cgroup_item failed while removing the device node); + return false; + } + } + return true; +} + +static bool lxcapi_add_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, true); +} + +static bool lxcapi_remove_device_node(struct lxc_container *c, char *path) +{ + return add_remove_device_node(c, path, false); +} + static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) { va_list ap; @@ -3041,6 +3123,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c-snapshot_restore = lxcapi_snapshot_restore; c-snapshot_destroy = lxcapi_snapshot_destroy; c-may_control = lxcapi_may_control; + c-add_device_node = lxcapi_add_device_node; + c-remove_device_node = lxcapi_remove_device_node; /* we'll allow the caller to update these later */ if (lxc_log_init(NULL, none, NULL, lxc_container, 0, c-config_path)) { diff --git
Re: [lxc-devel] [PATCH] fix multithreaded create()
Hey Dwight, On Tue, Nov 12, 2013 at 3:35 PM, S.Çağlar Onur cag...@10ur.org wrote: Hmm, you are testing through the go binding correct? I ran these two without error: ./src/tests/lxc-test-concurrent -i 200 -j 8 create,destroy ./src/tests/lxc-test-concurrent -i 100 -j 8 I wonder if lxc-test-concurrent will fail for you? As you suspected lxc-test-concurrent runs fine on my system, I also tried running concurrent_stress with directory backend and as long as I see it also works fine. I guess the initial failure I observed had something with btrfs backend, I'll try to reproduce it and possibly spend some time on it to see what's happening. Hmm will try ASAP. Also I remembered that I started to use best bdev option on my desktop machine which uses btrfs so maybe it has something to do with it. I'll revert back to dir type on Go bindings and try that again as well. Will report back as soon as I have something! Cheers, -- S.Çağlar Onur cag...@10ur.org -- DreamFactory - Open Source REST JSON Services for HTML5 Native Apps OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access Free app hosting. Or install the open source package on any LAMP server. Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native! http://pubads.g.doubleclick.net/gampad/clk?id=63469471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] introduce lxcapi_add_device_node and lxcapi_remove_device_node to API (v3)
Adding block/char devices to running container is a common operation so provide a common implementation for users to consume. changes since v2; * lets the user set an alternate path inside the container as Stéphane suggested changes since v1; * removed duplicated code Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 100 + src/lxc/lxccontainer.h | 19 ++ 2 files changed, 119 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 05ca643..2a70bc7 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -49,6 +49,7 @@ #include lxc/namespace.h #include sched.h #include arpa/inet.h +#include libgen.h #if HAVE_IFADDRS_H #include ifaddrs.h @@ -62,6 +63,8 @@ #endif #endif +#define MAX_BUFFER 4096 + lxc_log_define(lxc_container, lxc); static bool file_exists(char *f) @@ -2920,6 +2923,101 @@ static bool lxcapi_may_control(struct lxc_container *c) return lxc_try_cmd(c-name, c-config_path) == 0; } +static bool add_remove_device_node(struct lxc_container *c, char *src_path, char *dest_path, bool add) +{ + int ret; + struct stat st; + char path[MAXPATHLEN]; + char value[MAX_BUFFER]; + char *directory_path = NULL, *p; + + /* make sure container is running */ + if (!c-is_running(c)) { + ERROR(container is not running); + goto out; + } + + /* use src_path if dest_path is NULL otherwise use dest_path */ + p = dest_path ? dest_path : src_path; + + /* prepare the path */ + ret = snprintf(path, MAXPATHLEN, /proc/%d/root/%s, c-init_pid(c), p); + if (ret 0 || ret = MAXPATHLEN) + goto out; + remove_trailing_slashes(path); + + p = add ? src_path : path; + /* make sure we can access p */ + if(access(p, F_OK) 0 || stat(p, st) 0) + goto out; + + /* continue if path is character device or block device */ + if S_ISCHR(st.st_mode) + ret = snprintf(value, MAX_BUFFER, c %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else if S_ISBLK(st.st_mode) + ret = snprintf(value, MAX_BUFFER, b %d:%d rwm, major(st.st_rdev), minor(st.st_rdev)); + else + goto out; + + /* check snprintf return code */ + if (ret 0 || ret = MAX_BUFFER) + goto out; + + directory_path = dirname(strdup(path)); + /* remove path and directory_path (if empty) */ + if(access(path, F_OK) == 0) { + if (unlink(path) 0) { + ERROR(unlink failed); + goto out; + } + if (rmdir(directory_path) 0 errno != ENOTEMPTY) { + ERROR(rmdir failed); + goto out; + } + } + + if (add) { + /* create the missing directories */ + if (mkdir_p(directory_path, 0755) 0) { + ERROR(failed to create directory); + goto out; + } + + /* create the device node */ + if (mknod(path, st.st_mode, st.st_rdev) 0) { + ERROR(mknod failed); +goto out; + } + + /* add device node to device list */ + if (!c-set_cgroup_item(c, devices.allow, value)) { + ERROR(set_cgroup_item failed while adding the device node); + goto out; + } + } else { + /* remove device node from device list */ + if (!c-set_cgroup_item(c, devices.deny, value)) { + ERROR(set_cgroup_item failed while removing the device node); + goto out; + } + } + return true; +out: + if (directory_path) + free(directory_path); + return false; +} + +static bool lxcapi_add_device_node(struct lxc_container *c, char *src_path, char *dest_path) +{ + return add_remove_device_node(c, src_path, dest_path, true); +} + +static bool lxcapi_remove_device_node(struct lxc_container *c, char *src_path, char *dest_path) +{ + return add_remove_device_node(c, src_path, dest_path, false); +} + static int lxcapi_attach_run_waitl(struct lxc_container *c, lxc_attach_options_t *options, const char *program, const char *arg, ...) { va_list ap; @@ -3041,6 +3139,8 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c-snapshot_restore = lxcapi_snapshot_restore; c-snapshot_destroy = lxcapi_snapshot_destroy; c-may_control = lxcapi_may_control; + c-add_device_node = lxcapi_add_device_node; + c-remove_device_node = lxcapi_remove_device_node; /* we'll allow the caller to update these later */ if (lxc_log_init(NULL, none, NULL, lxc_container,
[lxc-devel] [PATCH] replace redundant creat() with open()
creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/bdev.c | 2 +- src/lxc/conf.c | 6 +++--- src/lxc/lxc_start.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index c7e5e5e..0194ccd 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -1594,7 +1594,7 @@ static int do_loop_create(const char *path, unsigned long size, const char *fsty int fd, ret; // create the new loopback file. process_lock(); - fd = creat(path, S_IRUSR|S_IWUSR); + fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); process_unlock(); if (fd 0) return -1; diff --git a/src/lxc/conf.c b/src/lxc/conf.c index a756731..dc34568 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -909,7 +909,7 @@ static int setup_tty(const struct lxc_rootfs *rootfs, return -1; } process_lock(); - ret = creat(lxcpath, 0660); + ret = open(lxcpath, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1 errno != EEXIST) { SYSERROR(error creating %s\n, lxcpath); @@ -945,7 +945,7 @@ static int setup_tty(const struct lxc_rootfs *rootfs, /* If we populated /dev, then we need to create /dev/ttyN */ if (access(path, F_OK)) { process_lock(); - ret = creat(path, 0660); + ret = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1) { SYSERROR(error creating %s\n, path); @@ -1546,7 +1546,7 @@ static int setup_ttydir_console(const struct lxc_rootfs *rootfs, } process_lock(); - ret = creat(lxcpath, 0660); + ret = open(lxcpath, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1 errno != EEXIST) { SYSERROR(error %d creating %s\n, errno, lxcpath); diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index add2542..f8fc6d4 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -62,7 +62,7 @@ static int ensure_path(char **confpath, const char *path) if (path) { if (access(path, W_OK)) { - fd = creat(path, 0600); + fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0600); if (fd 0 errno != EEXIST) { SYSERROR(failed to create '%s', path); goto err; -- 1.8.3.2 -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] replace redundant creat() with open()
Hey Serge, On Fri, Nov 8, 2013 at 4:06 PM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): creat() is equivalent to open() with flags equal to O_CREAT|O_WRONLY|O_TRUNC Hi, I'm confused - what is redundant in the use of creat()? If there is an improvement here then I don't understand what it is. Otherwise I'd argue creat() is more concise and clearer about its intent. There is no improvement other than a syntactic change (assuming creat() is also protected by glibc like open()). I saw them while trying to come up with a list of functions protected by process_lock and replaced them with open() without checking what glibc does. If you think creat is also protected than please feel free to drop this :) Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/bdev.c | 2 +- src/lxc/conf.c | 6 +++--- src/lxc/lxc_start.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index c7e5e5e..0194ccd 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -1594,7 +1594,7 @@ static int do_loop_create(const char *path, unsigned long size, const char *fsty int fd, ret; // create the new loopback file. process_lock(); - fd = creat(path, S_IRUSR|S_IWUSR); + fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); process_unlock(); if (fd 0) return -1; diff --git a/src/lxc/conf.c b/src/lxc/conf.c index a756731..dc34568 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -909,7 +909,7 @@ static int setup_tty(const struct lxc_rootfs *rootfs, return -1; } process_lock(); - ret = creat(lxcpath, 0660); + ret = open(lxcpath, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1 errno != EEXIST) { SYSERROR(error creating %s\n, lxcpath); @@ -945,7 +945,7 @@ static int setup_tty(const struct lxc_rootfs *rootfs, /* If we populated /dev, then we need to create /dev/ttyN */ if (access(path, F_OK)) { process_lock(); - ret = creat(path, 0660); + ret = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1) { SYSERROR(error creating %s\n, path); @@ -1546,7 +1546,7 @@ static int setup_ttydir_console(const struct lxc_rootfs *rootfs, } process_lock(); - ret = creat(lxcpath, 0660); + ret = open(lxcpath, O_CREAT|O_WRONLY|O_TRUNC, 0660); process_unlock(); if (ret==-1 errno != EEXIST) { SYSERROR(error %d creating %s\n, errno, lxcpath); diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index add2542..f8fc6d4 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -62,7 +62,7 @@ static int ensure_path(char **confpath, const char *path) if (path) { if (access(path, W_OK)) { - fd = creat(path, 0600); + fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0600); if (fd 0 errno != EEXIST) { SYSERROR(failed to create '%s', path); goto err; -- 1.8.3.2 -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- November Webinars for C, C++, Fortran Developers Accelerate application performance with scalable programming models. Explore techniques for threading, error checking, porting, and tuning. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60136231iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] allow setting/getting lxc.loglevel and lxc.logfile via set_config_item/get_config_item API calls
Hi Serge, On Mon, Nov 4, 2013 at 7:23 AM, Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting S.Çağlar Onur (cag...@10ur.org): Signed-off-by: S.Çağlar Onur cag...@10ur.org A bit more description would have been appreciated :) But I think I see. Yeah, you are right. I was working on something else when I observed this problem so prepared a patch quickly without proper explanation. Sorry about that :/ We also may want to change it so that the logfile and loglevel can actually be changed mid-run. At some point. Acked-by: Serge E. Hallyn serge.hal...@ubuntu.com --- src/lxc/log.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lxc/log.c b/src/lxc/log.c index 0946e44..e5eb04f 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -295,13 +295,13 @@ extern int lxc_log_init(const char *name, const char *file, } if (priority) { - lxc_loglevel_specified = 1; - lxc_priority = lxc_log_priority_to_int(priority); - if (lxc_priority == LXC_LOG_PRIORITY_NOTSET) { ERROR(invalid log priority %s, priority); return -1; } + + lxc_loglevel_specified = 1; + lxc_priority = lxc_log_priority_to_int(priority); } lxc_log_category_lxc.priority = lxc_priority; @@ -314,9 +314,9 @@ extern int lxc_log_init(const char *name, const char *file, lxc_log_set_prefix(prefix); if (file) { - lxc_logfile_specified = 1; if (strcmp(file, none) == 0) return 0; + lxc_logfile_specified = 1; ret = __lxc_log_set_file(file, 1); } else { ret = -1; @@ -362,6 +362,7 @@ extern int lxc_log_set_level(int level) ERROR(invalid log priority %d, level); return -1; } + lxc_loglevel_specified = 1; lxc_log_category_lxc.priority = level; return 0; } @@ -390,6 +391,7 @@ extern int lxc_log_set_file(const char *fname) { if (lxc_logfile_specified) return 0; + lxc_logfile_specified = 1; return __lxc_log_set_file(fname, 0); } -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] make sure to check c-lxc_conf is not NULL before dereferencing it.
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index a9d97ad..362b429 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -441,7 +441,7 @@ static bool lxcapi_load_config(struct lxc_container *c, const char *alt_file) static void lxcapi_want_daemonize(struct lxc_container *c) { - if (!c) + if (!c || !c-lxc_conf) return; if (container_mem_lock(c)) { ERROR(Error getting mem lock); -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] valgrind drd tool shows conflicting stores happening at lxc_global_config_value@src/lxc/utils.c (v2)
Conflict occurs between following lines [...] 269 if (values[i]) 270 return values[i]; [...] and [...] 309 /* could not find value, use default */ 310 values[i] = (*ptr)[1]; [...] fix it using a specific lock dedicated to that problem as Serge suggested. Also introduce a new autoconf parameter (--enable-mutex-debugging) to convert mutexes to error reporting type and to provide a stacktrace when locking fails. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- configure.ac | 9 ++ src/lxc/cgroup.c | 2 +- src/lxc/lxclock.c | 17 +-- src/lxc/start.c | 2 +- src/lxc/utils.c | 90 --- src/lxc/utils.h | 5 +++- 6 files changed, 115 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 9fedf55..6004b35 100644 --- a/configure.ac +++ b/configure.ac @@ -178,6 +178,15 @@ AM_COND_IF([ENABLE_PYTHON], PKG_CHECK_MODULES([PYTHONDEV], [python3 = 3.2],[],[AC_MSG_ERROR([You must install python3-dev])]) AC_DEFINE_UNQUOTED([ENABLE_PYTHON], 1, [Python3 is available])]) +# Enable dumping stack traces +AC_ARG_ENABLE([mutex-debugging], + [AC_HELP_STRING([--enable-mutex-debugging], [Makes mutexes to report error and provide stack trace])], + [enable_mutex_debugging=yes], [enable_mutex_debugging=no]) +AM_CONDITIONAL([MUTEX_DEBUGGING], [test x$enable_mutex_debugging = xyes]) + +AM_COND_IF([MUTEX_DEBUGGING], + AC_DEFINE_UNQUOTED([MUTEX_DEBUGGING], 1, [Enabling mutex debugging])) + # Not in older autoconf versions # AS_VAR_COPY(DEST, SOURCE) # - diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 01ed040..1e1e72a 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -91,7 +91,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta() int saved_errno; errno = 0; - cgroup_use = lxc_global_config_value(cgroup.use); + cgroup_use = default_cgroup_use(); if (!cgroup_use errno != 0) return NULL; if (cgroup_use) { diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c index d403bcc..3857ff0 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c @@ -18,15 +18,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include pthread.h +#define _GNU_SOURCE #include lxclock.h #include malloc.h #include stdio.h #include errno.h #include unistd.h #include fcntl.h -#define _GNU_SOURCE #include stdlib.h +#include pthread.h #include lxc/utils.h #include lxc/log.h #include lxc/lxccontainer.h @@ -38,7 +38,11 @@ lxc_log_define(lxc_lock, lxc); +#ifdef MUTEX_DEBUGGING +pthread_mutex_t thread_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; +#else pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif static char *lxclock_name(const char *p, const char *n) { @@ -267,13 +271,20 @@ void process_lock(void) if ((ret = pthread_mutex_lock(thread_mutex)) != 0) { ERROR(pthread_mutex_lock returned:%d %s, ret, strerror(ret)); + dump_stacktrace(); exit(1); } } void process_unlock(void) { - pthread_mutex_unlock(thread_mutex); + int ret; + + if ((ret = pthread_mutex_unlock(thread_mutex)) != 0) { + ERROR(pthread_mutex_unlock returned:%d %s, ret, strerror(ret)); + dump_stacktrace(); + exit(1); + } } int container_mem_lock(struct lxc_container *c) diff --git a/src/lxc/start.c b/src/lxc/start.c index 1cadc09..58e1194 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -695,7 +695,7 @@ int lxc_spawn(struct lxc_handler *handler) * default value is available */ if (getuid() == 0) - cgroup_pattern = lxc_global_config_value(cgroup.pattern); + cgroup_pattern = default_cgroup_pattern(); if (!cgroup_pattern) cgroup_pattern = %n; diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 9e2e326..590482e 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -21,7 +21,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#define _GNU_SOURCE +#include config.h + #include errno.h #include unistd.h #include stdlib.h @@ -38,6 +39,8 @@ #include sys/types.h #include sys/wait.h #include assert.h +#include pthread.h +#include execinfo.h #ifndef HAVE_GETLINE #ifdef HAVE_FGETLN @@ -49,8 +52,61 @@ #include log.h #include lxclock.h +#define MAX_STACKDEPTH 25 + lxc_log_define(lxc_utils, lxc); + +#ifdef MUTEX_DEBUGGING +static pthread_mutex_t static_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; + +inline void dump_stacktrace(void) +{ + void *array[MAX_STACKDEPTH]; + size_t size; + char **strings; + size_t i; + + size = backtrace(array, MAX_STACKDEPTH); + strings = backtrace_symbols(array, size); + + // Using fprintf here as our logging module
[lxc-devel] [PATCH] ignore tags files that can be created via make ctags target
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8901fc7..82b144a 100644 --- a/.gitignore +++ b/.gitignore @@ -128,3 +128,4 @@ src/stamp-h1 patches *.orig *.rej +tags -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] allow setting/getting lxc.loglevel and lxc.logfile via set_config_item/get_config_item API calls
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/log.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lxc/log.c b/src/lxc/log.c index 0946e44..e5eb04f 100644 --- a/src/lxc/log.c +++ b/src/lxc/log.c @@ -295,13 +295,13 @@ extern int lxc_log_init(const char *name, const char *file, } if (priority) { - lxc_loglevel_specified = 1; - lxc_priority = lxc_log_priority_to_int(priority); - if (lxc_priority == LXC_LOG_PRIORITY_NOTSET) { ERROR(invalid log priority %s, priority); return -1; } + + lxc_loglevel_specified = 1; + lxc_priority = lxc_log_priority_to_int(priority); } lxc_log_category_lxc.priority = lxc_priority; @@ -314,9 +314,9 @@ extern int lxc_log_init(const char *name, const char *file, lxc_log_set_prefix(prefix); if (file) { - lxc_logfile_specified = 1; if (strcmp(file, none) == 0) return 0; + lxc_logfile_specified = 1; ret = __lxc_log_set_file(file, 1); } else { ret = -1; @@ -362,6 +362,7 @@ extern int lxc_log_set_level(int level) ERROR(invalid log priority %d, level); return -1; } + lxc_loglevel_specified = 1; lxc_log_category_lxc.priority = level; return 0; } @@ -390,6 +391,7 @@ extern int lxc_log_set_file(const char *fname) { if (lxc_logfile_specified) return 0; + lxc_logfile_specified = 1; return __lxc_log_set_file(fname, 0); } -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] valgrind drd tool shows conflicting stores happening at lxc_global_config_value@src/lxc/utils.c
Conflict occurs between following lines [...] 269 if (values[i]) 270 return values[i]; [...] and [...] 309 /* could not find value, use default */ 310 values[i] = (*ptr)[1]; [...] so call it while holding the process_lock Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/cgroup.c | 2 +- src/lxc/start.c | 2 +- src/lxc/utils.c | 41 + src/lxc/utils.h | 3 ++- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 01ed040..1e1e72a 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -91,7 +91,7 @@ struct cgroup_meta_data *lxc_cgroup_load_meta() int saved_errno; errno = 0; - cgroup_use = lxc_global_config_value(cgroup.use); + cgroup_use = default_cgroup_use(); if (!cgroup_use errno != 0) return NULL; if (cgroup_use) { diff --git a/src/lxc/start.c b/src/lxc/start.c index 1cadc09..58e1194 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -695,7 +695,7 @@ int lxc_spawn(struct lxc_handler *handler) * default value is available */ if (getuid() == 0) - cgroup_pattern = lxc_global_config_value(cgroup.pattern); + cgroup_pattern = default_cgroup_pattern(); if (!cgroup_pattern) cgroup_pattern = %n; diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 9e2e326..6129cf8 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -269,9 +269,7 @@ const char *lxc_global_config_value(const char *option_name) if (values[i]) return values[i]; - process_lock(); fin = fopen_cloexec(LXC_GLOBAL_CONF, r); - process_unlock(); if (fin) { while (fgets(buf, 1024, fin)) { if (buf[0] == '#') @@ -317,30 +315,57 @@ const char *lxc_global_config_value(const char *option_name) errno = 0; out: - process_lock(); if (fin) fclose(fin); - process_unlock(); return values[i]; } const char *default_lvm_vg(void) { - return lxc_global_config_value(lvm_vg); + process_lock(); + const char *ret = lxc_global_config_value(lvm_vg); + process_unlock(); + return ret; } const char *default_lvm_thin_pool(void) { - return lxc_global_config_value(lvm_thin_pool); + process_lock(); + const char *ret = lxc_global_config_value(lvm_thin_pool); + process_unlock(); + return ret; } const char *default_zfs_root(void) { - return lxc_global_config_value(zfsroot); + process_lock(); + const char *ret = lxc_global_config_value(zfsroot); + process_unlock(); + return ret; } + const char *default_lxc_path(void) { - return lxc_global_config_value(lxcpath); + process_lock(); + const char *ret = lxc_global_config_value(lxcpath); + process_unlock(); + return ret; +} + +const char *default_cgroup_use(void) +{ + process_lock(); + const char *ret = lxc_global_config_value(cgroup.use); + process_unlock(); + return ret; +} + +const char *default_cgroup_pattern(void) +{ + process_lock(); + const char *ret = lxc_global_config_value(cgroup.pattern); + process_unlock(); + return ret; } const char *get_rundir() diff --git a/src/lxc/utils.h b/src/lxc/utils.h index fc46760..8aa1550 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -49,7 +49,8 @@ extern const char *default_lxc_path(void); extern const char *default_zfs_root(void); extern const char *default_lvm_vg(void); extern const char *default_lvm_thin_pool(void); - +extern const char *default_cgroup_use(void); +extern const char *default_cgroup_pattern(void); /* Define getline() if missing from the C library */ #ifndef HAVE_GETLINE #ifdef HAVE_FGETLN -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] unnamed semaphores should be destroyed not closed
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxclock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lxc/lxclock.c b/src/lxc/lxclock.c index 020bd34..d403bcc 100644 --- a/src/lxc/lxclock.c +++ b/src/lxc/lxclock.c @@ -240,7 +240,7 @@ void lxc_putlock(struct lxc_lock *l) switch(l-type) { case LXC_LOCK_ANON_SEM: if (l-u.sem) { - sem_close(l-u.sem); + sem_destroy(l-u.sem); free(l-u.sem); l-u.sem = NULL; } -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] free getline allocated line variable to make valgrind happy
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 1600276..f2f7240 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -3129,6 +3129,9 @@ int list_active_containers(const char *lxcpath, char ***names, struct lxc_contai if (names) *names = unique_names; + if (line) + free(line); + process_lock(); fclose(f); process_unlock(); @@ -3145,6 +3148,9 @@ free_bad: lxc_container_put((*cret)[i]); free(*cret); } + if (line) + free(line); + process_lock(); fclose(f); process_unlock(); -- 1.8.3.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] Use actual length of socket's name for abstract sockets (v3)
The addrlen parameter should be the actual length of socket's name for abstract sockets. Otherwise socket gets padded with NULLs. cat /proc/net/unix | grep lxc [...] : 0003 0001 03 226548 @lxc/ad055575fe28ddd5//var/lib/lxc^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ [...] with this patch; cat /proc/net/unix | grep lxc [...] : 0002 0001 0001 01 109563 @lxc/ad055575fe28ddd5//var/lib/lxc [...] Changes since v1: * check the length of passed-in string Changes since v2: * remove non-abstract socket code path to simplify functions * rename lxc_af_unix_* family to lxc_abstract_unix_* Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/af_unix.c | 57 +- src/lxc/af_unix.h | 14 ++--- src/lxc/commands.c | 12 +-- src/lxc/lxc_monitord.c | 2 +- src/lxc/monitor.c | 11 +- 5 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c index 333f05e..ab73963 100644 --- a/src/lxc/af_unix.c +++ b/src/lxc/af_unix.c @@ -20,6 +20,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include stddef.h #include string.h #include unistd.h #include fcntl.h @@ -34,7 +35,7 @@ lxc_log_define(lxc_af_unix, lxc); -int lxc_af_unix_open(const char *path, int type, int flags) +int lxc_abstract_unix_open(const char *path, int type, int flags) { int fd; size_t len; @@ -49,27 +50,26 @@ int lxc_af_unix_open(const char *path, int type, int flags) if (fd 0) return -1; + /* Clear address structure */ memset(addr, 0, sizeof(addr)); if (!path) return fd; addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - len = sizeof(addr.sun_path); - if (path[0]) { - len = strlen(path); - if (len = sizeof(addr.sun_path)) { - process_lock(); - close(fd); - process_unlock(); - errno = ENAMETOOLONG; - return -1; - } + + len = strlen(path[1]) + 1; + if (len = sizeof(addr.sun_path) - 1) { + process_lock(); + close(fd); + process_unlock(); + errno = ENAMETOOLONG; + return -1; } - memcpy(addr.sun_path, path, len); + /* addr.sun_path[0] has already been set to 0 by memset() */ + strncpy(addr.sun_path[1], path[1], strlen(path[1])); - if (bind(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (bind(fd, (struct sockaddr *)addr, offsetof(struct sockaddr_un, sun_path) + len)) { int tmp = errno; process_lock(); close(fd); @@ -90,7 +90,7 @@ int lxc_af_unix_open(const char *path, int type, int flags) return fd; } -int lxc_af_unix_close(int fd) +int lxc_abstract_unix_close(int fd) { struct sockaddr_un addr; socklen_t addrlen = sizeof(addr); @@ -106,9 +106,10 @@ int lxc_af_unix_close(int fd) return 0; } -int lxc_af_unix_connect(const char *path) +int lxc_abstract_unix_connect(const char *path) { int fd; + size_t len; struct sockaddr_un addr; process_lock(); @@ -120,11 +121,19 @@ int lxc_af_unix_connect(const char *path) memset(addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, - path[0]?strlen(path):sizeof(addr.sun_path)); - if (connect(fd, (struct sockaddr *)addr, sizeof(addr))) { + len = strlen(path[1]) + 1; + if (len = sizeof(addr.sun_path) - 1) { + process_lock(); + close(fd); + process_unlock(); + errno = ENAMETOOLONG; + return -1; + } + /* addr.sun_path[0] has already been set to 0 by memset() */ + strncpy(addr.sun_path[1], path[1], strlen(path[1])); + + if (connect(fd, (struct sockaddr *)addr, offsetof(struct sockaddr_un, sun_path) + len)) { int tmp = errno; process_lock(); close(fd); @@ -136,7 +145,7 @@ int lxc_af_unix_connect(const char *path) return fd; } -int lxc_af_unix_send_fd(int fd, int sendfd, void *data, size_t size) +int lxc_abstract_unix_send_fd(int fd, int sendfd, void *data, size_t size) { struct msghdr msg = { 0 }; struct iovec iov; @@ -166,7 +175,7 @@ int lxc_af_unix_send_fd(int fd, int sendfd, void *data, size_t size) return sendmsg(fd, msg, 0); } -int
[lxc-devel] [PATCH] Use actual length of socket's name for abstract sockets (v2)
The addrlen parameter should be the actual length of socket's name for abstract sockets. Otherwise socket gets padded with NULLs. cat /proc/net/unix | grep lxc [...] : 0003 0001 03 226548 @lxc/ad055575fe28ddd5//var/lib/lxc^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ [...] with this patch; cat /proc/net/unix | grep lxc [...] : 0002 0001 0001 01 109563 @lxc/ad055575fe28ddd5//var/lib/lxc [...] Changes since v1: * checking the length of passed-in string Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/af_unix.c | 46 ++ src/lxc/monitor.c | 11 ++- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c index 333f05e..4446203 100644 --- a/src/lxc/af_unix.c +++ b/src/lxc/af_unix.c @@ -20,6 +20,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include stddef.h #include string.h #include unistd.h #include fcntl.h @@ -55,21 +56,22 @@ int lxc_af_unix_open(const char *path, int type, int flags) return fd; addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - len = sizeof(addr.sun_path); + len = path[0] ? strlen(path) : offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + if (len = sizeof(addr.sun_path)) { + process_lock(); + close(fd); + process_unlock(); + errno = ENAMETOOLONG; + return -1; + } + if (path[0]) { - len = strlen(path); - if (len = sizeof(addr.sun_path)) { - process_lock(); - close(fd); - process_unlock(); - errno = ENAMETOOLONG; - return -1; - } + memcpy(addr.sun_path, path, len); + } else { + memcpy((char *) addr.sun_path + 1, path[1], len); } - memcpy(addr.sun_path, path, len); - if (bind(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (bind(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); @@ -109,6 +111,7 @@ int lxc_af_unix_close(int fd) int lxc_af_unix_connect(const char *path) { int fd; + size_t len; struct sockaddr_un addr; process_lock(); @@ -120,11 +123,22 @@ int lxc_af_unix_connect(const char *path) memset(addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, - path[0]?strlen(path):sizeof(addr.sun_path)); + len = path[0] ? strlen(path) : offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + if (len = sizeof(addr.sun_path)) { + process_lock(); + close(fd); + process_unlock(); + errno = ENAMETOOLONG; + return -1; + } + + if (path[0]) { + memcpy(addr.sun_path, path, len); + } else { + memcpy((char *) addr.sun_path + 1, path[1], len); + } - if (connect(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (connect(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index ab567c8..71f2074 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -27,6 +27,7 @@ #include unistd.h #include string.h #include stdlib.h +#include stddef.h #include fcntl.h #include inttypes.h #include stdint.h @@ -194,6 +195,7 @@ int lxc_monitor_open(const char *lxcpath) struct sockaddr_un addr; int fd,ret; int retry,backoff_ms[] = {10, 50, 100}; + size_t len; if (lxc_monitor_sock_name(lxcpath, addr) 0) return -1; @@ -206,8 +208,15 @@ int lxc_monitor_open(const char *lxcpath) return -1; } + len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path[1]) + 1; + if (len = sizeof(addr.sun_path)) { + ret = -1; + errno = ENAMETOOLONG; + goto err1; + } + for (retry = 0; retry sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) { - ret = connect(fd, (struct sockaddr *)addr, sizeof(addr)); + ret = connect(fd, (struct sockaddr *)addr, len); if (ret == 0 || errno != ECONNREFUSED) break; ERROR(connect : backing off %d, backoff_ms[retry]); -- 1.8.3.2
[lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers (v2)
list_active_containers parses /proc/net/unix which can contain multiple entries for the same container; : 0002 0001 0001 01 273672 @/var/lib/lxc/6/command : 0002 0001 0001 01 274395 @/var/lib/lxc/5/command : 0002 0001 0001 01 273890 @/var/lib/lxc/4/command : 0002 0001 0001 01 273141 @/var/lib/lxc/3/command : 0002 0001 0001 01 273915 @/var/lib/lxc/2/command : 0002 0001 0001 01 273683 @/var/lib/lxc/1/command : 0002 0001 0001 01 273074 @/var/lib/lxc/0/command : 0002 0001 0001 01 273931 @/var/lib/lxc/9/command : 0002 0001 0001 01 273110 @/var/lib/lxc/8/command : 0002 0001 0001 01 273390 @/var/lib/lxc/7/command : 0003 0001 03 275903 @/var/lib/lxc/8/command : 0003 0001 03 276043 @/var/lib/lxc/1/command : 0003 0001 03 273301 @/var/lib/lxc/0/command : 0003 0001 03 275650 @/var/lib/lxc/4/command On this system list_active_containers returns 14 containers while only 10 containers are running. Following patch; * Introduces array_contains function to do a binary search on given array, * Starts to sort arrays inside the add_to_clist and add_to_names functions, * Consumes array_contains in list_active_containers to eliminate duplicates, * Replaces the linear search code in lxcapi_get_interfaces with the new function. Changes since v1: * Do not load containers if a if a container list is not passed in * Fix possible memory leaks in lxcapi_get_ips and lxcapi_get_interfaces if realloc fails Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 207 ++--- 1 file changed, 126 insertions(+), 81 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6e6c38c..5b9a14a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1242,12 +1242,81 @@ out: return false; } +// used by qsort and bsearch functions for comparing names +static inline int string_cmp(char **first, char **second) +{ + return strcmp(*first, *second); +} + +// used by qsort and bsearch functions for comparing container names +static inline int container_cmp(struct lxc_container **first, struct lxc_container **second) +{ + return strcmp((*first)-name, (*second)-name); +} + +static bool add_to_array(char ***names, char *cname, int pos) +{ + char **newnames = realloc(*names, (pos+1) * sizeof(char *)); + if (!newnames) { + ERROR(Out of memory); + return false; + } + + *names = newnames; + newnames[pos] = strdup(cname); + if (!newnames[pos]) + return false; + + // sort the arrray as we will use binary search on it + qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + + return true; +} + +static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos) +{ + struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *)); + if (!newlist) { + ERROR(Out of memory); + return false; + } + + *list = newlist; + newlist[pos] = c; + + // sort the arrray as we will use binary search on it + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp); + + return true; +} + +static char** get_from_array(char ***names, char *cname, int size) +{ + return (char **)bsearch(cname, *names, size, sizeof(char *), (int (*)(const void *, const void *))string_cmp); +} + + +static bool array_contains(char ***names, char *cname, int size) { + if(get_from_array(names, cname, size) != NULL) + return true; + return false; +} + +static bool remove_from_array(char ***names, char *cname, int size) +{ + char **result = get_from_array(names, cname, size); + if (result != NULL) { + free(result); + return true; + } + return false; +} + static char** lxcapi_get_interfaces(struct lxc_container *c) { - int count = 0, i; - bool found = false; + int i, count = 0; struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; - char **interfaces = NULL, **temp; + char **interfaces = NULL; int old_netns = -1, new_netns = -1; if (!enter_to_ns(c, old_netns, new_netns)) @@ -1261,51 +1330,41 @@ static char** lxcapi_get_interfaces(struct lxc_container *c) /* Iterate through the interfaces
[lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers
list_active_containers parses /proc/net/unix which can contain multiple entries for the same container; : 0002 0001 0001 01 273672 @/var/lib/lxc/6/command : 0002 0001 0001 01 274395 @/var/lib/lxc/5/command : 0002 0001 0001 01 273890 @/var/lib/lxc/4/command : 0002 0001 0001 01 273141 @/var/lib/lxc/3/command : 0002 0001 0001 01 273915 @/var/lib/lxc/2/command : 0002 0001 0001 01 273683 @/var/lib/lxc/1/command : 0002 0001 0001 01 273074 @/var/lib/lxc/0/command : 0002 0001 0001 01 273931 @/var/lib/lxc/9/command : 0002 0001 0001 01 273110 @/var/lib/lxc/8/command : 0002 0001 0001 01 273390 @/var/lib/lxc/7/command : 0003 0001 03 275903 @/var/lib/lxc/8/command : 0003 0001 03 276043 @/var/lib/lxc/1/command : 0003 0001 03 273301 @/var/lib/lxc/0/command : 0003 0001 03 275650 @/var/lib/lxc/4/command On this system list_active_containers returns 14 containers while only 10 containers are running. Following patch; * Introduces array_contains function to do a binary search on given array, * Starts to sort arrays inside the add_to_clist and add_to_names functions, * Consumes array_contains in list_active_containers to eliminate duplicates, * Replaces the linear search code in lxcapi_get_interfaces with the new function. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 161 ++--- 1 file changed, 86 insertions(+), 75 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index c8ecef3..46389ab 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1240,12 +1240,67 @@ out: return false; } +// used by qsort and bsearch functions +static inline int string_cmp(char **first, char **second) +{ + return strcmp(*first, *second); +} + +static bool add_to_names(char ***names, char *cname, int pos) +{ + char **newnames = realloc(*names, (pos+1) * sizeof(char *)); + if (!newnames) { + ERROR(Out of memory); + return false; + } + + *names = newnames; + newnames[pos] = strdup(cname); + if (!newnames[pos]) + return false; + + // sort the arrray as we will use binary search on it + qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + + return true; +} + +// used by qsort and bsearch functions +static inline int container_cmp(struct lxc_container **first, struct lxc_container **second) +{ + return strcmp((*first)-name, (*second)-name); +} + +static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos) +{ + struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *)); + if (!newlist) { + ERROR(Out of memory); + return false; + } + + *list = newlist; + newlist[pos] = c; + + // sort the arrray as we will use binary search on it + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp); + + return true; +} + +static bool array_contains(char **names, char *cname, int size) { + char *result = NULL; + result = (char *)bsearch((char *)cname, (char *)names, size, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + if (result != NULL) + return true; + return false; +} + static char** lxcapi_get_interfaces(struct lxc_container *c) { - int count = 0, i; - bool found = false; + int count = 0; struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; - char **interfaces = NULL, **temp; + char **interfaces = NULL; int old_netns = -1, new_netns = -1; if (!enter_to_ns(c, old_netns, new_netns)) @@ -1259,30 +1314,10 @@ static char** lxcapi_get_interfaces(struct lxc_container *c) /* 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
[lxc-devel] [PATCH] Use actual length of socket's name for abstract sockets
The addrlen parameter should be the actual length of socket's name for abstract sockets. Otherwise socket gets padded with NULLs. cat /proc/net/unix | grep lxc [...] : 0003 0001 03 226548 @lxc/ad055575fe28ddd5//var/lib/lxc^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ [...] with this patch; cat /proc/net/unix | grep lxc [...] : 0002 0001 0001 01 109563 @lxc/ad055575fe28ddd5//var/lib/lxc [...] Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/af_unix.c | 23 +++ src/lxc/monitor.c | 5 - 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c index 333f05e..2f8d593 100644 --- a/src/lxc/af_unix.c +++ b/src/lxc/af_unix.c @@ -20,6 +20,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include stddef.h #include string.h #include unistd.h #include fcntl.h @@ -55,8 +56,6 @@ int lxc_af_unix_open(const char *path, int type, int flags) return fd; addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - len = sizeof(addr.sun_path); if (path[0]) { len = strlen(path); if (len = sizeof(addr.sun_path)) { @@ -66,10 +65,13 @@ int lxc_af_unix_open(const char *path, int type, int flags) errno = ENAMETOOLONG; return -1; } + memcpy(addr.sun_path, path, len); + } else { + len = offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + memcpy((char *) addr.sun_path + 1, path[1], len); } - memcpy(addr.sun_path, path, len); - if (bind(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (bind(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); @@ -109,6 +111,7 @@ int lxc_af_unix_close(int fd) int lxc_af_unix_connect(const char *path) { int fd; + size_t len; struct sockaddr_un addr; process_lock(); @@ -120,11 +123,15 @@ int lxc_af_unix_connect(const char *path) memset(addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, - path[0]?strlen(path):sizeof(addr.sun_path)); + if (path[0]) { + len = strlen(path); + memcpy(addr.sun_path, path, len); + } else { + len = offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + memcpy((char *) addr.sun_path + 1, path[1], len); + } - if (connect(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (connect(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index e736937..b965225 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -27,6 +27,7 @@ #include unistd.h #include string.h #include stdlib.h +#include stddef.h #include fcntl.h #include inttypes.h #include stdint.h @@ -194,6 +195,7 @@ int lxc_monitor_open(const char *lxcpath) struct sockaddr_un addr; int fd,ret; int retry,backoff_ms[] = {10, 50, 100}; + size_t len; if (lxc_monitor_sock_name(lxcpath, addr) 0) return -1; @@ -206,8 +208,9 @@ int lxc_monitor_open(const char *lxcpath) return -1; } + len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path[1]) + 1; for (retry = 0; retry sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) { - ret = connect(fd, (struct sockaddr *)addr, sizeof(addr)); + ret = connect(fd, (struct sockaddr *)addr, len); if (ret == 0 || errno != ECONNREFUSED) break; ERROR(connect : backing off %d, backoff_ms[retry]); -- 1.8.3.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135991iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Use actual length of socket's name for abstract sockets
Hi, On Mon, Oct 21, 2013 at 8:30 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): The addrlen parameter should be the actual length of socket's name for abstract sockets. Otherwise socket gets padded with NULLs. cat /proc/net/unix | grep lxc [...] : 0003 0001 03 226548 @lxc/ad055575fe28ddd5//var/lib/lxc^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ [...] with this patch; cat /proc/net/unix | grep lxc [...] : 0002 0001 0001 01 109563 @lxc/ad055575fe28ddd5//var/lib/lxc [...] Yeah I've noticed that too :) However, you can't just take the length of the passed-in string, you need to make sure it's no larger than sizeof(addr.sun_path)-1. Is that being guaranteed somewhere else that I'm glossing over? Hmm I think current code path also lacks that check. As long as I see we only control the length in lxc_af_unix_open for non-abstract case. I'll add the checks and iterate one more time sometime this week. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/af_unix.c | 23 +++ src/lxc/monitor.c | 5 - 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lxc/af_unix.c b/src/lxc/af_unix.c index 333f05e..2f8d593 100644 --- a/src/lxc/af_unix.c +++ b/src/lxc/af_unix.c @@ -20,6 +20,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include stddef.h #include string.h #include unistd.h #include fcntl.h @@ -55,8 +56,6 @@ int lxc_af_unix_open(const char *path, int type, int flags) return fd; addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - len = sizeof(addr.sun_path); if (path[0]) { len = strlen(path); if (len = sizeof(addr.sun_path)) { @@ -66,10 +65,13 @@ int lxc_af_unix_open(const char *path, int type, int flags) errno = ENAMETOOLONG; return -1; } + memcpy(addr.sun_path, path, len); + } else { + len = offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + memcpy((char *) addr.sun_path + 1, path[1], len); } - memcpy(addr.sun_path, path, len); - if (bind(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (bind(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); @@ -109,6 +111,7 @@ int lxc_af_unix_close(int fd) int lxc_af_unix_connect(const char *path) { int fd; + size_t len; struct sockaddr_un addr; process_lock(); @@ -120,11 +123,15 @@ int lxc_af_unix_connect(const char *path) memset(addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - /* copy entire buffer in case of abstract socket */ - memcpy(addr.sun_path, path, -path[0]?strlen(path):sizeof(addr.sun_path)); + if (path[0]) { + len = strlen(path); + memcpy(addr.sun_path, path, len); + } else { + len = offsetof(struct sockaddr_un, sun_path) + strlen(path[1]) + 1; + memcpy((char *) addr.sun_path + 1, path[1], len); + } - if (connect(fd, (struct sockaddr *)addr, sizeof(addr))) { + if (connect(fd, (struct sockaddr *)addr, len)) { int tmp = errno; process_lock(); close(fd); diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index e736937..b965225 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -27,6 +27,7 @@ #include unistd.h #include string.h #include stdlib.h +#include stddef.h #include fcntl.h #include inttypes.h #include stdint.h @@ -194,6 +195,7 @@ int lxc_monitor_open(const char *lxcpath) struct sockaddr_un addr; int fd,ret; int retry,backoff_ms[] = {10, 50, 100}; + size_t len; if (lxc_monitor_sock_name(lxcpath, addr) 0) return -1; @@ -206,8 +208,9 @@ int lxc_monitor_open(const char *lxcpath) return -1; } + len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path[1]) + 1; for (retry = 0; retry sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) { - ret = connect(fd, (struct sockaddr *)addr, sizeof(addr)); + ret = connect(fd, (struct sockaddr *)addr, len); if (ret == 0 || errno != ECONNREFUSED) break; ERROR(connect : backing off %d, backoff_ms[retry]); -- 1.8.3.2
Re: [lxc-devel] [PATCH] umount $rootfs/lib on errors as well otherwise system ends up with stalled mounts
Hi Serge, Then there must be something else going on cause without this patch I find myself in the situation that I described earlier in this email [1] [1] http://sourceforge.net/mailarchive/message.php?msg_id=31539485 On Mon, Oct 21, 2013 at 8:11 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): Signed-off-by: S.Çağlar Onur cag...@10ur.org Actually this isn't necessary, nor is the umount in the success path. This code is executed in a fresh mount namespace. --- templates/lxc-busybox.in | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/lxc-busybox.in b/templates/lxc-busybox.in index cbdaaf3..44f0a45 100644 --- a/templates/lxc-busybox.in +++ b/templates/lxc-busybox.in @@ -209,6 +209,7 @@ EOFF if [ \$? -ne 0 ]; then echo Failed to change root password +umount $rootfs/lib exit 1 fi -- 1.8.3.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135991iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Eliminate duplicate entries from list_active_containers
Hi, On Mon, Oct 21, 2013 at 8:22 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): list_active_containers parses /proc/net/unix which can contain multiple entries for the same container; : 0002 0001 0001 01 273672 @/var/lib/lxc/6/command : 0002 0001 0001 01 274395 @/var/lib/lxc/5/command : 0002 0001 0001 01 273890 @/var/lib/lxc/4/command : 0002 0001 0001 01 273141 @/var/lib/lxc/3/command : 0002 0001 0001 01 273915 @/var/lib/lxc/2/command : 0002 0001 0001 01 273683 @/var/lib/lxc/1/command : 0002 0001 0001 01 273074 @/var/lib/lxc/0/command : 0002 0001 0001 01 273931 @/var/lib/lxc/9/command : 0002 0001 0001 01 273110 @/var/lib/lxc/8/command : 0002 0001 0001 01 273390 @/var/lib/lxc/7/command : 0003 0001 03 275903 @/var/lib/lxc/8/command : 0003 0001 03 276043 @/var/lib/lxc/1/command : 0003 0001 03 273301 @/var/lib/lxc/0/command : 0003 0001 03 275650 @/var/lib/lxc/4/command On this system list_active_containers returns 14 containers while only 10 containers are running. Following patch; * Introduces array_contains function to do a binary search on given array, * Starts to sort arrays inside the add_to_clist and add_to_names functions, * Consumes array_contains in list_active_containers to eliminate duplicates, * Replaces the linear search code in lxcapi_get_interfaces with the new function. Thanks - that patch on the whole is good, except that you move the adding to *names in list_active_containers() to after the attempt to load the container. Not loading the container if a container list is not passed in is deliberately done to avoid a potentially large amount of work. (The very low potential for differing results when passing in *cret and not is deemed worthwhile) OK, I was just trying to make sure both cases return same result :) I'll iterate one more time with that change. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 161 ++--- 1 file changed, 86 insertions(+), 75 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index c8ecef3..46389ab 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1240,12 +1240,67 @@ out: return false; } +// used by qsort and bsearch functions +static inline int string_cmp(char **first, char **second) +{ + return strcmp(*first, *second); +} + +static bool add_to_names(char ***names, char *cname, int pos) +{ + char **newnames = realloc(*names, (pos+1) * sizeof(char *)); + if (!newnames) { + ERROR(Out of memory); + return false; + } + + *names = newnames; + newnames[pos] = strdup(cname); + if (!newnames[pos]) + return false; + + // sort the arrray as we will use binary search on it + qsort(newnames, pos + 1, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + + return true; +} + +// used by qsort and bsearch functions +static inline int container_cmp(struct lxc_container **first, struct lxc_container **second) +{ + return strcmp((*first)-name, (*second)-name); +} + +static bool add_to_clist(struct lxc_container ***list, struct lxc_container *c, int pos) +{ + struct lxc_container **newlist = realloc(*list, (pos+1) * sizeof(struct lxc_container *)); + if (!newlist) { + ERROR(Out of memory); + return false; + } + + *list = newlist; + newlist[pos] = c; + + // sort the arrray as we will use binary search on it + qsort(newlist, pos + 1, sizeof(struct lxc_container *), (int (*)(const void *,const void *))container_cmp); + + return true; +} + +static bool array_contains(char **names, char *cname, int size) { + char *result = NULL; + result = (char *)bsearch((char *)cname, (char *)names, size, sizeof(char *), (int (*)(const void *,const void *))string_cmp); + if (result != NULL) + return true; + return false; +} + static char** lxcapi_get_interfaces(struct lxc_container *c) { - int count = 0, i; - bool found = false; + int count = 0; struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL; - char **interfaces = NULL, **temp; + char **interfaces = NULL; int old_netns = -1, new_netns = -1; if
Re: [lxc-devel] Strange problem (stray mounts) with lxc-create...
Hey, I upgraded my ubuntu box to saucy (using do-release-upgrade tool) minutes ago and I realized that this very same problem starts to happen on my system as well (using lxc@master). [caglar@oOo:~] lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 13.10 Release: 13.10 Codename: saucy [caglar@oOo:~] uname -a Linux oOo 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux [caglar@oOo:~] mount old [caglar@oOo:~] sudo lxc-create -n t -t busybox setting root password to root Failed to change root password [caglar@oOo:~] mount new [caglar@oOo:~] diff -u old new --- old 2013-10-19 13:32:41.701250989 -0400 +++ new 2013-10-19 13:32:47.629178285 -0400 @@ -23,3 +23,4 @@ cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb) systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd) gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,user=caglar) +/lib on /usr/lib/x86_64-linux-gnu/lxc/rootfs/lib type none (rw,bind) [caglar@oOo:~] mount /dev/sda1 on / type ext4 (rw,errors=remount-ro) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) none on /sys/fs/cgroup type tmpfs (rw) none on /sys/fs/fuse/connections type fusectl (rw) none on /sys/kernel/debug type debugfs (rw) none on /sys/kernel/security type securityfs (rw) udev on /dev type devtmpfs (rw,mode=0755) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620) tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755) none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880) none on /run/shm type tmpfs (rw,nosuid,nodev) none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755) none on /sys/fs/pstore type pstore (rw) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,relatime,cpuset) cgroup on /sys/fs/cgroup/cpu type cgroup (rw,relatime,cpu) cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,relatime,cpuacct) cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory) cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,relatime,blkio) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,relatime,perf_event) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb) systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd) gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,user=caglar) /lib on /usr/lib/x86_64-linux-gnu/lxc/rootfs/lib type none (rw,bind) [caglar@oOo:~] cat /proc/self/mountinfo 15 20 0:14 / /sys rw,nosuid,nodev,noexec,relatime - sysfs sysfs rw 16 20 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw 17 20 0:5 / /dev rw,relatime - devtmpfs udev rw,size=1015004k,nr_inodes=253751,mode=755 18 17 0:11 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,gid=5,mode=620,ptmxmode=000 19 20 0:15 / /run rw,nosuid,noexec,relatime - tmpfs tmpfs rw,size=205016k,mode=755 20 1 8:1 / / rw,relatime - ext4 /dev/disk/by-uuid/0f36b909-f4b8-434f-a8d2-cbdce7f5ddc9 rw,errors=remount-ro,data=ordered 22 15 0:16 / /sys/fs/cgroup rw,relatime - tmpfs none rw,size=4k,mode=755 23 15 0:17 / /sys/fs/fuse/connections rw,relatime - fusectl none rw 24 15 0:6 / /sys/kernel/debug rw,relatime - debugfs none rw 25 15 0:10 / /sys/kernel/security rw,relatime - securityfs none rw 26 19 0:18 / /run/lock rw,nosuid,nodev,noexec,relatime - tmpfs none rw,size=5120k 27 19 0:19 / /run/shm rw,nosuid,nodev,relatime - tmpfs none rw 28 19 0:20 / /run/user rw,nosuid,nodev,noexec,relatime - tmpfs none rw,size=102400k,mode=755 29 22 0:21 / /sys/fs/cgroup/cpuset rw,relatime - cgroup cgroup rw,cpuset,clone_children 30 15 0:22 / /sys/fs/pstore rw,relatime - pstore none rw 31 22 0:23 / /sys/fs/cgroup/cpu rw,relatime - cgroup cgroup rw,cpu 32 22 0:24 / /sys/fs/cgroup/cpuacct rw,relatime - cgroup cgroup rw,cpuacct 33 22 0:25 / /sys/fs/cgroup/memory rw,relatime - cgroup cgroup rw,memory 34 22 0:26 / /sys/fs/cgroup/devices rw,relatime - cgroup cgroup rw,devices 35 22 0:27 / /sys/fs/cgroup/freezer rw,relatime - cgroup cgroup rw,freezer 36 22 0:28 / /sys/fs/cgroup/blkio rw,relatime - cgroup cgroup rw,blkio 37 22 0:29 / /sys/fs/cgroup/perf_event rw,relatime - cgroup cgroup rw,perf_event 38 22 0:30 / /sys/fs/cgroup/hugetlb rw,relatime - cgroup cgroup rw,hugetlb 39 22 0:31 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd 40 28 0:32 / /run/user/1000/gvfs rw,nosuid,nodev,relatime - fuse.gvfsd-fuse gvfsd-fuse rw,user_id=1000,group_id=1000 Let me know if you need anything else. Cheers, On Mon, Oct 14, 2013 at 5:34 PM, Michael H. Warfield m...@wittsend.comwrote: On Wed, 2013-10-09 at 09:50 -0500, Serge Hallyn wrote: lxc-create -n Ubuntu-test -t ubuntu Bingo... /dev/mapper/fedora-root on /usr/lib64/lxc/rootfs type ext4
Re: [lxc-devel] Strange problem (stray mounts) with lxc-create...
Hi, On Sat, Oct 19, 2013 at 1:43 PM, S.Çağlar Onur cag...@10ur.org wrote: Hey, I upgraded my ubuntu box to saucy (using do-release-upgrade tool) minutes ago and I realized that this very same problem starts to happen on my system as well (using lxc@master). Never mind this as it turns out to be a problem in the template, patch will follow. -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] umount $rootfs/lib on errors as well otherwise system ends up with stalled mounts
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- templates/lxc-busybox.in | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/lxc-busybox.in b/templates/lxc-busybox.in index cbdaaf3..44f0a45 100644 --- a/templates/lxc-busybox.in +++ b/templates/lxc-busybox.in @@ -209,6 +209,7 @@ EOFF if [ \$? -ne 0 ]; then echo Failed to change root password +umount $rootfs/lib exit 1 fi -- 1.8.3.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] Fix following compile error on ubuntu 12.10
[...] make[3]: Entering directory `/home/caglar/Projects/lxc/src/tests' depbase=`echo attach.o | sed 's|[^/]*$|.deps/|;s|\.o$||'`;\ gcc -DHAVE_CONFIG_H -I. -I../../src-I../../src -DLXCROOTFSMOUNT=\/usr/lib/x86_64-linux-gnu/lxc/rootfs\ -DLXCPATH=\/var/lib/lxc\ -DLXC_GLOBAL_CONF=\/etc/lxc/lxc.conf\ -DLXCINITDIR=\/usr/libexec\ -DLXC_DEFAULT_CONFIG=\/etc/lxc/default.conf\ -g -O2 -Wall -Werror -MT attach.o -MD -MP -MF $depbase.Tpo -c -o attach.o attach.c \ mv -f $depbase.Tpo $depbase.Po attach.c: In function ‘main’: attach.c:380:2: error: implicit declaration of function ‘test_lsm_detect’ [-Werror=implicit-function-declaration] cc1: all warnings being treated as errors make[3]: *** [attach.o] Error 1 [...] Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/tests/attach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/attach.c b/src/tests/attach.c index 54650bd..57a4bdd 100644 --- a/src/tests/attach.c +++ b/src/tests/attach.c @@ -31,7 +31,6 @@ fprintf(stderr, %s:%d fmt \n, __FILE__, __LINE__, ##__VA_ARGS__); \ } while (0) -#if HAVE_APPARMOR || HAVE_SELINUX static const char *lsm_config_key = NULL; static const char *lsm_label = NULL; @@ -53,6 +52,7 @@ static void test_lsm_detect(void) } } +#if HAVE_APPARMOR || HAVE_SELINUX static void test_attach_lsm_set_config(struct lxc_container *ct) { ct-load_config(ct, NULL); -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] call lxc_container_put when needed in lxc_destroy.c
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxc_destroy.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lxc/lxc_destroy.c b/src/lxc/lxc_destroy.c index 9983241..1d1e687 100644 --- a/src/lxc/lxc_destroy.c +++ b/src/lxc/lxc_destroy.c @@ -108,5 +108,12 @@ int main(int argc, char *argv[]) c-stop(c); } - exit(c-destroy(c) ? 0 : 1); + if (!c-destroy(c)) { + fprintf(stderr, Destroying %s failed\n, my_args.name); + lxc_container_put(c); + exit(1); + } + + lxc_container_put(c); + return 0; } -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] use snapshot_destroy in tests/snapshot.c and clean up containers after the test run
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/tests/snapshot.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/tests/snapshot.c b/src/tests/snapshot.c index 8f16548..1f6d115 100644 --- a/src/tests/snapshot.c +++ b/src/tests/snapshot.c @@ -118,13 +118,25 @@ int main(int argc, char *argv[]) goto err; } - printf(All tests passed\n); + if (!c-snapshot_destroy(c, snap0)) { + fprintf(stderr, %s: %d: failed to destroy snapshot\n, __FILE__, __LINE__); + goto err; + } + + if (!c-destroy(c)) { + fprintf(stderr, %s: %d: failed to destroy container\n, __FILE__, __LINE__); + goto err; + } + lxc_container_put(c); - exit(0); + try_to_remove(); + printf(All tests passed\n); + exit(0); err: lxc_container_put(c); - fprintf(stderr, Exiting on error\n); try_to_remove(); + + fprintf(stderr, Exiting on error\n); exit(1); } -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] introduce snapshot_destroy
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 32 src/lxc/lxccontainer.h | 7 +++ 2 files changed, 39 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6f97879..73a71ce 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2609,6 +2609,37 @@ static bool lxcapi_snapshot_restore(struct lxc_container *c, char *snapname, cha return b; } +static bool lxcapi_snapshot_destroy(struct lxc_container *c, char *snapname) +{ + int ret; + char clonelxcpath[MAXPATHLEN]; + struct lxc_container *snap = NULL; + + if (!c || !c-name || !c-config_path) + return false; + + ret = snprintf(clonelxcpath, MAXPATHLEN, %ssnaps/%s, c-config_path, c-name); + if (ret 0 || ret = MAXPATHLEN) + goto err; + + snap = lxc_container_new(snapname, clonelxcpath); + if (!snap || !lxcapi_is_defined(snap)) { + ERROR(Could not find snapshot %s, snapname); + goto err; + } + + if (!lxcapi_destroy(snap)) { + ERROR(Could not destroy snapshot %s, snapname); + goto err; + } + + return true; +err: + if (snap) + lxc_container_put(snap); + return false; +} + static bool lxcapi_may_control(struct lxc_container *c) { return lxc_try_cmd(c-name, c-config_path) == 0; @@ -2733,6 +2764,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c-snapshot = lxcapi_snapshot; c-snapshot_list = lxcapi_snapshot_list; c-snapshot_restore = lxcapi_snapshot_restore; + c-snapshot_destroy = lxcapi_snapshot_destroy; c-may_control = lxcapi_may_control; /* we'll allow the caller to update these later */ diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 5901066..adcac6a 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -225,6 +225,13 @@ struct lxc_container { bool (*snapshot_restore)(struct lxc_container *c, char *snapname, char *newname); /* +* snapshot_destroy() will destroy the given snapshot of c +* +* Returns true on success, false on failure. +*/ + bool (*snapshot_destroy)(struct lxc_container *c, char *snapname); + + /* * Return false if there is a control socket for the container monitor, * and the caller may not access it. Return true otherwise. */ -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] use snapshot_destroy in tests/snapshot.c and clean containers after the test
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/tests/snapshot.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/tests/snapshot.c b/src/tests/snapshot.c index 8f16548..ef3f9c2 100644 --- a/src/tests/snapshot.c +++ b/src/tests/snapshot.c @@ -118,8 +118,19 @@ int main(int argc, char *argv[]) goto err; } - printf(All tests passed\n); + if (!c-snapshot_destroy(c, snap0)) { + fprintf(stderr, %s: %d: failed to destroy snapshot\n, __FILE__, __LINE__); + goto err; + } + + if (!c-destroy(c)) { + fprintf(stderr, %s: %d: failed to destroy container\n, __FILE__, __LINE__); + goto err; + } + lxc_container_put(c); + printf(All tests passed\n); + try_to_remove(); exit(0); err: -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] do not allocate lxc_snapshot array if NULL is passed into snapshot_list as a ret_snaps parameter.
Hi, I just realized that the only reason of not being able to pass native data types to C world was my mistake so I believe you can ignore this patch :) Best, On Tue, Oct 15, 2013 at 12:32 AM, S.Çağlar Onur cag...@10ur.org wrote: All the other (similar) API calls behaves this way, aka passing NULL returns the count. This patch both provides consistency to calling conventions and also may make binding's life little easier cause we need to call those function two times. First to get the length and then get the data itself. This is required because we cannot pass our native data types directly to C world, at least Go can't for now. Right now a function that returns size only has to do something like that to free returned array; int i; struct lxc_snapshot *s; int n = c-snapshot_list(c, s); if (n 1) return 0; for (i = 0; i n; i++) { s[i].free(s[i]); } free(s); return n; whereas following should be enough. return c-snapshot_list(c, NULL); --- src/lxc/lxccontainer.c | 37 - src/lxc/lxccontainer.h | 4 ++-- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6f97879..391e4cd 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2516,23 +2516,25 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r } if (!file_exists(path2)) continue; - nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps)); - if (!nsnaps) { - SYSERROR(Out of memory); - goto out_free; - } - snaps = nsnaps; - snaps[count].free = lxcsnap_free; - snaps[count].name = strdup(direntp-d_name); - if (!snaps[count].name) - goto out_free; - snaps[count].lxcpath = strdup(snappath); - if (!snaps[count].lxcpath) { - free(snaps[count].name); - goto out_free; + if(ret_snaps != NULL) { + nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps)); + if (!nsnaps) { + SYSERROR(Out of memory); + goto out_free; + } + snaps = nsnaps; + snaps[count].free = lxcsnap_free; + snaps[count].name = strdup(direntp-d_name); + if (!snaps[count].name) + goto out_free; + snaps[count].lxcpath = strdup(snappath); + if (!snaps[count].lxcpath) { + free(snaps[count].name); + goto out_free; + } + snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp-d_name); + snaps[count].timestamp = get_timestamp(snappath, direntp-d_name); } - snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp-d_name); - snaps[count].timestamp = get_timestamp(snappath, direntp-d_name); count++; } @@ -2541,7 +2543,8 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r WARN(failed to close directory); process_unlock(); - *ret_snaps = snaps; + if (ret_snaps != NULL) + *ret_snaps = snaps; return count; out_free: diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 5901066..bb77126 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -197,12 +197,12 @@ struct lxc_container { /* * snapshot_list() will return a description of all snapshots of c in -* a simple array. See src/tests/snapshot.c for the proper way to +* a simple array, if ret_snaps is not null. See src/tests/snapshot.c for the proper way to * free the allocated results. * * Returns the number of snapshots. */ - int (*snapshot_list)(struct lxc_container *, struct lxc_snapshot **); + int (*snapshot_list)(struct lxc_container *c, struct lxc_snapshot **ret_snaps); /* * snapshot_restore() will create a new container based on a snapshot. -- 1.8.1.2 -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register
[lxc-devel] [PATCH] do not allocate lxc_snapshot array if NULL is passed into snapshot_list as a ret_snaps parameter.
All the other (similar) API calls behaves this way, aka passing NULL returns the count. This patch both provides consistency to calling conventions and also may make binding's life little easier cause we need to call those function two times. First to get the length and then get the data itself. This is required because we cannot pass our native data types directly to C world, at least Go can't for now. Right now a function that returns size only has to do something like that to free returned array; int i; struct lxc_snapshot *s; int n = c-snapshot_list(c, s); if (n 1) return 0; for (i = 0; i n; i++) { s[i].free(s[i]); } free(s); return n; whereas following should be enough. return c-snapshot_list(c, NULL); --- src/lxc/lxccontainer.c | 37 - src/lxc/lxccontainer.h | 4 ++-- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 6f97879..391e4cd 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -2516,23 +2516,25 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r } if (!file_exists(path2)) continue; - nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps)); - if (!nsnaps) { - SYSERROR(Out of memory); - goto out_free; - } - snaps = nsnaps; - snaps[count].free = lxcsnap_free; - snaps[count].name = strdup(direntp-d_name); - if (!snaps[count].name) - goto out_free; - snaps[count].lxcpath = strdup(snappath); - if (!snaps[count].lxcpath) { - free(snaps[count].name); - goto out_free; + if(ret_snaps != NULL) { + nsnaps = realloc(snaps, (count + 1)*sizeof(*snaps)); + if (!nsnaps) { + SYSERROR(Out of memory); + goto out_free; + } + snaps = nsnaps; + snaps[count].free = lxcsnap_free; + snaps[count].name = strdup(direntp-d_name); + if (!snaps[count].name) + goto out_free; + snaps[count].lxcpath = strdup(snappath); + if (!snaps[count].lxcpath) { + free(snaps[count].name); + goto out_free; + } + snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp-d_name); + snaps[count].timestamp = get_timestamp(snappath, direntp-d_name); } - snaps[count].comment_pathname = get_snapcomment_path(snappath, direntp-d_name); - snaps[count].timestamp = get_timestamp(snappath, direntp-d_name); count++; } @@ -2541,7 +2543,8 @@ static int lxcapi_snapshot_list(struct lxc_container *c, struct lxc_snapshot **r WARN(failed to close directory); process_unlock(); - *ret_snaps = snaps; + if (ret_snaps != NULL) + *ret_snaps = snaps; return count; out_free: diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 5901066..bb77126 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -197,12 +197,12 @@ struct lxc_container { /* * snapshot_list() will return a description of all snapshots of c in -* a simple array. See src/tests/snapshot.c for the proper way to +* a simple array, if ret_snaps is not null. See src/tests/snapshot.c for the proper way to * free the allocated results. * * Returns the number of snapshots. */ - int (*snapshot_list)(struct lxc_container *, struct lxc_snapshot **); + int (*snapshot_list)(struct lxc_container *c, struct lxc_snapshot **ret_snaps); /* * snapshot_restore() will create a new container based on a snapshot. -- 1.8.1.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60135031iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] API errors
Hi Serge, On Sat, Oct 5, 2013 at 12:27 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting Serge Hallyn (serge.hal...@ubuntu.com): Quoting S.Çağlar Onur (cag...@10ur.org): Hi, src/lxc/lxccontainer.h contains two public field named error_string and error_num. If I'm not missing anything no one seems to be using them. What was the intention? Should API calls set those and stop using macros like ERROR and SYSERROR? That is the idea. It's not yet clear to me how to best track that. Maybe it should become an array of strings, so that each stack layer moving up and seeing an error happened can give its own input on what it was doing. Then when lxc-start fails, we can see something like [0] failed to create container [1] failed to setup network [2] failed to create veth [3] failed to pass veth into network namespce And then yes, ERROR and SYSERROR should be reserved for the actual programs, and should spit out error stacks as well. So I'm thinking an API like the below. Much in bdev.c for instance can be converted to PUSH_ERR. Although all the places where we have fork()ed obviouslly cannot. There they'll have to keep doing ERROR(), and the parent can point to the logfile for further info. I'm imagining API methods themselves are going to call the clear_errors (i.e something like below) and the only reason to export that is to provide an alternative way to manage the stack? If that's the case, wouldn't be helpful if there will be a get_error call as well, which removes the last error from the stack and returns to the caller? diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 02126b2..7390cac 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -510,6 +510,8 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv if (!c-lxc_conf) return false; + c-clear_errors(); + if ((ret = ongoing_create(c)) 0) { ERROR(Error checking for incomplete creation); return false; diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 20ab8e8..b3c9641 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -49,9 +49,16 @@ struct lxc_container { int numthreads; /* protected by privlock. */ struct lxc_conf *lxc_conf; // maybe we'll just want the whole lxc_handler? - // public fields - char *error_string; + // error stack - protected by privlock + // These can be accessed using get_errors() and clear_errors() + // below. + char **error_string; int error_num; + bool oom; // true if there were more errors but no free memory; + char oom_error[MAXPATHLEN]; // if we oomed, last error goes in here + + // public fields + bool int daemonize; char *config_path; @@ -229,6 +236,18 @@ struct lxc_container { * and the caller may not access it. Return true otherwise. */ bool (*may_control)(struct lxc_container *c); + + /* +* Get stack of errors - one per line +* @output: preallocated string into which to print the errors +* @inlen: the length of passed-in buffer +* @oomed: will be set to 1 if we also oomed, in which case the oom msg +* is also a part of @output. +* +* Returns the needed length (including terminating \0) +*/ + int (*get_errors)(struct lxc_container *c, char *output, int inlen, int *oomed); + void (*clear_errors)(); }; struct lxc_snapshot { @@ -248,6 +267,18 @@ const char *lxc_get_default_lvm_vg(void); const char *lxc_get_default_zfs_root(void); const char *lxc_get_version(void); +/* + * Add another error to c-error_string, bump error_num. If we run + * out of memory and c-oom is not yet set, then set c-oom to 1 and + * put the message into c-oom_error. + */ +int DO_PUSH_ERR(struct lxc_container *c, char *fmt, ...); + +/* + * DO_PUSH_ERR_locked is same as DO_PUSH_ERR but will not call process_lock(). + */ +int DO_PUSH_ERR_locked(struct lxc_container *c, char *fmt, ...); + #if 0 char ** lxc_get_valid_keys(); char ** lxc_get_valid_values(char *key); -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60134791iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] API errors
Hi, src/lxc/lxccontainer.h contains two public field named error_string and error_num. If I'm not missing anything no one seems to be using them. What was the intention? Should API calls set those and stop using macros like ERROR and SYSERROR? Cheers, -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60134791iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [minor] Changing the version naming
Hi, On Thu, Sep 26, 2013 at 9:51 AM, Dwight Engen dwight.en...@oracle.comwrote: On Wed, 25 Sep 2013 17:57:02 -0400 Stéphane Graber stgra...@ubuntu.com wrote: On Wed, Sep 25, 2013 at 05:48:26PM -0400, S.Çağlar Onur wrote: Hey, It's not that important but I just wanted to learn your thoughts about starting to use more predictable version names for releases. I was trying to do some stuff based on the LXC version that is installed on the system and realized that current naming is little different than what I was expecting. Do you think something like following (and also starting to use http://semver.org/ kind of naming) is acceptable? diff --git a/configure.ac b/configure.ac index a523583..f466a43 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([lxc], [1.0.0.alpha1]) +AC_INIT([lxc], [1.0.0-alpha1]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) Best, It doesn't really matter to me or to any of the Debian based distros, but I seem to remember the version number being a problem to the RPM based distros in the past, so I'd rather not change the format unless we first make sure it's going to work with everyone's packaging. Yeah using the dash was a problem for RPM, see commit 0b531758. Got it. Thanks for the feedback... (And if we do change format, I'd only start doing it with alpha2 to avoid some extra confusion) Best, -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60133471iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 2/2] fix some larger memory leaks in cgroup code
Uhh something is wrong with this commit (178938fe0ac891092205d76f67af855dcf7397af), both go bindings and some lxc tools started to seg fault sudo lxc-ps Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) CONTAINER PID TTY TIME CMD 27168 pts/200:00:00 ps 27169 pts/200:00:00 awk 27061 pts/200:00:00 sudo 27062 pts/200:00:00 lxc-ps reverting 178938fe0a makes things OK again. On Tue, Sep 24, 2013 at 7:46 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: From: Dwight Engen dwight.en...@oracle.com Don't worry about saved_errno since none of the *_free routines will set it Signed-off-by: Dwight Engen dwight.en...@oracle.com Signed-off-by: Serge Hallyn serge.hal...@ubuntu.com --- 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 72abc2f..730d3b7 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -296,7 +296,7 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char ** return false; 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; @@ -305,7 +305,7 @@ static bool find_hierarchy_mountpts( struct cgroup_meta_data *meta_data, char ** 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 out; @@ -477,6 +477,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; } @@ -1103,29 +1104,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.3.2 -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60133471iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60133471iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net
Re: [lxc-devel] [PATCH 2/2] fix some larger memory leaks in cgroup code
On Wed, Sep 25, 2013 at 4:56 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting Dwight Engen (dwight.en...@oracle.com): Okay, it looks like you didn't merge any of the first one (cleanup fds, memory in lxc_cgroup_load_meta2()) so I'll look at rebasing that on git head, re-valgrind, and resubmit. Thanks. Thanks! -serge Much better now, thanks! -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60133471iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [minor] Changing the version naming
Hey, It's not that important but I just wanted to learn your thoughts about starting to use more predictable version names for releases. I was trying to do some stuff based on the LXC version that is installed on the system and realized that current naming is little different than what I was expecting. Do you think something like following (and also starting to use http://semver.org/ kind of naming) is acceptable? diff --git a/configure.ac b/configure.ac index a523583..f466a43 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. -AC_INIT([lxc], [1.0.0.alpha1]) +AC_INIT([lxc], [1.0.0-alpha1]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_AUX_DIR([config]) Best, -- S.Çağlar Onur cag...@10ur.org -- October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register http://pubads.g.doubleclick.net/gampad/clk?id=60133471iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Expose underlying close_all_fds config value via API
Actually I think there is no reason not to return a result to the caller, I'll send an incremental patch to do that. On Sat, Sep 21, 2013 at 12:47 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): Being able to set close_all_fds via API would be usefull for the situations like running an application (let's say web server) that controls the lifecycle of the container using the LXC API. We don't want forked process to inherit parent's resource (file, socket, ...) Signed-off-by: S.Çağlar Onur cag...@10ur.org Thanks, looks good to me. Acked-by: Serge E. Hallyn serge.hal...@ubuntu.com --- src/lxc/lxc_start.c| 2 +- src/lxc/lxccontainer.c | 13 + src/lxc/lxccontainer.h | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index dfc514e..a30a9f6 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -265,7 +265,7 @@ int main(int argc, char *argv[]) } if (my_args.close_all_fds) - conf-close_all_fds = 1; + c-want_close_all_fds(c); err = c-start(c, 0, args) ? 0 : -1; diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index e8dde91..727c680 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -456,6 +456,18 @@ static void lxcapi_want_daemonize(struct lxc_container *c) container_mem_unlock(c); } +static void lxcapi_want_close_all_fds(struct lxc_container *c) +{ + if (!c || !c-lxc_conf) + return; + if (container_mem_lock(c)) { + ERROR(Error getting mem lock); + return; + } + c-lxc_conf-close_all_fds = 1; + container_mem_unlock(c); +} + static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout) { int ret; @@ -2682,6 +2694,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath c-init_pid = lxcapi_init_pid; c-load_config = lxcapi_load_config; c-want_daemonize = lxcapi_want_daemonize; + c-want_close_all_fds = lxcapi_want_close_all_fds; c-start = lxcapi_start; c-startl = lxcapi_startl; c-stop = lxcapi_stop; diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 89b55bd..8b6c6ef 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -68,6 +68,7 @@ struct lxc_container { bool (*startl)(struct lxc_container *c, int useinit, ...); bool (*stop)(struct lxc_container *c); void (*want_daemonize)(struct lxc_container *c); + void (*want_close_all_fds)(struct lxc_container *c); // Return current config file name. The result is strdup()d, so free the result. char *(*config_file_name)(struct lxc_container *c); // for wait, timeout == -1 means wait forever, timeout == 0 means don't wait. -- 1.8.1.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=58041151iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- 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/22/13. http://pubads.g.doubleclick.net/gampad/clk?id=64545871iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] return the result of the lxcapi_want_close_all_fds call to the caller
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/lxccontainer.c | 7 --- src/lxc/lxccontainer.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 727c680..5c49b8b 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -456,16 +456,17 @@ static void lxcapi_want_daemonize(struct lxc_container *c) container_mem_unlock(c); } -static void lxcapi_want_close_all_fds(struct lxc_container *c) +static bool lxcapi_want_close_all_fds(struct lxc_container *c) { if (!c || !c-lxc_conf) - return; + return false; if (container_mem_lock(c)) { ERROR(Error getting mem lock); - return; + return false; } c-lxc_conf-close_all_fds = 1; container_mem_unlock(c); + return true; } static bool lxcapi_wait(struct lxc_container *c, const char *state, int timeout) diff --git a/src/lxc/lxccontainer.h b/src/lxc/lxccontainer.h index 8b6c6ef..225fb39 100644 --- a/src/lxc/lxccontainer.h +++ b/src/lxc/lxccontainer.h @@ -68,7 +68,7 @@ struct lxc_container { bool (*startl)(struct lxc_container *c, int useinit, ...); bool (*stop)(struct lxc_container *c); void (*want_daemonize)(struct lxc_container *c); - void (*want_close_all_fds)(struct lxc_container *c); + bool (*want_close_all_fds)(struct lxc_container *c); // Return current config file name. The result is strdup()d, so free the result. char *(*config_file_name)(struct lxc_container *c); // for wait, timeout == -1 means wait forever, timeout == 0 means don't wait. -- 1.8.1.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/22/13. http://pubads.g.doubleclick.net/gampad/clk?id=64545871iu=/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 - v3
Do you want me to sync this on top of staging and re-send?I think they are conflicting right now. On Wed, Sep 18, 2013 at 2:47 PM, Stéphane Graber stgra...@ubuntu.comwrote: On Mon, Sep 16, 2013 at 05:01:11PM -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. Support for python bindings also introduced as a part of this version. Signed-off-by: S.Çağlar Onur cag...@10ur.org Acked-by: Stéphane Graber stgra...@ubuntu.com --- 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; +
[lxc-devel] [PATCH] Add get_interfaces to the API - v4
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 cag...@10ur.org --- src/lxc/lxccontainer.c | 133 ++-- 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, 191 insertions(+), 41 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index d77ce37..e8dde91 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -1179,25 +1179,30 @@ 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); + process_lock(); + if (*new_netns = 0) + close(*new_netns); + if (*old_netns = 0) + close(*old_netns); + process_unlock(); +} + +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 */ process_lock(); - old_netns = open(/proc/self/ns/net, O_RDONLY); + *old_netns = open(/proc/self/ns/net, O_RDONLY); process_unlock(); - if (old_netns 0) { + if (*old_netns 0) { SYSERROR(failed to open /proc/self/ns/net); goto out; } @@ -1208,17 +1213,92 @@ char** lxcapi_get_ips(struct lxc_container *c, char* interface, char* family, in goto out; process_lock(); - new_netns = open(new_netns_path, O_RDONLY); + *new_netns = open(new_netns_path, O_RDONLY); process_unlock(); - if (new_netns 0) { + 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
Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v3
Not at all as I already did it on my tree, sending in a minute as v4... On Wed, Sep 18, 2013 at 2:58 PM, Stéphane Graber stgra...@ubuntu.comwrote: On Wed, Sep 18, 2013 at 02:53:33PM -0400, S.Çağlar Onur wrote: Do you want me to sync this on top of staging and re-send?I think they are conflicting right now. Ah, if you don't mind, that'd be great (I started doing it but I'm getting interrupted quite a bit since I'm attending a conference)! On Wed, Sep 18, 2013 at 2:47 PM, Stéphane Graber stgra...@ubuntu.com wrote: On Mon, Sep 16, 2013 at 05:01:11PM -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. Support for python bindings also introduced as a part of this version. Signed-off-by: S.Çağlar Onur cag...@10ur.org Acked-by: Stéphane Graber stgra...@ubuntu.com --- 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
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 stgra...@ubuntu.comwrote: 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 stgra...@ubuntu.com 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 cag...@10ur.org 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 **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
[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 cag...@10ur.org --- 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, tempIfAddr-ifa_name) == 0)
Re: [lxc-devel] [PATCH] Add get_interfaces to the API - v2
On Mon, Sep 16, 2013 at 2:39 PM, Stéphane Graber stgra...@ubuntu.comwrote: 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 cag...@10ur.org 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_netns, new_netns); + return false; +} + +static char** lxcapi_get_interfaces(struct lxc_container *c) +{ + int count = 0; + struct ifaddrs
[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 cag...@10ur.org --- 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_netns, new_netns); + +
Re: [lxc-devel] [PATCH] tests: Introduce lxc-test-concurrent for testing basic actions concurrently
Hi Serge, This seems to fix the creates but starts started to fail this time. One quick note, my concurrent.c still uses ubuntu as it's much more easy to replicate the issue with it. diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c index 7faf34c..ffc025c 100644 --- a/src/tests/concurrent.c +++ b/src/tests/concurrent.c @@ -40,7 +40,7 @@ void * concurrent(void *arguments) { args-return_code = 1; if (strcmp(args-mode, create) == 0) { if (!c-is_defined(c)) { -if (!c-create(c, busybox, NULL, NULL, 1, NULL)) { +if (!c-create(c, ubuntu, NULL, NULL, 1, NULL)) { fprintf(stderr, Creating the container (%s) failed...\n, name); goto out; } [caglar@oOo:~/Projects/lxc(staging)] sudo lxc-test-concurrent Executing (create) for 5 containers... Executing (start) for 5 containers... Starting the container (4) failed... lxc_container: command get_cgroup failed to receive response Starting the container (3) failed... Starting the container (2) failed... Starting the container (1) failed... Starting the container (0) failed... [caglar@oOo:~/go/src/github.com/caglar10ur/lxc(devel)] sudo lxc-ls 0 1 2 3 4 [caglar@oOo:~/go/src/github.com/caglar10ur/lxc(devel)] sudo lxc-start -d -n 0 lxc-start: command get_cgroup failed to receive response [caglar@oOo:~/go/src/github.com/caglar10ur/lxc(devel)] On Fri, Sep 13, 2013 at 10:20 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting Serge Hallyn (serge.hal...@ubuntu.com): Quoting Dwight Engen (dwight.en...@oracle.com): On Fri, 13 Sep 2013 17:29:53 -0400 Dwight Engen dwight.en...@oracle.com wrote: On Fri, 13 Sep 2013 12:09:55 -0400 S.Çağlar Onur cag...@10ur.org wrote: Hi Dwight, Yes, I only observed a hang so far but not this assertion (in fact I don't remember ever seeing that). What I'm seeing is this; Okay, something funny is going on, but I don't know what yet. That assertion is coming from liblxc.so-libgnutls-libgcrypt and seems to be complaining that we're unlocking something that is already unlocked. So I compiled lxc without GNUTLS support (by commenting out the check for it in configure.ac) and now I get past that and get hangs similar to yours. Interestingly, I modified your program to just do the create and destroy and not the start nor stop and I still get the hangs during the creation part. Sorry to reply to myself: So now I modified your program to do the create single threaded and everything else threaded (see attached patch) and that doesn't hang for me. It looked like to me that the hung threads were stuck on process_lock() so I added a backtrace there to debug it a bit more and it looks like the hang is in the flow: lxcapi_create() c-save_config() container_disk_lock() lxclock() process_lock() Not sure why yet though. Serge, do you think this could have to do with the fork()ing from a thread in that flow? Well, we've got save_config() doing an fopen without the process_lock() for one thing which is bad. That could explain it in a few ways - we could have corruption due to both tasks changing fdtable at the same time, or perhaps because open() is a cancelation point... Does doing a process_lock() around the fopen and fclose in lxcapi_save_config() fix it? something like this should be a start: Subject: api_start: make thread-safe (or at least start to) Signed-off-by: Serge Hallyn serge.hal...@ubuntu.com --- src/lxc/lxccontainer.c | 6 ++ src/lxc/parse.c| 4 2 files changed, 10 insertions(+) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 79237df..3c51c4a 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -665,7 +665,9 @@ static bool create_container_dir(struct lxc_container *c) free(s); return false; } + process_lock(); ret = mkdir(s, 0755); + process_unlock(); if (ret) { if (errno == EEXIST) ret = 0; @@ -1362,11 +1364,15 @@ static bool lxcapi_save_config(struct lxc_container *c, const char *alt_file) if (lret) return false; + process_lock(); fout = fopen(alt_file, w); + process_unlock(); if (!fout) goto out; write_config(fout, c-lxc_conf); + process_lock(); fclose(fout); + process_unlock(); ret = true; out: diff --git a/src/lxc/parse.c b/src/lxc/parse.c index 26cbbdd..f154b89 100644 --- a/src/lxc/parse.c +++ b/src/lxc/parse.c @@ -90,7 +90,9 @@ int lxc_file_for_each_line(const char *file, lxc_file_cb callback, void *data) char *line = NULL; size_t len = 0; + process_lock(); f = fopen(file, r); + process_unlock(); if (!f)
[lxc-devel] [PATCH] use busybox instead of ubuntu to test as it's much more lightweight, also wait containers to enter desired state
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/tests/concurrent.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c index 41c171b..7faf34c 100644 --- a/src/tests/concurrent.c +++ b/src/tests/concurrent.c @@ -40,7 +40,7 @@ void * concurrent(void *arguments) { args-return_code = 1; if (strcmp(args-mode, create) == 0) { if (!c-is_defined(c)) { -if (!c-create(c, ubuntu, NULL, NULL, 1, NULL)) { +if (!c-create(c, busybox, NULL, NULL, 1, NULL)) { fprintf(stderr, Creating the container (%s) failed...\n, name); goto out; } @@ -52,6 +52,10 @@ void * concurrent(void *arguments) { fprintf(stderr, Starting the container (%s) failed...\n, name); goto out; } +if (!c-wait(c, RUNNING, -1)) { +fprintf(stderr, Waiting the container (%s) to start failed...\n, name); +goto out; +} } } else if(strcmp(args-mode, stop) == 0) { if (c-is_defined(c) c-is_running(c)) { @@ -59,6 +63,10 @@ void * concurrent(void *arguments) { fprintf(stderr, Stopping the container (%s) failed...\n, name); goto out; } +if (!c-wait(c, STOPPED, -1)) { +fprintf(stderr, Waiting the container (%s) to stop failed...\n, name); +goto out; +} } } else if(strcmp(args-mode, destroy) == 0) { if (c-is_defined(c) !c-is_running(c)) { -- 1.8.1.2 -- How ServiceNow helps IT people transform IT departments: 1. Consolidate legacy IT systems to a single system of record for IT 2. Standardize and globalize service processes across IT 3. Implement zero-touch automation to replace manual, redundant tasks http://pubads.g.doubleclick.net/gampad/clk?id=5127iu=/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 and start not to filter out loopback interface
Hey Stéphane, On Fri, Sep 13, 2013 at 6:32 PM, Stéphane Graber stgra...@ubuntu.comwrote: On Fri, Sep 13, 2013 at 06:21:20PM -0400, S.Çağlar Onur wrote: Signed-off-by: S.Çağlar Onur cag...@10ur.org The loopback filtering was there so that all the software using get_ips to wait for the container to be reachable would work. Your change will essentially force everyone to do two calls, one for all interfaces and one just for lo, then substract the second set from the first, that seems suboptimal. I guess your plan is that most API users will iterate through get_interfaces then call get_ips for the interfaces they want, though that's just making things harder for little benefit. So I see two ways not to regress in that regard: 1) Make scope filtering work with IPv4, so that get_ips() user can pass scope=0 and only get global IPv4 and IPv6 addresses. 2) Add a no_loopback argument to get_ips. To be honest I removed filtering just because I thought get_ips and get_interfaces should return everything in the name of the completeness not because I saw something wrong with them. For that reason I can add filtering back to get_ips and start to filter loopback on get_interfaces. My real question is what do you think having a get_interfaces method in the API? I added that cause there was no way to get interface names from the container (and get_ips accepts an interface parameter). As it's: Nacked-by: Stéphane Graber stgra...@ubuntu.com --- src/lxc/lxccontainer.c | 119 +++-- src/lxc/lxccontainer.h | 1 + 2 files changed, 97 insertions(+), 23 deletions(-) diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 79237df..14b6942 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 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 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,93 @@ 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; +} + +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) { +if (tempIfAddr-ifa_addr == NULL) +continue; + + if(tempIfAddr-ifa_addr-sa_family != AF_PACKET) { +continue; +} + +count += 1; +temp = realloc(interfaces, count * sizeof(*interfaces)); +if (!temp) { +count -= 1; +goto out; +} +interfaces = temp; +
Re: [lxc-devel] [PATCH] tests: Introduce lxc-test-concurrent for testing basic actions concurrently
Hi Dwight, Yes it only stuck during creating concurrent containers for me and start/stop/freeze/unfreeze seems to work fine. If it helps I'm pretty sure that it was working fine till last week (or I was so lucky not to hit by this problem before). Go binding's test suite does lots of concurrent stuff to test bindings and they were passing but now ConcurrentCreate test case (which creates 10 containers in parallel) hangs most of the time. On Fri, Sep 13, 2013 at 5:29 PM, Dwight Engen dwight.en...@oracle.comwrote: On Fri, 13 Sep 2013 12:09:55 -0400 S.Çağlar Onur cag...@10ur.org wrote: Hi Dwight, Yes, I only observed a hang so far but not this assertion (in fact I don't remember ever seeing that). What I'm seeing is this; Okay, something funny is going on, but I don't know what yet. That assertion is coming from liblxc.so-libgnutls-libgcrypt and seems to be complaining that we're unlocking something that is already unlocked. So I compiled lxc without GNUTLS support (by commenting out the check for it in configure.ac) and now I get past that and get hangs similar to yours. Interestingly, I modified your program to just do the create and destroy and not the start nor stop and I still get the hangs during the creation part. * lxc-test-concurrent get stuck [caglar@qgq:~] sudo lxc-test-concurrent Executing (create) for 5 containers... * ps auwxf shows this (so no rsync etc. running anymore) caglar 21004 0.2 0.2 51344 4868 ?S11:59 0:00 mosh-server new -s -c 256 -l LANG=en_US.UTF-8 caglar 21005 0.0 0.2 23068 4412 pts/2Ss 11:59 0:00 \_ -bash root 27347 0.0 0.1 60248 2080 pts/2S+ 12:03 0:00 \_ sudo lxc-test-concurrent root 27348 0.0 0.0 383816 884 pts/2Sl+ 12:03 0:00 \_ lxc-test-concurrent root 27354 0.0 0.0 381684 408 pts/2S+ 12:03 0:00 \_ lxc-test-concurrent * strace give this [caglar@qgq:~/Projects/lxc(staging)] sudo strace -p 27354 Process 27354 attached - interrupt to quit futex(0x7fdc68b82cc0, FUTEX_WAIT_PRIVATE, 2, NULL^C unfinished ... Process 27354 detached [caglar@qgq:~/Projects/lxc(staging)] sudo strace -p 27348 Process 27348 attached - interrupt to quit futex(0x7fdc65f3d9d0, FUTEX_WAIT, 27353, NULL^C unfinished ... Process 27348 detached [caglar@qgq:~/Projects/lxc(staging)] sudo strace -p 27347 Process 27347 attached - interrupt to quit select(6, [3 5], [], NULL, NULL^C unfinished ... Process 27347 detached * lxc-ls [caglar@qgq:~/Projects/lxc(staging)] sudo lxc-ls --fancy NAME STATEIPV4 IPV6 -- 0 STOPPED - - 1 STOPPED - - 2 STOPPED - - 3 STOPPED - - 4 STOPPED - - * /var/lib/lxc/4/partial still there [caglar@qgq:/var/lib/lxc] ls /var/lib/lxc/* /var/lib/lxc/lxc-monitord.log /var/lib/lxc/0: config fstab rootfs /var/lib/lxc/1: config fstab rootfs /var/lib/lxc/2: config fstab rootfs /var/lib/lxc/3: config fstab rootfs /var/lib/lxc/4: config partial rootfs /var/lib/lxc/bleach: config fstab lxc_snapshots rootfs /var/lib/lxc/bleach-ng: config delta0 fstab lxc_rdepends rootfs -- S.Çağlar Onur cag...@10ur.org -- How ServiceNow helps IT people transform IT departments: 1. Consolidate legacy IT systems to a single system of record for IT 2. Standardize and globalize service processes across IT 3. Implement zero-touch automation to replace manual, redundant tasks http://pubads.g.doubleclick.net/gampad/clk?id=5127iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] regression: lxc-start -d hangs in lxc_monitor_sock_name (at process_lock)
Hi, I think staging (my head is @ 813a48...) started to stuck while creating containers concurrently after monitoring related changes. I observed that issue with the Go bindings first. Then I wrote a test case to remove Go from the picture and I also thought that having a test case would be helpful (see [PATCH] tests: Introduce lxc-test-concurrent for testing basic actions concurrently). Normally one should see following [caglar@qgq:~/Projects/lxc(staging)] sudo lxc-test-concurrent Executing (create) for 5 containers... Executing (start) for 5 containers... Executing (stop) for 5 containers... Executing (destroy) for 5 containers... but occasionally create started to stuck on my test system (just try to run couple of times). Cheers, On Thu, Sep 12, 2013 at 10:41 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting Dwight Engen (dwight.en...@oracle.com): On Thu, 12 Sep 2013 00:27:04 -0400 Stéphane Graber stgra...@ubuntu.com wrote: Hello, It looks like Dwight's last change introduce a bit of a regression when running lxc-start -d. Yikes, sorry I didn't catch that in my testing. My follow on patch for doing the monitor socket in the abstract space gets rid of this entirely, so this is an additional reason to consider it. Tracing it down (added a ton of printf all over), it looks like it's hanging on: - lxcapi_start - wait_on_daemonized_start - lxcapi_wait - lxc_wait - lxc_monitor_open - lxc_monitor_sock_name Specifically, it's hanging at the process_lock() call because process_lock() was already called as part of lxcapi_start and only gets unlocked right after wait_on_daemonized_start returns. Looking at the code, I'm not even sure why we need process_lock there. What it protects is another thread triggering the mkdir_p in parallel, but that shouldn't really be a problem since running two mkdir_p at the same time should still result in the hierarchy being created, or did I miss something? That sounds logical to me, but hmm, does that mean we don't need it in lxclock_name() either (where I was modeling this on)? I wonder if there is a code flow that its possible for us to hang there. Well mkdir uses the umask right? (and *may* use the cwd). Both of which are shared among threads. It won't set them, but something else might change them underneath them. So I could be wrong and we might not need it, but it seemed like we might. -serge -- How ServiceNow helps IT people transform IT departments: 1. Consolidate legacy IT systems to a single system of record for IT 2. Standardize and globalize service processes across IT 3. Implement zero-touch automation to replace manual, redundant tasks http://pubads.g.doubleclick.net/gampad/clk?id=5127iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- How ServiceNow helps IT people transform IT departments: 1. Consolidate legacy IT systems to a single system of record for IT 2. Standardize and globalize service processes across IT 3. Implement zero-touch automation to replace manual, redundant tasks http://pubads.g.doubleclick.net/gampad/clk?id=5127iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH] tests: Introduce lxc-test-concurrent for testing basic actions concurrently
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 3 ++ src/tests/Makefile.am | 6 ++- src/tests/concurrent.c | 116 + 3 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 src/tests/concurrent.c diff --git a/.gitignore b/.gitignore index 660756f..c005c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ .deps .libs +.dirstamp Makefile.in Makefile @@ -75,6 +76,7 @@ src/python-lxc/lxc/__pycache__/ src/tests/lxc-test-cgpath src/tests/lxc-test-clonetest +src/tests/lxc-test-concurrent src/tests/lxc-test-console src/tests/lxc-test-containertests src/tests/lxc-test-createtest @@ -85,6 +87,7 @@ src/tests/lxc-test-locktests src/tests/lxc-test-lxcpath src/tests/lxc-test-saveconfig src/tests/lxc-test-shutdowntest +src/tests/lxc-test-snapshot src/tests/lxc-test-startone src/tests/lxc-usernic-test diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index a6dacab..8157407 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -18,6 +18,7 @@ lxc_test_console_SOURCES = console.c lxc_usernic_test_SOURCES = ../lxc/lxc_user_nic.c ../lxc/nl.c lxc_usernic_test_CFLAGS = -DISTEST lxc_test_snapshot_SOURCES = snapshot.c +lxc_test_concurrent_SOURCES = concurrent.c AM_CFLAGS=-I$(top_srcdir)/src \ -DLXCROOTFSMOUNT=\$(LXCROOTFSMOUNT)\ \ @@ -30,7 +31,7 @@ bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \ lxc-test-destroytest lxc-test-saveconfig lxc-test-createtest \ lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \ lxc-test-cgpath lxc-test-clonetest lxc-test-console lxc-usernic-test \ - lxc-test-snapshot + lxc-test-snapshot lxc-test-concurrent bin_SCRIPTS = lxc-test-usernic @@ -51,4 +52,5 @@ EXTRA_DIST = \ startone.c \ console.c \ lxc-test-usernic \ - snapshot.c + snapshot.c \ + concurrent.c diff --git a/src/tests/concurrent.c b/src/tests/concurrent.c new file mode 100644 index 000..41c171b --- /dev/null +++ b/src/tests/concurrent.c @@ -0,0 +1,116 @@ +/* concurrent.c + * + * Copyright © 2013 S.Çağlar Onur cag...@10ur.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include stdio.h +#include pthread.h + +#include ../lxc/lxccontainer.h + +#define NTHREADS 5 + +struct thread_args { +int thread_id; +int return_code; +char *mode; +}; + +void * concurrent(void *arguments) { +char name[4]; +struct thread_args *args = arguments; +struct lxc_container *c; + +sprintf(name, %d, args-thread_id); + +c = lxc_container_new(name, NULL); + +args-return_code = 1; +if (strcmp(args-mode, create) == 0) { +if (!c-is_defined(c)) { +if (!c-create(c, ubuntu, NULL, NULL, 1, NULL)) { +fprintf(stderr, Creating the container (%s) failed...\n, name); +goto out; +} +} +} else if(strcmp(args-mode, start) == 0) { +if (c-is_defined(c) !c-is_running(c)) { +c-want_daemonize(c); +if (!c-start(c, false, NULL)) { +fprintf(stderr, Starting the container (%s) failed...\n, name); +goto out; +} +} +} else if(strcmp(args-mode, stop) == 0) { +if (c-is_defined(c) c-is_running(c)) { +if (!c-stop(c)) { +fprintf(stderr, Stopping the container (%s) failed...\n, name); +goto out; +} +} +} else if(strcmp(args-mode, destroy) == 0) { +if (c-is_defined(c) !c-is_running(c)) { +if (!c-destroy(c)) { +fprintf(stderr, Destroying the container (%s) failed...\n, name); +goto out; +} +} +} +args-return_code = 0; +out: +lxc_container_put(c); +pthread_exit(NULL); +} + + +int main(int argc, char *argv[]) { +int i, j; +pthread_attr_t attr; +pthread_t threads[NTHREADS]; +struct thread_args args[NTHREADS]; + +char *modes[] = {create, start, stop, destroy, NULL}; + +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;
Re: [lxc-devel] Clarifying the licensing of LXC
Hey Stéphane, I realized that Go bindings are licensed as GPLv2. I've no objection to re-licensing them with LGPL v2.1 but wanted to clarify it with you first. Should I go ahead and change the license or is it ok to stay with GPLv2? Best, On Fri, Aug 30, 2013 at 3:42 PM, Stéphane Graber stgra...@ubuntu.comwrote: Hello, First of all, sorry for the boring e-mail, nobody likes to deal with licenses but it's an unfortunate thing we have to deal with from time to time. Thomas Moschny reported some inconsistencies in the way LXC is currently licensed. The bug report is available here: https://github.com/lxc/lxc/issues/36 Basically the way I see it, LXC is made of 4 different bits: - The main library - The language bindings - The binary tools/scripts - The templates In order to make the library easily usable by others, LXC was originally licensed entirely under the LGPL v2.1 and higher and that certainly makes sense for any bit in the main library as well as for the bindings. Most of the tools, scripts and templates followed course and are also under LGPLv2.1+, some are under GPLv2 and that's all fine since they're tools and not libraries. The problem is that we currently have some files that are part of the library or part of bindings which are licensed under the wrong license, namely, they're currently under GPLv2. I believe this was an oversight and that we should get those switched to the proper license immediately. But I'm not simply going to go ahead and do that myself since I'm not the actual copyright holder for those. Instead, I'd like the original/main author of those to confirm it's fine by them and then we can do that. This still means we'll effectively re-license the code of some of our contributors without explicitly asking them about it. As I said, I'm convinced that this isn't a problem since we're just talking about a handful of files and it's always been clear that the LXC library is licensed under LGPLv2.1+. Nevertheless, if anyone contributed to one of those files we're about to re-license and do not wish their contributions re-licensed, please get in touch as soon as possible so we can remove the affected code from the project. The following files will be re-licensed from GPLv2 to LGPLv2.1+: - src/lua-lxc/core.c (Dwight) - src/lxc/lxccontainer.c (Serge) - src/lxc/lxclock.c (Serge) - src/lxc/lxclock.h (Serge) - src/tests/cgpath.c (Serge) - src/tests/containertests.c (Serge) - src/tests/createtest.c (Serge) - src/tests/destroytest.c (Serge) - src/tests/getkeys.c (Serge) - src/tests/get_item.c (Serge) - src/tests/locktests.c (Serge) - src/tests/lxcpath.c (Serge) - src/tests/saveconfig.c (Serge) - src/tests/shutdowntest.c (Serge) - src/tests/startone.c (Serge) - templates/lxc-ubuntu.in (Serge) - templates/lxc-ubuntu-cloud.in (Serge) Any file that currently doesn't contain a licensing header is assumed to be under the LGPLv2.1+ (as specified in COPYING). Additionally, some of the Android compatibility bits under lxc/includes/ are licensed under a two-clause BSD license. To the best of my knowledge, there are no restrictions in linking LGPLv2 code to BSD code. While processing that bug report, I've also noticed some cases where our license headers are out of date (wrong FSF address) or inconsistent (in the form, not the content). I'll be fixing those too before I send the alpha1 pull-request. -- Stéphane Graber Ubuntu developer http://www.ubuntu.com -- Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58040911iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58041391iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] Clarifying the licensing of LXC
Hi, On Fri, Sep 6, 2013 at 12:10 AM, Stéphane Graber stgra...@ubuntu.comwrote: Hi, Well since they're currently shipped out of tree, you're free to do whatever you want. GPLv2 code is allowed to link with an LGPLv2.1+ library so your code isn't in violation of LXC's license. However this very likely means that any software using your Go bindings will have to be GPLv2 in order to respect the binding's license. While that's your right, it's fairly uncommon and that's why I tend to prefer having bindings under a more permissive license with regard to linking, such as LGPLv2.1+. That's a good point. I'll re-license them with LGPLv2.1 as your argument really makes sense. Btw, speaking of those bindings, do they have to remain out of tree to be easily usable with go or could they be merged into LXC upstream at some point? I guess one potential issue would be packaging. Right now all magic is handled by go get and to be honest it's pretty convenient to use :). A quick Google search yielded multiple discussions about packaging RFC's on both go-nuts and debian mailing list. I haven't read all of them (so maybe I missed something) but it looks like none of them ended up with results. Even Juju's installation instructions says something like install go via sudo apt-get install golang-go and then get Juju by running go get -v launchpad.net/juju-core/.. so I'm assuming there is a reason for that. On Fri, Sep 06, 2013 at 12:01:15AM -0400, S.Çağlar Onur wrote: Hey Stéphane, I realized that Go bindings are licensed as GPLv2. I've no objection to re-licensing them with LGPL v2.1 but wanted to clarify it with you first. Should I go ahead and change the license or is it ok to stay with GPLv2? Best, On Fri, Aug 30, 2013 at 3:42 PM, Stéphane Graber stgra...@ubuntu.com wrote: Hello, First of all, sorry for the boring e-mail, nobody likes to deal with licenses but it's an unfortunate thing we have to deal with from time to time. Thomas Moschny reported some inconsistencies in the way LXC is currently licensed. The bug report is available here: https://github.com/lxc/lxc/issues/36 Basically the way I see it, LXC is made of 4 different bits: - The main library - The language bindings - The binary tools/scripts - The templates In order to make the library easily usable by others, LXC was originally licensed entirely under the LGPL v2.1 and higher and that certainly makes sense for any bit in the main library as well as for the bindings. Most of the tools, scripts and templates followed course and are also under LGPLv2.1+, some are under GPLv2 and that's all fine since they're tools and not libraries. The problem is that we currently have some files that are part of the library or part of bindings which are licensed under the wrong license, namely, they're currently under GPLv2. I believe this was an oversight and that we should get those switched to the proper license immediately. But I'm not simply going to go ahead and do that myself since I'm not the actual copyright holder for those. Instead, I'd like the original/main author of those to confirm it's fine by them and then we can do that. This still means we'll effectively re-license the code of some of our contributors without explicitly asking them about it. As I said, I'm convinced that this isn't a problem since we're just talking about a handful of files and it's always been clear that the LXC library is licensed under LGPLv2.1+. Nevertheless, if anyone contributed to one of those files we're about to re-license and do not wish their contributions re-licensed, please get in touch as soon as possible so we can remove the affected code from the project. The following files will be re-licensed from GPLv2 to LGPLv2.1+: - src/lua-lxc/core.c (Dwight) - src/lxc/lxccontainer.c (Serge) - src/lxc/lxclock.c (Serge) - src/lxc/lxclock.h (Serge) - src/tests/cgpath.c (Serge) - src/tests/containertests.c (Serge) - src/tests/createtest.c (Serge) - src/tests/destroytest.c (Serge) - src/tests/getkeys.c (Serge) - src/tests/get_item.c (Serge) - src/tests/locktests.c (Serge) - src/tests/lxcpath.c (Serge) - src/tests/saveconfig.c (Serge) - src/tests/shutdowntest.c (Serge) - src/tests/startone.c (Serge) - templates/lxc-ubuntu.in (Serge) - templates/lxc-ubuntu-cloud.in (Serge) Any file that currently doesn't contain a licensing header is assumed to be under the LGPLv2.1+ (as specified in COPYING). Additionally, some of the Android compatibility bits under lxc/includes/ are licensed under a two-clause BSD license. To the best of my knowledge, there are no restrictions in linking LGPLv2 code to BSD code. While processing that bug report, I've also noticed some cases where our license
[lxc-devel] [PATCH] bdev_copy segfaults if bdevtype is NULL
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/bdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index 39592b2..b45f2cb 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -1939,7 +1939,7 @@ struct bdev *bdev_copy(const char *src, const char *oldname, const char *cname, bdevtype = overlayfs; *needs_rdep = 0; - if (strcmp(orig-type, dir) == 0 + if (bdevtype strcmp(orig-type, dir) == 0 strcmp(bdevtype, overlayfs) == 0) *needs_rdep = 1; -- 1.8.1.2 -- Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more! Discover the easy way to master current and previous Microsoft technologies and advance your career. Get an incredible 1,500+ hours of step-by-step tutorial videos with LearnDevNow. Subscribe today and save! http://pubads.g.doubleclick.net/gampad/clk?id=58040911iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] RFC: aliases
Hey Serge, I'm not opposed the idea but just trying to understand the motivation behind it. We are doing exactly what you described (daily builds uses somename-date-buildnumber and two symlinks latest and stable points some containers) and I'm just using something like following sudo lxc-clone -o $(basename $(readlink SOMEPATH/latest)) -n SOMEOTHERNAME -s and I'm just wondering does it really worth adding more code for doing that? Cheers, On Tue, Aug 20, 2013 at 4:55 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Hi, one idea that has been brought up is to support 'aliases'. So if you're locally building a daily pristine container, say at 'c-2013-08-20', you might want to then have a 'c-latest' alias or link pointing to the latest container, so you can always just sudo lxc-clone -o c-latest -n test1 -s The most obvious idea would be to use a symbolic link. However, while that mostly works, it's actually not perfect - lxc_container_new() will be called with the name you passed in (c-latest), not with the symlinked name. Another idea would be to support a $lxcpath/$lxcname/config consisting of only 'lxc.alias = c-2013-0820'. Do people have any other ideas? I'm thinking symbolic link may be the simplest thing to support - lxc_container_new() could immediately readlink() to get the real container name. -serge -- Introducing Performance Central, a new site from SourceForge and AppDynamics. Performance Central is your source for news, insights, analysis and resources for efficient Application Performance Management. Visit us today! http://pubads.g.doubleclick.net/gampad/clk?id=48897511iu=/4140/ostg.clktrk ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Introducing Performance Central, a new site from SourceForge and AppDynamics. Performance Central is your source for news, insights, analysis and resources for efficient Application Performance Management. Visit us today! http://pubads.g.doubleclick.net/gampad/clk?id=48897511iu=/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: add outfile option
Hi, On Thu, Jul 11, 2013 at 5:39 PM, Dwight Engen dwight.en...@oracle.comwrote: On Thu, 11 Jul 2013 16:22:11 -0500 Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting Dwight Engen (dwight.en...@oracle.com): On Thu, 11 Jul 2013 15:40:10 -0500 Serge Hallyn serge.hal...@ubuntu.com wrote: Quoting Dwight Engen (dwight.en...@oracle.com): On Thu, 11 Jul 2013 14:48:21 -0500 Serge Hallyn serge.hal...@ubuntu.com wrote: lxc-create ... -o - will send template output to standard output (the old default). lxc-create ... without any -o will hide template output. lxc-create -o /tmp/xxx will send template output to the file /tmp/xxx. I like having a -o for lxc-create, but I'm not sure we should change the Sorry, that was wrong in my commit msg. only '--outfile' works (because 'o' is used by the common options for logfile output) default of lxc-create to not show the template output. For interactive We could swap the meanings so that '--outfile -' means on output, and not listing '--outfile' shows the output on stdout. Sorry, I'm not getting the difference between --outfile - and just getting output on stdout? My main concern was that lxc-create without any extra args do what it does today (shows output). With this current patch: lxc-create with no extra args does not show output lxc-create --outfile - shows output to stdout I'm suggesting we just flip those. Ahh, yep, I'd like it better flipped then as the no args case won't change today's behavior, but if others feel strongly I don't really care too much. So this is what I think you're proposing: lxc-create with no extra args - shows output on stdout lxc-create --outfile -- shows output on stdout lxc-create --outfile /tmp/xxx - output in /tmp/xxx What about adding a quiet parameter instead? It can silence the output and default will write to stdout, this way people who wants output file can redirect stdout to file as well use it can be quite useful, whereas I think silent certainly makes sense for the API (which is what I think Çağlars original concern was). Oh, hm, yeah. So my approach actually doesn't suffice. I was thinking callers could do the same thing, but that's somewhat silly. Maybe the API should take fds which we can dup2() onto 0,1,2 of the forked create process to handle both cases? (and would allow the API to capture the output if so desired) pass in an int* which is either NULL or contains 3 ints (i.e. -1, 10, 10 if 10 is an output file)? Yeah I think that would work, or 3 separate ints like we do for lxcapi_console(). Either way, if the caller passes -1, does that mean we would use the callers existing stdin,out,err i.e. don't dup2() that fd I was thinking -1 would mean leave that fd alone, but at all, or that we will ensure stdin,out,err are /dev/null? The later is probably easier for API callers and lxc-create can just pass the fd's it wants. Agreed, that seems to make sense. -- S.Çağlar Onur cag...@10ur.org -- See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] template output
Hi Serge, On Wed, Jul 10, 2013 at 10:36 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): Hi, It looks like LXC@staging started to write template outputs to stdout like following when one uses the API; [caglar@oOo:~/go/src/github.com/caglar10ur/lxc/examples] sudo ./create Creating container... Checking cache download in /var/cache/lxc/raring/rootfs-amd64 ... Copy /var/cache/lxc/raring/rootfs-amd64 to /usr/lib/x86_64-linux-gnu/lxc/rootfs ... Copying rootfs to /usr/lib/x86_64-linux-gnu/lxc/rootfs ... Generating locales... en_US.UTF-8... up-to-date Generation complete. Creating SSH2 RSA key; this may take some time ... Creating SSH2 DSA key; this may take some time ... Creating SSH2 ECDSA key; this may take some time ... ## # The default user is 'ubuntu' with password 'ubuntu'! # Use the 'sudo' command to run tasks as root in the container. ## It wasn't like that @0.9 and I'm not sure whether this change was intentional. Wanted to check with you before diving into code to see what changed. It was intentional. The template scripts provide meaningful output which I (after switching to lxc_create.c) was silencing, so I considered that a bug. Do you disagree? Should we keep it silent? Should we add an option to lxc-create to dump template output either to a file or stdout or (if unspecified) silent? -serge I think your suggestion providing an option to dump template output either to a file or stdout or (if unspecified) silent sounds best among possible solutions. Cheers -- S.Çağlar Onur cag...@10ur.org -- See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] template output
Hi, It looks like LXC@staging started to write template outputs to stdout like following when one uses the API; [caglar@oOo:~/go/src/github.com/caglar10ur/lxc/examples] sudo ./create Creating container... Checking cache download in /var/cache/lxc/raring/rootfs-amd64 ... Copy /var/cache/lxc/raring/rootfs-amd64 to /usr/lib/x86_64-linux-gnu/lxc/rootfs ... Copying rootfs to /usr/lib/x86_64-linux-gnu/lxc/rootfs ... Generating locales... en_US.UTF-8... up-to-date Generation complete. Creating SSH2 RSA key; this may take some time ... Creating SSH2 DSA key; this may take some time ... Creating SSH2 ECDSA key; this may take some time ... ## # The default user is 'ubuntu' with password 'ubuntu'! # Use the 'sudo' command to run tasks as root in the container. ## It wasn't like that @0.9 and I'm not sure whether this change was intentional. Wanted to check with you before diving into code to see what changed. Best, -- S.Çağlar Onur cag...@10ur.org -- See everything from the browser to the database with AppDynamics Get end-to-end visibility with application monitoring from AppDynamics Isolate bottlenecks and diagnose root cause in seconds. Start your free trial of AppDynamics Pro today! http://pubads.g.doubleclick.net/gampad/clk?id=48808831iu=/4140/ostg.clktrk___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] create api
Hi Serge, On Tue, May 14, 2013 at 3:13 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Hi, I'd like to rewrite lxc-create to be c (calling out to the c templates which continue to be scripts for the most part). Unfortunately right now the lxcapi_create() just takes arguments to send to the lxc-create script. I could either dump the existing lxcapi_create function, replace it with something close to the lxcapi_clone, and update the current callers, or I can write a new function lxcapi_create2, keeping lxcapi_create() as calling the c program (which then calls lxcapi_create2 :). The only reason to go with lxcapi_create2 would be for out of tree callers (which includes the go bindings). Since we're not at 1.0 yet we don't guarantee anything about api stability (for exactly this reason), but I thought I'd ask anyway what you all thought. Dumping the existing one and replacing it with something else works for me. Also I'm not aware any other user of go bindings than me and. Any if there are then I guess they shouldn't expect a stable API at this point because of the reasons that you stated. -serge -- AlienVault Unified Security Management (USM) platform delivers complete security visibility with the essential security capabilities. Easily and efficiently configure, manage, and operate all of your security controls from a single console and one unified framework. Download a free trial. http://p.sf.net/sfu/alienvault_d2d ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- AlienVault Unified Security Management (USM) platform delivers complete security visibility with the essential security capabilities. Easily and efficiently configure, manage, and operate all of your security controls from a single console and one unified framework. Download a free trial. http://p.sf.net/sfu/alienvault_d2d___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] lxc_monitord - monitor exiting
Hi Dwight, Thank you so much for quick triage and a patch! I briefly tested it and looks like it fixed the issue here as well. IMHO the thread safety of LXC is not that bad with the staging tree (thanks to your lxc-monitord and couple of other concurrency fixes). I believe we can create/start/stop/shutdown/freeze/unfreeze (I haven't tested clone yet) different containers in parallel. There may still some issues with doing those operations to the same container from multiple threads (src/lxc/commands.c come to my mind). My short term goal/wish is to provide a good concurrent experience to the go bindings (maybe we can add one or two tests two to test suite as well). P.S: I'll be away for couple of days (till next tuesday) so I won't be able to test this further or try other patches about this issue. Cheers, On Mon, May 6, 2013 at 3:59 PM, Dwight Engen dwight.en...@oracle.comwrote: On Mon, 6 May 2013 13:06:43 -0400 Dwight Engen dwight.en...@oracle.com wrote: Hi Çağlar, Thanks for the test program, I can sort of recreate it here with that, although once I lxc-stop them all, lxc-monitord does go away. I put a debug in lxc_wait() to see that the client always close the fd to the monitord and they all were closed so I'm not sure why lxc-monitord isn't seeing the accepted fd coming back from epoll to close. Still investigating... Okay, so I debugged this and the problem is basically down to lxc not being thread aware. With your test program we get multiple threads in lxcapi_start() simultaneously in the daemonize case. One of them forks while another one has the client fd to the monitor open and thus the fd gets duped by the fork and that is the client fd that holds lxc-monitord open until the container shuts down. Çağlar you could try out the following patch, it essentially serializes container startup from a thread perspective. I haven't tested it thoroughly, but it did fix the problem here. Right now lxc doesn't support threaded use, so you may run into other things as well. Depending on our stance on thread support in lxc, you may need to do the serialization in the threaded app. I guess another alternative is that initially we could just thread serialize at the API (big lxc lock). -- diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index 04a9208..f464fdb 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -18,6 +18,7 @@ */ #define _GNU_SOURCE +#include pthread.h #include unistd.h #include sys/types.h #include sys/wait.h @@ -346,6 +347,7 @@ static bool wait_on_daemonized_start(struct lxc_container *c) * I can't decide if it'd be more convenient for callers if we accept '...', * or a null-terminated array (i.e. execl vs execv) */ +static pthread_mutex_t start_mutex = PTHREAD_MUTEX_INITIALIZER; static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv[]) { int ret; @@ -391,13 +393,24 @@ static bool lxcapi_start(struct lxc_container *c, int useinit, char * const argv if (!lxc_container_get(c)) return false; lxc_monitord_spawn(c-config_path); + + ret = pthread_mutex_lock(start_mutex); + if (ret != 0) { + ERROR(pthread_mutex_lock returned:%d %s, ret, strerror(ret)); + return false; + } pid_t pid = fork(); if (pid 0) { lxc_container_put(c); + pthread_mutex_unlock(start_mutex); return false; } - if (pid != 0) - return wait_on_daemonized_start(c); + if (pid != 0) { + ret = wait_on_daemonized_start(c); + pthread_mutex_unlock(start_mutex); + return ret; + } + pthread_mutex_unlock(start_mutex); /* second fork to be reparented by init */ pid = fork(); if (pid 0) { -- S.Çağlar Onur cag...@10ur.org -- Learn Graph Databases - Download FREE O'Reilly Book Graph Databases is the definitive new guide to graph databases and their applications. This 200-page book is written by three acclaimed leaders in the field. The early access version is available now. Download your free book today! http://p.sf.net/sfu/neotech_d2d_may___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] lxc_monitord - monitor exiting
Hi all, I think I understand why I'm confused before while chasing another bug. This is what I'm seeing right now. * I patched lxc_monitord.c with following diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c index e76af71..59f1e9d 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c @@ -373,6 +373,7 @@ int main(int argc, char *argv[]) } if (lxc_monitord_create(mon)) { + NOTICE(create failed); goto out; } @@ -398,6 +399,7 @@ int main(int argc, char *argv[]) NOTICE(no clients for 30 seconds, exiting); break; } + NOTICE(clients %d, mon.clientfds_cnt); } lxc_mainloop_close(mon.descr); * I started 10 containers using go bindings [caglar@qgq:~/Project/lxc/examples] sudo ./concurrent_start Starting the container (3)... Starting the container (2)... Starting the container (4)... Starting the container (0)... Starting the container (1)... Starting the container (8)... Starting the container (7)... Starting the container (6)... Starting the container (5)... Starting the container (9)... * Then started to stop them 1 by 1 using lxc-stop [caglar@qgq:~/Project/lxc/examples] sudo lxc-stop -n 0 [caglar@qgq:~/Project/lxc/examples] sudo ./list 0 (STOPPED) 1 (RUNNING) 2 (RUNNING) 3 (RUNNING) 4 (RUNNING) 5 (RUNNING) 6 (RUNNING) 7 (RUNNING) 8 (RUNNING) 9 (RUNNING) [caglar@qgq:~/Project/lxc/examples] date sudo ./list Fri May 3 23:57:14 EDT 2013 0 (STOPPED) 1 (STOPPED) 2 (STOPPED) 3 (STOPPED) 4 (STOPPED) 5 (STOPPED) 6 (STOPPED) 7 (STOPPED) 8 (STOPPED) 9 (RUNNING) bleach (STOPPED) * lxc-monitord is still around after ~10min [caglar@qgq:~/Project/lxc/examples] ps aux | grep /usr/bin/lxc-monitord caglar1170 0.0 0.0 13580 940 pts/3S+ 23:57 0:00 grep --color=auto /usr/bin/lxc-monitord root 29997 0.0 0.0 15000 744 ?Ss 23:47 0:00 /usr/bin/lxc-monitord /var/lib/lxc 5 [caglar@qgq:~/Project/lxc/examples] date Fri May 3 23:57:52 EDT 2013 * And lastly here is what lxc-monitord.log shows [caglar@qgq:~/Project/lxc(clone)] tail -f /var/lib/lxc/lxc-monitord.log lxc-monitord 1367639242.631 NOTICE lxc_monitord - monitoring lxcpath /var/lib/lxc lxc-monitord 1367639242.633 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.633 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.636 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.639 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.643 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.643 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.651 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.654 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.665 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.678 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.681 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.681 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.682 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.707 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.710 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.710 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.722 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.733 NOTICE lxc_monitord - create failed lxc-monitord 1367639242.831 NOTICE lxc_monitord - create failed lxc-monitord 1367639274.071 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639323.928 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639372.862 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639444.107 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639474.130 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639504.133 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639534.161 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639564.190 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639594.209 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639624.223 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639654.256 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639684.287 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639714.317 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639744.347 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639774.370 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639804.396 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639834.426 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639864.456 NOTICE lxc_monitord - clients 9 lxc-monitord 1367639894.486 NOTICE lxc_monitord - clients 9 On Fri, Apr 26, 2013 at 4:52 PM, S.Çağlar Onur cag...@10ur.org wrote: Yeah, I think you all correct and I'm just confused - probably direct effect of lack of caffeine. And
[lxc-devel] lxcpath/default_path
Hey Serge, It looks like staging requires following as https://github.com/lxc/lxc/commit/a8428dfa2c6a43ee195f4be3e04a519ca1fc6ec0uses default_path but lxc_config provides lxcpath. index a454e07..cf19c7b 100644 --- a/src/lxc/lxc_config.c +++ b/src/lxc/lxc_config.c @@ -9,7 +9,7 @@ struct lxc_config_items { struct lxc_config_items items[] = { - { .name = lxcpath, .fn = lxc_get_default_config_path, }, + { .name = default_path, .fn = lxc_get_default_config_path, }, { .name = lvm_vg, .fn = lxc_get_default_lvm_vg, }, { .name = zfsroot, .fn = lxc_get_default_zfs_root, }, { .name = NULL, }, Cheers, -- S.Çağlar Onur cag...@10ur.org -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH 2/3] Update .gitignore
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index c614a75..0cec29a 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,9 @@ src/lxc/lxc-cgroup src/lxc/lxc-checkconfig src/lxc/lxc-checkpoint src/lxc/lxc-clone +src/lxc/lxc-clone-sh src/lxc/lxc-console +src/lxc/lxc-config src/lxc/lxc-create src/lxc/lxc-destroy src/lxc/lxc-execute -- 1.8.1.2 -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1 ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH 1/3] silence sh: 1: zfs: not found errors on systems without ZFS
Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/bdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lxc/bdev.c b/src/lxc/bdev.c index a3577a2..1de302f 100644 --- a/src/lxc/bdev.c +++ b/src/lxc/bdev.c @@ -440,7 +440,7 @@ static int zfs_list_entry(const char *path, char *output) FILE *f; int found=0; - if ((f = popen(zfs list, r)) == NULL) { + if ((f = popen(zfs list 2 /dev/null, r)) == NULL) { SYSERROR(popen failed); return 0; } -- 1.8.1.2 -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1 ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 2/3] Update .gitignore
On Tue, Apr 30, 2013 at 3:08 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): Signed-off-by: S.Çağlar Onur cag...@10ur.org --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index c614a75..0cec29a 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,9 @@ src/lxc/lxc-cgroup src/lxc/lxc-checkconfig src/lxc/lxc-checkpoint src/lxc/lxc-clone +src/lxc/lxc-clone-sh Sorry, we should probably just drop lxc-clone-sh right? Is there any reason not to? Sure, I thought you want it for some reason as you didn't nuke it with your clone patch :) src/lxc/lxc-console +src/lxc/lxc-config Right - thanks. src/lxc/lxc-create src/lxc/lxc-destroy src/lxc/lxc-execute -- 1.8.1.2 -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1 ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 3/3] Use correct parameter name (default_path instead of lxcpath)
Nope, you missed a backquote :) diff --git a/src/lxc/lxc.functions.in b/src/lxc/lxc.functions.in index 8c25bd5..de268df 100644 --- a/src/lxc/lxc.functions.in +++ b/src/lxc/lxc.functions.in @@ -25,6 +25,6 @@ bindir=@BINDIR@ templatedir=@LXCTEMPLATEDIR@ lxcinitdir=@LXCINITDIR@ -lxc_path=`lxc-config lxcpath +lxc_path=`lxc-config lxcpath` lxc_vg=`lxc-config lvm_vg` lxc_zfsroot=`lxc-config zfsroot` On Tue, Apr 30, 2013 at 3:27 PM, Serge Hallyn serge.hal...@ubuntu.comwrote: Thanks, guys. I believe staging branch should nwo be correct. -- S.Çağlar Onur cag...@10ur.org -- Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET Get 100% visibility into your production application - at no cost. Code-level diagnostics for performance bottlenecks with 2% overhead Download for free and get started troubleshooting in minutes. http://p.sf.net/sfu/appdyn_d2d_ap1___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] lxc_monitord - monitor exiting
Hey Dwight, I'm observing following behavior with staging tree and just wanted to make sure that what I'm seeing is the expected; * Initially nothing runs [caglar@qgq:~/Projects/lxc/examples] sudo ./list bankai (STOPPED) bleach (STOPPED) zangetsu (STOPPED) * I start one container using the API [caglar@qgq:~/Projects/lxc/examples] sudo ./start -name zangetsu Starting the container... [caglar@qgq:~/Projects/lxc/examples] sudo ./list bankai (STOPPED) bleach (STOPPED) zangetsu (RUNNING) * monitord starts as expected but exits after 30 seconds later (although container is still running); [caglar@qgq:~/Projects/lxc-upstream(staging)] tail -f /var/lib/lxc/lxc-monitord.log lxc-monitord 1367004858.616 NOTICE lxc_monitord - monitoring lxcpath /var/lib/lxc lxc-monitord 1367004888.677 NOTICE lxc_monitord - no clients for 30 seconds, exiting lxc-monitord 1367004888.677 NOTICE lxc_monitord - monitor exiting [caglar@qgq:~/Projects/lxc/examples] sudo ./list bankai (STOPPED) bleach (STOPPED) zangetsu (RUNNING) [caglar@qgq:~/Projects/lxc/examples] ps aux | grep monitord caglar 28404 0.0 0.0 7240 624 pts/54 S+ 15:34 0:00 tail -f /var/lib/lxc/lxc-monitord.log caglar 29037 0.0 0.0 9436 948 pts/0S+ 15:38 0:00 grep --color=auto monitord [caglar@qgq:~/Projects/lxc/examples] I'm asking cause I was under the impression that lxc-monitord will keep running as long as there is a container. Am I wrong? Cheers, -- S.Çağlar Onur cag...@10ur.org -- Try New Relic Now We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] implement backend drivers and container clone API (v2)
Hi Serge, Also do you have a git repository somewhere to pull this patch as this one won't apply cleanly on top of staging tree and I wanted to give it a try. On Wed, Apr 24, 2013 at 11:51 AM, S.Çağlar Onur cag...@10ur.org wrote: Hi Serge, [resending as list rejected my first mail due to its size] On Wed, Apr 24, 2013 at 9:26 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: +static void new_hwaddr(char *hwaddr) +{ + snprintf(hwaddr, 18, 00:16:3e:%02x:%02x:%02x, + rand() % 255, rand() % 255, rand() % 255); +} I believe we need to call srand here otherwise it will always give the same set of numbers with the same sequence -- S.Çağlar Onur cag...@10ur.org -- S.Çağlar Onur cag...@10ur.org -- Try New Relic Now We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 1/2] Support starting containers concurrently
Just wanted to remind that we still need this on top of Dwight's awesome work so that start work reliably. On Tue, Apr 23, 2013 at 5:24 PM, S.Çağlar Onur cag...@10ur.org wrote: From: S.Çağlar Onur cag...@10ur.org Trying to start multiple containers concurrently may cause lxc_monitor_read_timeout to fail as select call could be interrupted by a signal, handle it. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/state.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lxc/state.c b/src/lxc/state.c index 437f11a..60da22c 100644 --- a/src/lxc/state.c +++ b/src/lxc/state.c @@ -231,8 +231,11 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, const goto out_close; curtime = tv.tv_sec; } - if (lxc_monitor_read_timeout(fd, msg, timeout) 0) - goto out_close; + if (lxc_monitor_read_timeout(fd, msg, timeout) 0) { + /* try again if select interrupted by signal */ + if (errno != EINTR) + goto out_close; + } if (timeout != -1) { retval = gettimeofday(tv, NULL); -- 1.7.10.4 -- S.Çağlar Onur cag...@10ur.org -- Try New Relic Now We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] No child processes - unexpected waitpid return value on double-fork
Hey Serge, Unfortunately I don't have time to debug it today but I believe started to get following after your last commit [1]. [caglar@qgq:~/Project/lxc/examples] sudo ./concurrent_start Starting the container (5)... Starting the container (7)... Starting the container (0)... Starting the container (6)... Starting the container (9)... lxc_container: No child processes - unexpected waitpid return value on double-fork Starting the container (8)... Starting the container (1)... Starting the container (4)... Starting the container (2)... Starting the container (3)... lxc_container: No child processes - unexpected waitpid return value on double-fork [1] https://github.com/lxc/lxc/commit/6b7916695264238a490971e8cd87612154fc18b1.patch Best, -- S.Çağlar Onur cag...@10ur.org -- Try New Relic Now We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
[lxc-devel] [PATCH 2/2] Support stopping containers concurrently
From: S.Çağlar Onur cag...@10ur.org Trying to stop multiple containers concurrently ends up with cgroup is not mounted errors as multiple threads corrupts the shared variables. Fix that stack corruption and start to use getmntent_r to support stopping multiple containers concurrently. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/cgroup.c | 152 +++-- src/lxc/freezer.c | 18 +-- src/lxc/state.c | 15 -- 3 files changed, 126 insertions(+), 59 deletions(-) diff --git a/src/lxc/cgroup.c b/src/lxc/cgroup.c index 368214f..0739477 100644 --- a/src/lxc/cgroup.c +++ b/src/lxc/cgroup.c @@ -54,6 +54,11 @@ lxc_log_define(lxc_cgroup, lxc); #define MTAB /proc/mounts +/* In the case of a bind mount, there could be two long pathnames in the + * mntent plus options so use large enough buffer size + */ +#define LARGE_MAXPATHLEN 4 * MAXPATHLEN + /* Check if a mount is a cgroup hierarchy for any subsystem. * Return the first subsystem found (or NULL if none). */ @@ -100,29 +105,31 @@ static char *mount_has_subsystem(const struct mntent *mntent) */ static int get_cgroup_mount(const char *subsystem, char *mnt) { - struct mntent *mntent; + struct mntent *mntent, mntent_r; FILE *file = NULL; int ret, err = -1; + char buf[LARGE_MAXPATHLEN] = {0}; + file = setmntent(MTAB, r); if (!file) { SYSERROR(failed to open %s, MTAB); return -1; } - while ((mntent = getmntent(file))) { - if (strcmp(mntent-mnt_type, cgroup)) + while ((mntent = getmntent_r(file, mntent_r, buf, sizeof(buf { + if (strcmp(mntent_r.mnt_type, cgroup) != 0) continue; - + if (subsystem) { - if (!hasmntopt(mntent, subsystem)) + if (!hasmntopt(mntent_r, subsystem)) continue; } else { - if (!mount_has_subsystem(mntent)) + if (!mount_has_subsystem(mntent_r)) continue; } - ret = snprintf(mnt, MAXPATHLEN, %s, mntent-mnt_dir); + ret = snprintf(mnt, MAXPATHLEN, %s, mntent_r.mnt_dir); if (ret 0 || ret = MAXPATHLEN) goto fail; @@ -148,22 +155,33 @@ out: * * Returns 0 on success, -1 on error. * - * The answer is written in a static char[MAXPATHLEN] in this function and - * should not be freed. */ extern int cgroup_path_get(char **path, const char *subsystem, const char *cgpath) { - static charbuf[MAXPATHLEN]; - static charretbuf[MAXPATHLEN]; int rc; + char *buf = NULL; + char *retbuf = NULL; + + buf = malloc(MAXPATHLEN * sizeof(char)); + if (!buf) { + ERROR(malloc failed); + goto fail; + } + + retbuf = malloc(MAXPATHLEN * sizeof(char)); + if (!retbuf) { + ERROR(malloc failed); + goto fail; + } + /* lxc_cgroup_set passes a state object for the subsystem, * so trim it to just the subsystem part */ if (subsystem) { rc = snprintf(retbuf, MAXPATHLEN, %s, subsystem); if (rc 0 || rc = MAXPATHLEN) { ERROR(subsystem name too long); - return -1; + goto fail; } char *s = index(retbuf, '.'); if (s) @@ -172,19 +190,28 @@ extern int cgroup_path_get(char **path, const char *subsystem, const char *cgpat } if (get_cgroup_mount(subsystem ? retbuf : NULL, buf)) { ERROR(cgroup is not mounted); - return -1; + goto fail; } rc = snprintf(retbuf, MAXPATHLEN, %s/%s, buf, cgpath); if (rc 0 || rc = MAXPATHLEN) { ERROR(name too long); - return -1; + goto fail; } DEBUG(%s: returning %s for subsystem %s, __func__, retbuf, subsystem); + if(buf) + free(buf); + *path = retbuf; return 0; +fail: + if (buf) + free(buf); + if (retbuf) + free(retbuf); + return -1; } /* @@ -292,20 +319,25 @@ static int do_cgroup_set(const char *path, const char *value) int lxc_cgroup_set_bypath(const char *cgpath, const char *filename, const char *value) { int ret; - char *dirpath; + char *dirpath = NULL; char path[MAXPATHLEN]; ret = cgroup_path_get(dirpath, filename, cgpath); if (ret) - return -1; + goto fail; ret = snprintf(path, MAXPATHLEN, %s/%s, dirpath, filename); if (ret 0 || ret = MAXPATHLEN) { ERROR(pathname too long); -
[lxc-devel] [PATCH 1/2] Support starting containers concurrently
From: S.Çağlar Onur cag...@10ur.org Trying to start multiple containers concurrently may cause lxc_monitor_read_timeout to fail as select call could be interrupted by a signal, handle it. Signed-off-by: S.Çağlar Onur cag...@10ur.org --- src/lxc/state.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lxc/state.c b/src/lxc/state.c index 437f11a..60da22c 100644 --- a/src/lxc/state.c +++ b/src/lxc/state.c @@ -231,8 +231,11 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, const goto out_close; curtime = tv.tv_sec; } - if (lxc_monitor_read_timeout(fd, msg, timeout) 0) - goto out_close; + if (lxc_monitor_read_timeout(fd, msg, timeout) 0) { + /* try again if select interrupted by signal */ + if (errno != EINTR) + goto out_close; + } if (timeout != -1) { retval = gettimeofday(tv, NULL); -- 1.7.10.4 -- Try New Relic Now We'll Send You this Cool Shirt New Relic is the only SaaS-based application performance monitoring service that delivers powerful full stack analytics. Optimize and monitor your browser, app, servers with just a few lines of code. Try New Relic and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH] Use container specific domain socket name
Hi Serge, Yeah you are correct we need regular users to be able to monitor their own containes. I guess we can encrypt the messages but I'm not going there :) Cheers, On Wed, Apr 17, 2013 at 8:52 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): Hi there, What about using AF_INET but binding a restricted port while adding a new field to the message? As an example we can start to create a hmac (or something like that) per container in the creation time and save that into LXCPATH/CONTAINERNAME/hmac. Then both client (can add that value to message) and server (can read from filesystem to check authenticity of the file) can use it. By binding a restricted port we guarantee that regular users cannot sniff the traffic and by using the filesystem permissions we provide the desired separation? But we want regular users to be able to monitor their own containers. Now I suppose we could require an extra netns layer where an unprivileged user must first create a new userns, create a new netns in that, and start containers from there. Then he has privilege over restricted ports in that netns, so he can monitor containers created from there. It also gives a somewhat simple way to provide networking to unprivileged-user-created containers- simply have a privileged init script create the userns+netns for the user, keeping it open, create a NIC in there and hook it into a host bridge (since this init job is privileged on the host), then hand the setns fd to the user (by bind-mounting into a DAC-protected directory like /lxc/ns/$USER/). Now the user can setns into /lxc/ns/$user before running any lxc commands. It's quite different from what I was earlier envisioning, but doable. Disclaimer: I'm groggy this morning, so might be talking sillyness. -serge -- S.Çağlar Onur cag...@10ur.org -- Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel
Re: [lxc-devel] [PATCH 1/2] Support starting containers concurrently
Hi, That's up to you, I can keep them in my branch till we endup with a new monitor code or you can merge them now and they start to work with new monitor code later. I'm using git to send those patches and I can easily add signed-off lines (I even don't know why they are missing as I believe I use --signoff argument) and sent it again. Best, On Wed, Apr 17, 2013 at 9:10 AM, Serge Hallyn serge.hal...@ubuntu.comwrote: Quoting S.Çağlar Onur (cag...@10ur.org): From: S.Çağlar Onur cag...@10ur.org Trying to start multiple containers concurrently may cause lxc_monitor_read_timeout to fail as select call could be interrupted by a signal, handle it. Hi, so if I understand right we're waiting on this for a redesign of the monitor, right? How are you generating your patches? Could you add a Signed-off-by automatically? --- src/lxc/state.c |9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lxc/state.c b/src/lxc/state.c index 95707ac..c50ef00 100644 --- a/src/lxc/state.c +++ b/src/lxc/state.c @@ -230,8 +230,13 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, const goto out_close; curtime = tv.tv_sec; } - if (lxc_monitor_read_timeout(fd, msg, timeout) 0) - goto out_close; + if (lxc_monitor_read_timeout(fd, msg, timeout) 0) { + /* continue if select interrupted by signal */ + if (errno == EINTR) + continue; + else + goto out_close; + } if (timeout != -1) { retval = gettimeofday(tv, NULL); -- 1.7.10.4 -- Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter ___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel -- S.Çağlar Onur cag...@10ur.org -- Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter___ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel