<div dir="ltr">Hi Serge,<div><br></div><div style>Got it, in this case I'm waiting Daniel to respond before changing the patch based on your comments.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">

On Tue, Apr 9, 2013 at 8:47 AM, Serge Hallyn <span dir="ltr"><<a href="mailto:serge.hallyn@ubuntu.com" target="_blank">serge.hallyn@ubuntu.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="HOEnZb"><div class="h5">Quoting S.Çağlar Onur (<a href="mailto:caglar@10ur.org">caglar@10ur.org</a>):<br>
> From: "S.Çağlar Onur" <<a href="mailto:caglar@10ur.org">caglar@10ur.org</a>><br>
><br>
> Otherwise trying to start N containers in parallel gives "lxc_container: bind : Address already in use" error.<br>
><br>
> Found while using Go bindings to create/start/stop large number of containers in parallel so I reproduced the same using Python API to rule out possible Go related problems.<br>
><br>
> ----<br>
> import lxc<br>
><br>
> from queue import Empty<br>
> from multiprocessing import Process, Queue<br>
><br>
> def create(q):<br>
>     while True:<br>
>         try:<br>
>             x = q.get(block=False)<br>
>             c = lxc.Container(str(x))<br>
>             print("Starting", x)<br>
>             c.start()<br>
>         except Empty:<br>
>             break<br>
><br>
> if __name__=="__main__":<br>
>     work_queue = Queue()<br>
>     for i in range(11):<br>
>         work_queue.put(i)<br>
><br>
>     process = [Process(target=create, args=(work_queue,)) for i in range(4)]<br>
>     for p in process:<br>
>         p.start()<br>
><br>
>     for p in process:<br>
>         p.join()<br>
> ----<br>
><br>
> caglar@qgq:~/Project$ sudo python3 cstart.py<br>
> Starting 0<br>
> Starting 1<br>
> lxc_container: bind : Address already in use<br>
> Starting 3<br>
> Starting 4<br>
> Starting 2<br>
> lxc_container: lxc_container: bind : Address already in use<br>
> bind : Address already in uselxc_container: bind : Address already in use<br>
><br>
> Starting 5<br>
> Starting 6<br>
> lxc_container: bind : Address already in use<br>
> lxc_container: bind : Address already in use<br>
> Starting 7<br>
> Starting 8<br>
> Starting 9<br>
> lxc_container: bind : Address already in use<br>
> lxc_container: bind : Address already in use<br>
> lxc_container: bind : Address already in use<br>
> Starting 10<br>
> lxc_container: bind : Address already in use<br>
><br>
> Signed-off-by: S.Çağlar Onur <<a href="mailto:caglar@10ur.org">caglar@10ur.org</a>><br>
<br>
</div></div>Hi,<br>
<br>
Thanks.  This is definately something we want to address.  However,<br>
what do here only partially solves it.  I'm not completely against<br>
it as it helps a useful case.<br>
<br>
Daniel has said (at least physical UDS) that he wanted to improve the<br>
monitor code to allow multiple simultaneous connections.  That would<br>
solve your problem as well as the more general problem of supporting<br>
multiple simulatanous lxc-wait and lxc-monitors, which yours does not<br>
solve.<br>
<br>
Daniel, can you lay out here how you were planning to do that?  Have you<br>
had any time - or will you have any time soon - to start that?<br>
<br>
In any case I'd prefer is if we kept lxc_name before lxc_path in arg list.<br>
<div><div class="h5"><br>
> ---<br>
>  src/lxc/lxc.h         |    2 +-<br>
>  src/lxc/lxc_monitor.c |    2 +-<br>
>  src/lxc/monitor.c     |   10 +++++-----<br>
>  src/lxc/state.c       |    2 +-<br>
>  4 files changed, 8 insertions(+), 8 deletions(-)<br>
><br>
> diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h<br>
> index db921f0..224d460 100644<br>
> --- a/src/lxc/lxc.h<br>
> +++ b/src/lxc/lxc.h<br>
> @@ -74,7 +74,7 @@ extern int lxc_execute(const char *name, char *const argv[], int quiet,<br>
>   * The function will return an fd corresponding to the events<br>
>   * Returns a file descriptor on success, < 0 otherwise<br>
>   */<br>
> -extern int lxc_monitor_open(const char *lxcpath);<br>
> +extern int lxc_monitor_open(const char *lxcpath, const char *lxcname);<br>
><br>
>  /*<br>
>   * Read the state of the container if this one has changed<br>
> diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c<br>
> index 0530373..4898377 100644<br>
> --- a/src/lxc/lxc_monitor.c<br>
> +++ b/src/lxc/lxc_monitor.c<br>
> @@ -87,7 +87,7 @@ int main(int argc, char *argv[])<br>
>               return -1;<br>
>       }<br>
><br>
> -     fd = lxc_monitor_open(my_args.lxcpath);<br>
> +     fd = lxc_monitor_open(my_args.lxcpath, <a href="http://my_args.name" target="_blank">my_args.name</a>);<br>
>       if (fd < 0)<br>
>               return -1;<br>
><br>
> diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c<br>
> index afdaf67..2590559 100644<br>
> --- a/src/lxc/monitor.c<br>
> +++ b/src/lxc/monitor.c<br>
> @@ -47,7 +47,7 @@ lxc_log_define(lxc_monitor, lxc);<br>
>  #define UNIX_PATH_MAX 108<br>
>  #endif<br>
><br>
> -static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath)<br>
> +static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath, const char *lxcname)<br>
>  {<br>
>       int fd;<br>
>       struct sockaddr_un addr = { .sun_family = AF_UNIX };<br>
> @@ -59,7 +59,7 @@ static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath)<br>
>        * should we take a hash of lxcpath?  a subset of it?<br>
>        */<br>
>       len = sizeof(addr.sun_path) - 1;<br>
> -     ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);<br>
> +     ret = snprintf(offset, len, "%s/%s-monitor", lxcpath, lxcname);<br>
<br>
</div></div>Note this will further exacerbate the name length issue - addr.sun_path<br>
is 108 bytes, but ${lxc_path}/${lxc_name}-monitor could get pretty long.<br>
<br>
The problem exists in any case, but this would be sure to break any juju<br>
users (which use pretty long container names) immediately.  That doesn't<br>
mean we can't do this, but would mean we'd have to switch to using<br>
something like hash(${lxc_path}/${lxc_name}-monitor) immediately.<br>
<div><div class="h5"><br>
>       if (ret < 0 || ret >= len) {<br>
>               ERROR("lxcpath too long to open monitor");<br>
>               return;<br>
> @@ -82,10 +82,10 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxc<br>
>       strncpy(<a href="http://msg.name" target="_blank">msg.name</a>, name, sizeof(<a href="http://msg.name" target="_blank">msg.name</a>));<br>
>       <a href="http://msg.name" target="_blank">msg.name</a>[sizeof(<a href="http://msg.name" target="_blank">msg.name</a>) - 1] = 0;<br>
><br>
> -     lxc_monitor_send(&msg, lxcpath);<br>
> +     lxc_monitor_send(&msg, lxcpath, name);<br>
>  }<br>
><br>
> -int lxc_monitor_open(const char *lxcpath)<br>
> +int lxc_monitor_open(const char *lxcpath, const char *lxcname)<br>
>  {<br>
>       struct sockaddr_un addr = { .sun_family = AF_UNIX };<br>
>       char *offset = &addr.sun_path[1];<br>
> @@ -97,7 +97,7 @@ int lxc_monitor_open(const char *lxcpath)<br>
>        * should we take a hash of lxcpath?  a subset of it?<br>
>        */<br>
>       len = sizeof(addr.sun_path) - 1;<br>
> -     ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);<br>
> +     ret = snprintf(offset, len, "%s/%s-monitor", lxcpath, lxcname);<br>
>       if (ret < 0 || ret >= len) {<br>
>               ERROR("lxcpath too long to open monitor");<br>
>               return -1;<br>
> diff --git a/src/lxc/state.c b/src/lxc/state.c<br>
> index 3e7e94a..454c02e 100644<br>
> --- a/src/lxc/state.c<br>
> +++ b/src/lxc/state.c<br>
> @@ -201,7 +201,7 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, const<br>
>       if (fillwaitedstates(states, s))<br>
>               return -1;<br>
><br>
> -     fd = lxc_monitor_open(lxcpath);<br>
> +     fd = lxc_monitor_open(lxcpath, lxcname);<br>
>       if (fd < 0)<br>
>               return -1;<br>
><br>
> --<br>
> 1.7.10.4<br>
><br>
><br>
</div></div>> ------------------------------------------------------------------------------<br>
> Precog is a next-generation analytics platform capable of advanced<br>
> analytics on semi-structured data. The platform includes APIs for building<br>
> apps and a phenomenal toolset for data science. Developers can use<br>
> our toolset for easy data analysis & visualization. Get a free account!<br>
> <a href="http://www2.precog.com/precogplatform/slashdotnewsletter" target="_blank">http://www2.precog.com/precogplatform/slashdotnewsletter</a><br>
> _______________________________________________<br>
> Lxc-devel mailing list<br>
> <a href="mailto:Lxc-devel@lists.sourceforge.net">Lxc-devel@lists.sourceforge.net</a><br>
> <a href="https://lists.sourceforge.net/lists/listinfo/lxc-devel" target="_blank">https://lists.sourceforge.net/lists/listinfo/lxc-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>S.Çağlar Onur <<a href="mailto:caglar@10ur.org">caglar@10ur.org</a>>
</div>