[systemd-devel] [PATCH 1/2] nspawn: --populate to run static binaries on empty target directory

Lennart Poettering lennart at poettering.net
Tue Dec 10 14:18:42 PST 2013


On Mon, 02.12.13 09:41, Shawn Landden (shawn at churchofgit.com) wrote:

> 
> On Mon, Dec 2, 2013 at 8:27 AM, Lennart Poettering
> <lennart at poettering.net> wrote:
> > On Sat, 30.11.13 10:20, Shawn Landden (shawn at churchofgit.com) wrote:
> >
> >> nspawn has been called "chroot on steroids".
> >>
> >> Continue that tradition by supporting target directories that
> >> are not root directories.
> >>
> >> This patch handles the simple case: a static binary.
> >
> > Hmm, I am not sure how I feel about this. This appears a bit too
> > specific for me, and given the requirement for static binaries this is
> > also so limited.
> The next patch is the series adds support for dynamic libraries. This patch
> also doesn't need bind mounts, and it executes through /proc/self/fd/%n, but
> support for one-file scripts and dynamic libraries in the next patch does
> require bind mounts. I feel you don't really understand my patch. :/
> I'll sum up what I'm doing:
> 
> If --populate is passed, analyze the executable, which opens it and set the
> exec path to /proc/self/fd/%n. If executable is static this is all you
> have to do.
> 
> If it has a shebang, analyze that. If either the shebang or executable
> is dynamic,
> test if the linker is the GNU linker, and if it is have the linker
> tell use what libraries the
> executable needs. Then bind mount the linker, shebang (if there is one), and
> libraries into the target.

But somethinglike this will never fully work, because there are so many
other kinds of deps that are not visible from ELF. It starts with
dynamically loadable modules (for example NSS is like that, and it gets
really awkward if you program from the host ends up linking against a
NSS module from the container...), but actually touches any other
resource the program might need, for example, external files in
/usr/shares and whatnot. You can never make this work correctly. 

Dracut has a logic for this to find what is necessary to pull into the
initrd. It works for the initrd, because that's a relatively well
defined environment, but I am very conservative on providing something
in nspawn that is supposed to work for the general case.

Maybe an alternative solution could be to generalize the bits in dracut
(we already use those outside of dracut in the test stuff of systemd
where we build a qemu image from the host OS to boot), and add something
to it that is capable of spitting out a list of "--bind" command line
arguments that you can include in the nspawn command line? Something
like this

$ systemd-nspawn -D /srv/my/container `dracut-collect --nspawn /home/lennart/xyz /tmp/xyz` /tmp/xyz

The hypothetical dracut-coollect tool would find all deps of
/home/lennart/xyz, output "--bind" switches for mounting them into the
container and finally output one --bind that mounts /home/lennart/xyz to
/tmp/xyz in the container. The latter we then execute as binary. 

This way we could make use of the more advanceed logic in dracut, and
wouldn't pretend in nspawn we could make this work for the general
case...

> > This of course wouldn't check if the file executed is staticall linked,
> > but the user should quickly get an error about missing .sos if it isn't?
> No, the linker would be missing, and the user would get "execvpe()
> failed: No such file or directory",

Which is an OK mesage I'd claim.

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list