[lxc-devel] Network interface - netns migration bug

2013-11-13 Thread Bogdan Purcareata
Hello,

I've encountered this bug with lxc-0.9.0, using the lxc-phys scenario - 
assigning a physical interface to a container.

In my understanding, this is what happens when a container starts (well, the 
relevant parts):
- the configuration file is parsed into a config structure - the kernel 
interface index is found using if_nametoindex(). This ifindex will be further 
used to move the interface from the host netns to the container's.
- the child process is cloned in a new netns;
- the parent issues a RTM_NEWLINK message to create a new interface in the 
netns associated with the pid of the child, having the known ifindex;
- it is implied that the interface will be removed from the host namespace;
- the child process will further use the same ifindex in order to rename the 
interface as needed; it is assumed that the interface will keep the same 
ifindex in the container network namespaces.

Here's my scenario - I'm using a small binary [1] that lists all the known 
interfaces and their respective ifindexes.

- the following interfaces are available on host:
Interface 1 : lo
Interface 2 : fm1-mac5
Interface 3 : fm2-mac5
Interface 4 : eth2
Interface 5 : tunl0
Interface 6 : sit0

- the following virtual interfaces are created when lxc-unsharing a process in 
a new netns:
Interface 1 : lo
Interface 2 : tunl0
Interface 3 : sit0

At this point, I want to create a container that has fm1-mac5 physically 
assigned. lxc-start fails with this message:
lxc-start: failed to rename tunl0->fm1-mac5 : File exists
lxc-start: failed to setup netdev
lxc-start: failed to setup the network for 'foo'
lxc-start: failed to setup the container
lxc-start: invalid sequence number 1. expected 2
lxc-start: failed to spawn 'foo'

By adding a few printf()s in the code, I was able to find the following facts:
- fm1-mac5 will have "2" as associated ifindex
- the new child process will be cloned with a new netns, with interfaces lo, 
tunl0 and sit0
- when issuing the RTM_NEWLINK netlink message, ifindex 2 (fm2-mac5) will be 
moved to the new netns, _however_ it will receive ifindex 4, since all previous 
ones are occupied
- when trying to rename the interface represented by ifindex 2 (tunl0) to 
"fm1-mac5", it will fail, because the interface is already there and it has 
ifindex 4

After container start fails, here are the interfaces on the host again:
Interface 1 : lo
Interface 3 : fm2-mac5
Interface 4 : eth2
Interface 5 : tunl0
Interface 6 : sit0
Interface 7 : fm1-mac5

fm1-mac5 now has ifindex 7 - when moving fm1-mac5 (having ifindex 4 in the 
container netns) back to the host netns, it will receive a new ifindex, since 4 
is occupied (eth2).

Running lxc-start again will succeed, and the following interfaces will be 
present in the container:
Interface 1 : lo
Interface 2 : tunl0
Interface 3 : sit0
Interface 7 : fm1-mac5

There was no problem assigning ifindex 7 to fm1-mac5 in the new netns, since it 
was used by no other interface.

I'm assuming that this doesn't manifest itself with virtual interfaces, since 
they receive high ifindexes (after all other interfaces) at creation time, with 
no possibility to clash with a new netns' default interfaces. This should only 
appear in the LXC_NET_PHYS case.

In this case, one thing that can be done is to force re-reading the ifindex, 
based on netdev->link:
---
 src/lxc/conf.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index 6b3f318..ff6b30b 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1846,6 +1846,14 @@ static int setup_netdev(struct lxc_netdev *netdev)
return 0;
  }

+ /* if LXC_NET_PHYS, update the ifindex */
+ if (netdev->type == LXC_NET_PHYS)
+   if (!(netdev->ifindex = if_nametoindex(netdev->link))) {
+ ERROR("unable to retrieve index for interface %s",
+   netdev->link);
+ return -1;
+   }
+
  /* retrieve the name of the interface */
  if (!if_indextoname(netdev->ifindex, current_ifname)) {
ERROR("no interface corresponding to index '%d'",
--
1.7.11.7

However, this does not solve a main issue: assuming that the ifindex will 
remain the same, in all situations, after an interface has been moved to a new 
netns. It _should_ not appear with virtual interfaces, but that depends on the 
ifindexes that are allocated to new interfaces.

How do you think this should be handled?

Thank you,
Bogdan P.

[1] 
http://iijean.blogspot.com/2010/03/howto-get-list-of-network-interfaces-in.html


--
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=63469471&iu=/4140/ostg.clktrk
_

Re: [lxc-devel] [PATCH] introduce lxcapi_add_device_node and lxcapi_remove_device_node to API

2013-11-13 Thread Serge Hallyn
Quoting S.Çağlar Onur (cag...@10ur.org):
> Adding block/char devices to running container is a common operation so 
> provide a common
> implementation for users to consume.
> 
> Signed-off-by: S.Çağlar Onur 

Acked-by: Serge E. Hallyn 

> ---
>  src/lxc/lxccontainer.c | 100 
> +
>  src/lxc/lxccontainer.h |   9 +
>  2 files changed, 109 insertions(+)
> 
> diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
> index ede0113..58eebb0 100644
> --- a/src/lxc/lxccontainer.c
> +++ b/src/lxc/lxccontainer.c
> @@ -2912,6 +2912,104 @@ static bool lxcapi_may_control(struct lxc_container 
> *c)
>   return lxc_try_cmd(c->name, c->config_path) == 0;
>  }
>  
> +static bool lxcapi_add_device_node(struct lxc_container *c, char *path)
> +{
> + int ret, size = 32;
> + struct stat st;
> + char *value = alloca(size);
> + char dest_path[MAXPATHLEN];
> +
> + /* make sure container is running */
> + if (!c->is_running(c)) {
> + ERROR("container is not running");
> + return false;
> + }
> +
> + /* make sure that we can access given path */
> + if(access(path, F_OK) < 0 || lstat(path, &st) < 0)
> + return false;
> +
> + /* continue if path is character device or block device */
> + if S_ISCHR(st.st_mode)
> + ret = snprintf(value, size, "c %d:%d rwm", major(st.st_rdev), 
> minor(st.st_rdev));
> + else if S_ISBLK(st.st_mode)
> + ret = snprintf(value, size, "b %d:%d rwm", major(st.st_rdev), 
> minor(st.st_rdev));
> + else
> + return false;
> +
> + /* check snprintf return code */
> + if (ret < 0 || ret >= size)
> + return false;
> +
> + /* prepare dest_path */
> + ret = snprintf(dest_path, MAXPATHLEN, "/proc/%d/root%s", 
> c->init_pid(c), path);
> + if (ret < 0 || ret >= MAXPATHLEN)
> + return false;
> +
> + /* remove dest_path if exists in the container */
> + if(access(dest_path, F_OK) == 0)
> + unlink(dest_path);
> +
> + /* create the device node */
> + if (mknod(dest_path, st.st_mode, st.st_rdev) < 0)
> + return false;
> +
> + /* add to device list */
> + if (!c->set_cgroup_item(c, "devices.allow", value)) {
> + ERROR("set_cgroup_item failed");
> + return false;
> + }
> +
> + return true;
> +}
> +
> +static bool lxcapi_remove_device_node(struct lxc_container *c, char *path)
> +{
> + int ret, size = 32;
> + struct stat st;
> + char *value = alloca(size);
> + 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), path);
> + if (ret < 0 || ret >= MAXPATHLEN)
> + return false;
> +
> + /* make sure that we can access dest_path */
> + if(access(dest_path, F_OK) < 0 || lstat(dest_path, &st) < 0)
> + return false;
> +
> + /* continue if path is character device or block device */
> + if S_ISCHR(st.st_mode)
> + ret = snprintf(value, size, "c %d:%d rwm", major(st.st_rdev), 
> minor(st.st_rdev));
> + else if S_ISBLK(st.st_mode)
> + ret = snprintf(value, size, "b %d:%d rwm", major(st.st_rdev), 
> minor(st.st_rdev));
> + else
> + return false;
> +
> + /* check snprintf return code */
> + if (ret < 0 || ret >= size)
> + return false;
> +
> + /* remove dest_path if exists in the container */
> + if(access(dest_path, F_OK) == 0)
> + unlink(dest_path);
> +
> + /* remove from device list */
> + if (!c->set_cgroup_item(c, "devices.deny", value)) {
> + ERROR("set_cgroup_item failed");
> + return false;
> + }
> +
> + return true;
> +}
> +
>  static int lxcapi_attach_run_waitl(struct lxc_container *c, 
> lxc_attach_options_t *options, const char *program, const char *arg, ...)
>  {
>   va_list ap;
> @@ -3033,6 +3131,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.
>*/
>   b

[lxc-devel] [lxc/lxc] ff4bac: introduce lxcapi_add_device_node and lxcapi_remove...

2013-11-13 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: ff4bacf71a3078cb2b926bfb248266236da9b1eb
  https://github.com/lxc/lxc/commit/ff4bacf71a3078cb2b926bfb248266236da9b1eb
  Author: S.Çağlar Onur 
  Date:   2013-11-13 (Wed, 13 Nov 2013)

  Changed paths:
M src/lxc/lxccontainer.c
M src/lxc/lxccontainer.h

  Log Message:
  ---
  introduce lxcapi_add_device_node and lxcapi_remove_device_node to API

Adding block/char devices to running container is a common operation so provide 
a common
implementation for users to consume.

Signed-off-by: S.Çağlar Onur 
Signed-off-by: Serge Hallyn 



--
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=63469471&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [lxc/lxc]

2013-11-13 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc

--
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=63469471&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH] introduce lxcapi_add_device_node and lxcapi_remove_device_node to API (v3)

2013-11-13 Thread Stéphane Graber
On Wed, Nov 13, 2013 at 12:39:00AM -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;
> * 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 

Hi,

So at first glance the reason why the remove function also take both src
and dest path wasn't very obvious though after thinking about it some
more, I guess it makes sense to always look for type/major/minor of the
source device, so passing only the dest path wouldn't work. And it's
possible that at some point we may want to do something again the dest
path (like removing it) so it doesn't hurt to have it passed too (though
at this point, passing it or not shouldn't make any difference).


Acked-by: Stéphane Graber 

Note that Serge pushed v0 by accident but he then reverted it, so I'll
push v3 now.

> ---
>  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 
>  #include 
>  #include 
> +#include 
>  
>  #if HAVE_IFADDRS_H
>  #include 
> @@ -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_remov

[lxc-devel] [lxc/lxc] a9a0ed: introduce lxcapi_add_device_node and lxcapi_remove...

2013-11-13 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/lxc/lxc
  Commit: a9a0ed90dd1cdadd412576a45af16419efc0e939
  https://github.com/lxc/lxc/commit/a9a0ed90dd1cdadd412576a45af16419efc0e939
  Author: S.Çağlar Onur 
  Date:   2013-11-13 (Wed, 13 Nov 2013)

  Changed paths:
M src/lxc/lxccontainer.c
M src/lxc/lxccontainer.h

  Log Message:
  ---
  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 
Acked-by: Stéphane Graber 



--
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=63469471&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] Rethinking lxc-info a bit

2013-11-13 Thread Stéphane Graber
Hello,

We recently got reports of the recent changes to lxc-info breaking
existing scripts.

While discusing those issues, I noticed a few points that I think are
worth discussing and addressing, I'm going to postpone alpha3 until
that's done as the current state of things would break quite a bunch of
scripts.

== confusing -n behaviour ==
Since Dwight's last change, -n now accepts a regular expression, which I
believe is the only case where it does. That seems fairly unintuitive
and redundant with what lxc-list for example provides.
This also brought on the next problem.

== change of behaviour when one of the filter is passed ==
In the past, someone could do "lxc-info -n p1 -p" and trivially retrieve
the PID.

The new behaviour instead returns:
Name:   p1
Pid:19446

Even though I didn't ask for the container's name. "pid" was also
renamed to "Pid", breaking anyone attempting to grep for the entry.

== --state-is option is redundant ==
The state-is option always seemed a bit odd to me, in fact, it's
absolutely identical to "lxc-wait -t 0 -n  -s " and I don't
really think it has its place in lxc-info. I'd suggest we just remove it
entirely (yes, that'll break some scripts).


I'm sorry I didn't think about those problems when reviewing the recent
changes to lxc-info, but hopefully it's not too late to correct some of
that.


So my suggestion for lxc-info in LXC 1.0 are:
 - Only support one container and make -n mandatory, fail with an error
   if the container can't be found.
 - Drop --state-is entirely and tell anyone who used it to use lxc-wait
   instead.
 - Only print Name: if none of the filters are passed
 - Make the combination of -H + a single filter only return that value,
   so that "lxc-info -n p1 -P -H" will just return 19446 without any
   formatting. Recommend doing that to anyone parsing lxc-info's output.
 - Have -H also apply to the general formatting, simply printing :
when passed.


With those done, there will still be breakage for users of alpha2
upgrading to alpha3, but that should at least ensure no more surprises
after that point and a more script friendly command.


Thoughts?

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


signature.asc
Description: Digital signature
--
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=63469471&iu=/4140/ostg.clktrk___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] Rethinking lxc-info a bit

2013-11-13 Thread Serge Hallyn
Quoting Stéphane Graber (stgra...@ubuntu.com):
> Hello,
> 
> We recently got reports of the recent changes to lxc-info breaking
> existing scripts.

In my own case, I have a host with several containers where a backup
script uses 'lxc-info -n $container -p | awk ...' to get the init pid,
then rsyncs from /proc/$pid/root/$path to /decrypted_backup/$name/$path.
The fix was trivial (once diagnosed), but I don't know how many people
have scripts built into their infrastructure depending on this.

In the past, lxc-info -n www -p would have shown

pid: $pid

I always thought the 'pid:\t' was silly in that case.  OTOH, getting rid
of it now would, again, break existing scripts.

> While discusing those issues, I noticed a few points that I think are
> worth discussing and addressing, I'm going to postpone alpha3 until
> that's done as the current state of things would break quite a bunch of
> scripts.
> 
> == confusing -n behaviour ==
> Since Dwight's last change, -n now accepts a regular expression, which I
> believe is the only case where it does. That seems fairly unintuitive
> and redundant with what lxc-list for example provides.

Is there anything which lxc-list would not suffice for?

> This also brought on the next problem.
> 
> == change of behaviour when one of the filter is passed ==
> In the past, someone could do "lxc-info -n p1 -p" and trivially retrieve
> the PID.
> 
> The new behaviour instead returns:
> Name:   p1
> Pid:19446
> 
> Even though I didn't ask for the container's name. "pid" was also
> renamed to "Pid", breaking anyone attempting to grep for the entry.
> 
> == --state-is option is redundant ==
> The state-is option always seemed a bit odd to me, in fact, it's
> absolutely identical to "lxc-wait -t 0 -n  -s " and I don't
> really think it has its place in lxc-info. I'd suggest we just remove it
> entirely (yes, that'll break some scripts).
> 
> 
> I'm sorry I didn't think about those problems when reviewing the recent
> changes to lxc-info, but hopefully it's not too late to correct some of
> that.
> 
> 
> So my suggestion for lxc-info in LXC 1.0 are:
>  - Only support one container and make -n mandatory, fail with an error
>if the container can't be found.
>  - Drop --state-is entirely and tell anyone who used it to use lxc-wait
>instead.
>  - Only print Name: if none of the filters are passed
>  - Make the combination of -H + a single filter only return that value,
>so that "lxc-info -n p1 -P -H" will just return 19446 without any
>formatting. Recommend doing that to anyone parsing lxc-info's output.

Sounds good to me.

Perhaps we should have a transition guide for 1.0?  Where would that
belong?

>  - Have -H also apply to the general formatting, simply printing :
> when passed.
> 
> 
> With those done, there will still be breakage for users of alpha2
> upgrading to alpha3, but that should at least ensure no more surprises
> after that point and a more script friendly command.
> 
> 
> Thoughts?
> 
> -- 
> 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=63469471&iu=/4140/ostg.clktrk

> ___
> Lxc-devel mailing list
> Lxc-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel


--
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=63469471&iu=/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

2013-11-13 Thread S . Çağlar Onur
Signed-off-by: S.Çağlar Onur 
---
 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 
 #include 
 
+#ifdef MUTEX_DEBUGGING
+#include 
+#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 
 #include 
 #include 
-#include 
-
-#ifdef MUTEX_DEBUGGING
-#include 
-#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 static_unlock(void)
-{
-   int ret;
-
-   if ((ret = pthread_mutex_unlock(&stat

Re: [lxc-devel] Rethinking lxc-info a bit

2013-11-13 Thread Dwight Engen
On Wed, 13 Nov 2013 14:41:55 -0500
Stéphane Graber  wrote:

> Hello,
> 
> We recently got reports of the recent changes to lxc-info breaking
> existing scripts.
> 
> While discusing those issues, I noticed a few points that I think are
> worth discussing and addressing, I'm going to postpone alpha3 until
> that's done as the current state of things would break quite a bunch
> of scripts.
> 
> == confusing -n behaviour ==
> Since Dwight's last change, -n now accepts a regular expression,
> which I believe is the only case where it does. That seems fairly
> unintuitive and redundant with what lxc-list for example provides.
> This also brought on the next problem.

I did this because I wanted to be able to get info on all/some
containers and the previous precedent for that: lxc-wait, even before
I messed with it ;) used regex matching. I think Serge mentioned that
he didn't like regex's there, and would prefer glob fnmatch style
matching. I'm not particularly tied to lxc-info being able to handle
multiples though, so I'm fine if we want to rip that out :)

Also I don't think lxc-ls has a way to list all containers, (ie. both
defined and active) but it would be easy to have it do that now.

> == change of behaviour when one of the filter is passed ==
> In the past, someone could do "lxc-info -n p1 -p" and trivially
> retrieve the PID.
> 
> The new behaviour instead returns:
> Name:   p1
> Pid:19446
> 
> Even though I didn't ask for the container's name. "pid" was also
> renamed to "Pid", breaking anyone attempting to grep for the entry.

I agree name shouldn't be printed in that case, or any time a specific
thing is asked for. I actually looked for trouble the name changing
might cause, and the only potential case I saw in the shipped lxc
stuff was lxc-test-ubuntu, but it was okay because it called lxc-info
-i and awked out the second column, so renaming "IP" didn't break it.

You are correct though that external scripts might've broken though. If
we're going to say that lxc-info's output is "stable" though so folks
can grep out which parts they want, then maybe we don't need options
like -i and -p ?

> == --state-is option is redundant ==
> The state-is option always seemed a bit odd to me, in fact, it's
> absolutely identical to "lxc-wait -t 0 -n  -s " and I
> don't really think it has its place in lxc-info. I'd suggest we just
> remove it entirely (yes, that'll break some scripts).

Agree, especially considering it doesn't even seem to work right now.
$? seems to always be 0 for me.

> I'm sorry I didn't think about those problems when reviewing the
> recent changes to lxc-info, but hopefully it's not too late to
> correct some of that.

Sorry for introducing these problems :(

> 
> So my suggestion for lxc-info in LXC 1.0 are:
>  - Only support one container and make -n mandatory, fail with an
> error if the container can't be found.
>  - Drop --state-is entirely and tell anyone who used it to use
> lxc-wait instead.
>  - Only print Name: if none of the filters are passed
>  - Make the combination of -H + a single filter only return that
> value, so that "lxc-info -n p1 -P -H" will just return 19446 without
> any formatting. Recommend doing that to anyone parsing lxc-info's
> output.
>  - Have -H also apply to the general formatting, simply printing
> :  when passed.

That all sounds fine to me. 
 
> With those done, there will still be breakage for users of alpha2
> upgrading to alpha3, but that should at least ensure no more surprises
> after that point and a more script friendly command.
> 
> 
> Thoughts?
> 


--
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=63469471&iu=/4140/ostg.clktrk
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel