[lxc-devel] [PATCH] [RFC] Complete rewrite of lxc-attach functionality
Christian Seiler
christian at iwakd.de
Mon May 20 15:54:19 UTC 2013
Hi,
as discussed previously on this list, I've reimplemented the lxc-attach
functionality as an API function. The patchset consists of two parts:
1. Four minor patches that just fix some bugs, shuffle definitions
around and implement some small utility functions that I need for
the attach functionality, but which also may be useful generally.
These patches are trivial and I've signed off on them, I don't see
any reason not for applying them anyway.
2. One major patch that actually reimplements the lxc-attach
functionality in form of a function lxc_attach(). Since I want some
feedback here, I haven't added the Signed-off-by tag to the commit
message yet and I don't think it's quite ready to be committed yet.
Rationale behind the design of the new functionality:
- We have a ton of knobs one could want to do while attaching, my idea
was to give the API user the largest possible control over all of these
knobs. But since I didn't want to run into the trap of creating a
function that accepts 100 parameters, I thought the best idea would
be to have a structure (lxc_attach_options_t) where one specifies
precisely all of the options and just passes this structure to the
function. This way, lxc_attach only has 4 parameters and is called
like this:
ret = lxc_attach(container_name, lxcpath, &options_struct, &pid);
- In 0.9, we have a three-process hierarchy:
lxc-attach
+- lxc-attach [does setns() before spawning further]
+- attached process
This is due to user namespaces. The patch introduces a flat
hierarchy thanks to CLONE_PARENT:
lxc-attach
+- lxc-attach [does setns(), dies after creating next process]
+- attached process
That way, once attach is complete, there are two proceses running:
lxc-attach (supervising) and the attached process itself.
- In order to be able to do attach safely from a threaded program, we
have to make sure that all fds (including ipc sockets) that we open
do not conflict with other threads. For this reason, I use O_CLOEXEC
for all fds. That way, if another thread fork()s off while an attach
is in progress, as soon as that other process exec()s, the fd will
be closed and thus not leak. However, if a process that has been
forked from another thread does not exec(), then we run into the
problem that the process calling attach usually notices that error
by means of detecting that the IPC socket was closed unexpectedly.
Since another process that forked away at the wrong time from a
diffrerent thread may still hold an open fd of the child process's
socket, the child will call shutdown() on its socket before closing
it in order to make sure the parent still notices the end of the
socket. [1]
The functionality itself is tested, lxc-attach still works the same as
before.
Now for the part that I don't like about my current implementation: Once
I was done with adding the lxc_attach() function, I wanted to update the
"general purpose" LXC API, including Python bindings etc.. But for this
I would also have to have the struct lxc_attach_options_t in lxc_attach,
which would mean including attach.h from lxccontainer.h. But attach.h
contains all sorts of very low-level functions and lxccontainer.h is
supposed to be a high-level API.
Now I'm not quite sure what to do:
a) Add a really dumbed-down high-level API function that just accepts
the name of a program to start. (Kind of defeats the purpose of
having the container API.)
b) Really do include attach.h from lxccontainer.h (which currently
does not include any other lxc header!)
c) Move lxc_attach_options_t from attach.h to lxccontainer.h, include
lxccontainer.h from attach.h, add a function with the respective
signature to the container API and let that call lxc_attach()
internally. (My current favorite.)
d) Something else?
Thoughts? On this specific issue and also on the general
implementation?
-- Christian
[1] Note that this is still not safe from an interruption by a signal,
I will provide a separate patch that addresses that once the main
functionality has been merged into staging.
More information about the lxc-devel
mailing list