[lxc-devel] [PATCH] Use container specific domain socket name

Serge Hallyn serge.hallyn at ubuntu.com
Tue Apr 9 12:47:38 UTC 2013


Quoting S.Çağlar Onur (caglar at 10ur.org):
> From: "S.Çağlar Onur" <caglar at 10ur.org>
> 
> Otherwise trying to start N containers in parallel gives "lxc_container: bind : Address already in use" error.
> 
> 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.
> 
> ----
> import lxc
> 
> from queue import Empty
> from multiprocessing import Process, Queue
> 
> def create(q):
>     while True:
>         try:
>             x = q.get(block=False)
>             c = lxc.Container(str(x))
>             print("Starting", x)
>             c.start()
>         except Empty:
>             break
> 
> if __name__=="__main__":
>     work_queue = Queue()
>     for i in range(11):
>         work_queue.put(i)
> 
>     process = [Process(target=create, args=(work_queue,)) for i in range(4)]
>     for p in process:
>         p.start()
> 
>     for p in process:
>         p.join()
> ----
> 
> caglar at qgq:~/Project$ sudo python3 cstart.py
> Starting 0
> Starting 1
> lxc_container: bind : Address already in use
> Starting 3
> Starting 4
> Starting 2
> lxc_container: lxc_container: bind : Address already in use
> bind : Address already in uselxc_container: bind : Address already in use
> 
> Starting 5
> Starting 6
> lxc_container: bind : Address already in use
> lxc_container: bind : Address already in use
> Starting 7
> Starting 8
> Starting 9
> lxc_container: bind : Address already in use
> lxc_container: bind : Address already in use
> lxc_container: bind : Address already in use
> Starting 10
> lxc_container: bind : Address already in use
> 
> Signed-off-by: S.Çağlar Onur <caglar at 10ur.org>

Hi,

Thanks.  This is definately something we want to address.  However,
what do here only partially solves it.  I'm not completely against
it as it helps a useful case.

Daniel has said (at least physical UDS) that he wanted to improve the
monitor code to allow multiple simultaneous connections.  That would
solve your problem as well as the more general problem of supporting
multiple simulatanous lxc-wait and lxc-monitors, which yours does not
solve.

Daniel, can you lay out here how you were planning to do that?  Have you
had any time - or will you have any time soon - to start that?

In any case I'd prefer is if we kept lxc_name before lxc_path in arg list.

> ---
>  src/lxc/lxc.h         |    2 +-
>  src/lxc/lxc_monitor.c |    2 +-
>  src/lxc/monitor.c     |   10 +++++-----
>  src/lxc/state.c       |    2 +-
>  4 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/src/lxc/lxc.h b/src/lxc/lxc.h
> index db921f0..224d460 100644
> --- a/src/lxc/lxc.h
> +++ b/src/lxc/lxc.h
> @@ -74,7 +74,7 @@ extern int lxc_execute(const char *name, char *const argv[], int quiet,
>   * The function will return an fd corresponding to the events
>   * Returns a file descriptor on success, < 0 otherwise
>   */
> -extern int lxc_monitor_open(const char *lxcpath);
> +extern int lxc_monitor_open(const char *lxcpath, const char *lxcname);
>  
>  /*
>   * Read the state of the container if this one has changed
> diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
> index 0530373..4898377 100644
> --- a/src/lxc/lxc_monitor.c
> +++ b/src/lxc/lxc_monitor.c
> @@ -87,7 +87,7 @@ int main(int argc, char *argv[])
>  		return -1;
>  	}
>  
> -	fd = lxc_monitor_open(my_args.lxcpath);
> +	fd = lxc_monitor_open(my_args.lxcpath, my_args.name);
>  	if (fd < 0)
>  		return -1;
>  
> diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c
> index afdaf67..2590559 100644
> --- a/src/lxc/monitor.c
> +++ b/src/lxc/monitor.c
> @@ -47,7 +47,7 @@ lxc_log_define(lxc_monitor, lxc);
>  #define UNIX_PATH_MAX 108
>  #endif
>  
> -static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath)
> +static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath, const char *lxcname)
>  {
>  	int fd;
>  	struct sockaddr_un addr = { .sun_family = AF_UNIX };
> @@ -59,7 +59,7 @@ static void lxc_monitor_send(struct lxc_msg *msg, const char *lxcpath)
>  	 * should we take a hash of lxcpath?  a subset of it?
>  	 */
>  	len = sizeof(addr.sun_path) - 1;
> -	ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);
> +	ret = snprintf(offset, len, "%s/%s-monitor", lxcpath, lxcname);

Note this will further exacerbate the name length issue - addr.sun_path
is 108 bytes, but ${lxc_path}/${lxc_name}-monitor could get pretty long.

The problem exists in any case, but this would be sure to break any juju
users (which use pretty long container names) immediately.  That doesn't
mean we can't do this, but would mean we'd have to switch to using
something like hash(${lxc_path}/${lxc_name}-monitor) immediately.

>  	if (ret < 0 || ret >= len) {
>  		ERROR("lxcpath too long to open monitor");
>  		return;
> @@ -82,10 +82,10 @@ void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxc
>  	strncpy(msg.name, name, sizeof(msg.name));
>  	msg.name[sizeof(msg.name) - 1] = 0;
>  
> -	lxc_monitor_send(&msg, lxcpath);
> +	lxc_monitor_send(&msg, lxcpath, name);
>  }
>  
> -int lxc_monitor_open(const char *lxcpath)
> +int lxc_monitor_open(const char *lxcpath, const char *lxcname)
>  {
>  	struct sockaddr_un addr = { .sun_family = AF_UNIX };
>  	char *offset = &addr.sun_path[1];
> @@ -97,7 +97,7 @@ int lxc_monitor_open(const char *lxcpath)
>  	 * should we take a hash of lxcpath?  a subset of it?
>  	 */
>  	len = sizeof(addr.sun_path) - 1;
> -	ret = snprintf(offset, len, "%s/lxc-monitor", lxcpath);
> +	ret = snprintf(offset, len, "%s/%s-monitor", lxcpath, lxcname);
>  	if (ret < 0 || ret >= len) {
>  		ERROR("lxcpath too long to open monitor");
>  		return -1;
> diff --git a/src/lxc/state.c b/src/lxc/state.c
> index 3e7e94a..454c02e 100644
> --- a/src/lxc/state.c
> +++ b/src/lxc/state.c
> @@ -201,7 +201,7 @@ extern int lxc_wait(const char *lxcname, const char *states, int timeout, const
>  	if (fillwaitedstates(states, s))
>  		return -1;
>  
> -	fd = lxc_monitor_open(lxcpath);
> +	fd = lxc_monitor_open(lxcpath, lxcname);
>  	if (fd < 0)
>  		return -1;
>  
> -- 
> 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 at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel




More information about the lxc-devel mailing list