[lxc-devel] Getting complex data (structs) from a container (net ns) in API

Christian Brauner christian.brauner at ubuntu.com
Thu Feb 8 13:59:43 UTC 2018


Hi Rafał,

Sorry for the late reply.

On Fri, Jan 19, 2018 at 04:22:03PM +0100, Rafał Miłecki wrote:
> Hi,
> 
> currently lxccontainer's API has two functions for getting net info:
> char** (*get_interfaces)(struct lxc_container *c);
> char** (*get_ips)(struct lxc_container *c, const char* interface, const
> char* family, int scope);
> 
> I'd like to get more detailed info about container's interfaces like a
> list of interfaces with IPs (and maybe MAC) for each of them. Let's say:
> 
> struct lxc_interface {
> 	struct lxc_interface *next;
> 	const char name[IFNAMSIZ];
> 	uint8_t mac_addr[ETH_ALEN];
> 	char **ips;
> };
> 
> struct lxc_interface *(*get_interfaces_info)(struct lxc_container *c);

So this would be an API extension which would need some proper thinking
to make it supportable long term. The last thing I want to do right now
is introduce something whose interface we regret in a few months. But we
plan on doing some substantial API (re)work after LXC 3.0 has been
released and this could fit in there nicely. The main thing is that we
would need to discuss it amongst the maintainers and a bunch of people
that have made significant contributions to LXC. So I suggest you open
an issue against the LXC repo with your ideas and suggestions.

> 
> The problem is passing data between net's namespace (container) and a
> host. IPs and interface names are passed using a pipe as their format is
> quite trivial. Passing a whole struct is a bigger problem that I don't
> know how to handle.
> 
> 1) Passing struct over a pipe would require some serialization tricks.

Serialization wouldn'be such a big issue but we wouldn't use a pipe for
that. An obvious candidate for such work is a socket(). You can see how
I've done it for lxc_ls.c. I've also recently pushed some kernel patches
that allow you to retrieve information about network interfaces without
attaching to the network (and owning user) namespace of the container
which means you don't have to fork().

> 
> 2) Shared memory could be used while fork()ing (e.g. mmap or shmget) but
> not trivial, because shared memory can't be dynamically reallocated as
> needed for building a list of interfaces in a child process.

Another option is to use the clone syscall with CLONE_VM at which point
child and parent share the same virtual memory so memory mappings you
perform in the child will be visible in the parent and the other way
around. This way you could set up the mapping in the child and the
parent can later access it once the child has exited.

> 
> 3) Threads aren't currently used by LXC tools, so I'm not sure if they
> are acceptable.

Hm, that's not really needed I think.

> 
> These are the only ideas I got.

Well, they were good ones. :)

Thanks!
Christian


More information about the lxc-devel mailing list