This patch rewrites most of the cgroup logic. It creates a set of data
structures to store the kernel state of the cgroup hierarchies and
their mountpoints.
Mainly, everything is now grouped with respect to the hierarchies of
the system. Multiple controllers may be mounted together or separately
to different hierarchies, the data structures reflect this.
Each hierarchy may have multiple mount points (that were created
previously using the bind mount method) and each of these mount points
may point to a different prefix inside the cgroup tree. The current
code does not make any assumptions regarding the mount points, it just
parses /proc/self/mountinfo to acquire the relevant information.
The only requirement is that the current cgroup of either init (if
cgroup.pattern starts with '/' and the tools are executed as root) or
the current process (otherwise) are accessible. The root cgroup need
not be accessible.
The configuration option cgroup.pattern is introduced. For
root-executed containers, it specifies which format the cgroups should
be in. Example values may include '/lxc/%n', 'lxc/%n', '%n' or
'/machine/%n.lxc'. Any occurrence of '%n' is replaced with the name of
the container (and if clashes occur in any hierarchy, -1, -2, etc. are
appended globally). If the pattern starts with /, new containers'
cgroups will be located relative to init's cgroup; if it doesn't, they
will be located relative to the current process's cgroup.
Some changes to the cgroup.h API have been done to make it more
consistent, both with respect to naming and with respect to the
parameters. This causes some changes in other parts of the code that
are included in the patch.
There has been some testing of this functionality, but there are
probably still quite a few bugs in there, especially for people with
different configurations.
Signed-off-by: Christian Seiler <christian@iwakd.de> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Newer glibc versions (that we can't require) allow for an additional
letter 'e' in the fopen mode that will cause the file to be opened with
the O_CLOEXEC flag, so that it will be closed if the program exec()s
away. This is important because if liblxc is used in a multithreaded
program, another thread might want to run a program. This options
prevents the leakage of file descriptors from LXC. This patch adds an
emulation for that that uses the open(2) syscall and fdopen(3). At some
later point in time, it may be dropped against fopen(..., "...e").
This commit also converts all fopen() calls in utils.c (where the
function is added) to fopen_cloexec(). Subsequently, other calls to
fopen() and open() should also be adapted.
Signed-off-by: Christian Seiler <christian@iwakd.de> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
global config: Unify parsing, add additional checks
Instead of duplicating the code for parsing the global config file for
each option, write one main function, lxc_global_config_value, that
does the parsing for an arbitrary option name and just call that
function from the existing ones.
Signed-off-by: Christian Seiler <christian@iwakd.de> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
error.c: don't return error if container init signaled
We log that at INFO level in case it is needed. However, in a modern
kernel a container which was shut down using 'shutdown' will always
have been signaled with SIGINT. Making lxc-start return an error to
reflect that seems overkill.
It's *conceivable* that someone is depending on this behavior, so I'm
sending this out for anyone to NACK, but if I hear no complaints I'll
apply.
Hopefully someone else will come in and spruce it up :) This
version is as simple as can be
lxc-snapshot -n a1
create a snapshot of a1
echo "second commit" > /tmp/a
lxc-snapshot -n a1 -c /tmp/a
create a snapshot of a1 with /tmp/a as a commit comment
lxc-snapshot -n a1 -L
list a1's snapshots
lxc-snapshot -n a1 -L -C
list a1's snapshots along with commit comments
lxc-snapshot -n a1 -r snap0 a2
restore snapshot 0 of a1 as container a2
Some easy nice-to-haves:
1. sort snapshots in the list
2. allow a comment to be given in-line
3. an option to remove a snapshot?
Removing a snapshot can just as well be done with
lxc-destroy -P /var/lib/lxcsnaps/c1 -n snap2
so I leave it to others to decide whether they really want
it, and provide the patch if so.
The api allows for creating, listing, and restoring of container
snapshots. Snapshots are created as snapshot clones of the
original container - i.e. btrfs and lvm will be done as snapshot,
a directory-backed container will have overlayfs snapshots. A
restore is a copy-clone, using the same backing store as the
original container had.
Changelog:
. remove lxcapi_snap_open, which wasn't defined anyway.
. rename get_comment to get_commentpath
. if no newname is specified at restore, use c->name (as we meant to)
rather than segving.
. when choosing a snapshot index, use the correct path to check for.
Natanael Copa [Fri, 6 Sep 2013 07:08:45 +0000 (09:08 +0200)]
lua: fix logic to enable lua support in configure
When there is no --enable-lua or --with-lua-pc, Lua should not be
enabled.
This fixes a bug introduced with 12e93188 (configure/makefile:
Allow specify Lua pkg-config file with --with-lua-pc) that caused
configure script to fail if lua headers was missing.
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Natanael Copa [Thu, 5 Sep 2013 15:13:07 +0000 (17:13 +0200)]
configure/makefile: Allow specify Lua pkg-config file with --with-lua-pc
Enable support for both Lua 5.1 and 5.2 by letting user specify the Lua
pkg-config package name. By default it will use 'lua' and try figure
out which version it is.
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> Acked-by: Stéphane Graber <stgraber@ubuntu.com>
Serge Hallyn [Fri, 14 Jun 2013 03:43:01 +0000 (22:43 -0500)]
introduce lxc.cap.keep
The lxc configuration file currently supports 'lxc.cap.drop', a list of
capabilities to be dropped (using the bounding set) from the container.
The problem with this is that over time new capabilities are added. So
an older container configuration file may, over time, become insecure.
Walter has in the past suggested replacing lxc.cap.drop with
lxc.cap.preserve, which would have the inverse sense - any capabilities
in that set would be kept, any others would be dropped.
Realistically both have the same problem - the sendmail capabilities
bug proved that running code with unexpectedly dropped privilege can be
dangerous. This patch gives the admin a choice: You can use either
lxc.cap.keep or lxc.cap.drop, not both.
Both continue to be ignored if a user namespace is in use.
lxc-commands: add a comment explaining CMD_* rules
We wish to ensure that, henceforth, newer lxc tools are always compatible
with older lxc monitors. Add a comment to commands.c to explain the
rule we wish to enforce to this end.
Serge Hallyn [Thu, 29 Aug 2013 15:41:19 +0000 (10:41 -0500)]
start.c: handle potential signal flood
Signalfd does not guarantee that we'll get an event for every signal.
So if 3 tasks exit at the same time, we may get only one sigchld
event. Therefore, in signal_handler(), always check whether init has
exited. Do with with WNOWAIT so that we can still wait4 to cleanup
the init after lxc_poll() exists (rather than complicating the code).
Note - there is still a race in the kernel which can cause the
container init to become a defunct child of the host init (!). This
doesn't solve that, but is a potential (if very unlikely) race which
apw pointed out while we were trying to create a reproducer for the
kernel bug.
Serge Hallyn [Thu, 22 Aug 2013 15:27:40 +0000 (10:27 -0500)]
api: convert lxc_start
Normal lxc-start usage tends to be "lxc-start -n name [-P lxcpath]".
This causes $lxcpath/$name/config to be the configuration for the
container. However, lxc-start is more flexible than that. You can
specify a custom configuration file, in which case $lxcpath/$name/config
is not used. You can also (in addition or in place of either of these)
specify configuration entries one-by-one using "-s lxc.utsname=xxx".
To support this using the API, if we are not using
$lxcpath/$name/config then we put ourselves into a custom lxcpath
called (configurable using LXCPATH) /var/lib/lxc_anon. To stop a
container so created, then, you would use
lxc-stop -P /var/lib/lxc_anon -n name
TODO: we should walk over the list of &defines by hand and set them
using c->set_config_item. I haven't done that in this patch.
Scott Moser [Thu, 22 Aug 2013 19:38:48 +0000 (15:38 -0400)]
hooks/ubuntu-cloud-prep: add hostname to meta-data
prior to my enabling of the clone hook, the setting of the hostname
was being done by writing to /etc/hostname. Instead of relying on that
we're now writing 'local-hostname' into the metadata for the instance.
cloud-init then reads this and sets the hostname properly.
We are also writing /etc/hostname with the new hostname explicitly. This is
useful/necessary because on network bringup of eth0, dhclient will submit its
hosname. The updating done by cloud-init occurs to late, and thus
the dhcp request goes out with the un-configured hostname and dns doens't
work correctly.
Signed-off-by: Scott Moser <smoser@ubuntu.com> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Serge Hallyn [Wed, 21 Aug 2013 19:43:52 +0000 (14:43 -0500)]
Track snapshot dependencies (v2)
(Will push in a bit barring any objections)
lvm, btrfs, and zfs snapshots each do an ok job of handling deletions
for us - a btrfs snapshot does fine after the original is removed,
while zfs and lvm will both refuse to allow the original to be deleted
while the snapshot exists.
Overlayfs doesn't do this for us. So, for overlayfs snapshots, track
the dependencies.
When c2 is created as an overlayfs snapshot of dir-backed c1, then
1. c2's lxc_rdepends file will contain
c1_lxcpath
c1_lxcname
2. c1's lxc_snapshots will contain "1"
c1 cannot be deleted so long as lxc_snapshots exists and contains
a non-zero number.
The contents of lxc_snapshots and lxc_rdepends are protected by
container_disk_lock() and at lxc_clone by the new container not yet
being accessible.
(Originally I was going to keep them in the container config, but the
problem with using $lxcpath/$name/config is that api users could end up
calling c->save_config() with a cached old value of snapshots/rdepends.)
Changelog:
aug 21: check for fprintf and fclose failures
Scott Moser [Mon, 19 Aug 2013 14:18:37 +0000 (10:18 -0400)]
ubuntu-cloud-prep: improve overlayfs workaround
the previous 'patch_start' can be vastly simplified now that I better
understand what the bug was. Instead of wrapping 'start', we only
need to ensure that /etc/init exists inside the overlayfs, so that the
directory that upstart watches is guaranteed to be in the overlay, not
the underlay.
Christian Seiler [Sun, 18 Aug 2013 22:52:44 +0000 (00:52 +0200)]
python/attach: Add function that returns personality for architecture
Adds the arch_to_personality function that looks up an architecture
and returns the corresponding personality. This may be used in
conjunction with the attach/attach_wait keyword argument.
Signed-off-by: Christian Seiler <christian@iwakd.de> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Scott Moser [Fri, 16 Aug 2013 20:47:32 +0000 (16:47 -0400)]
ubuntu-cloud-prep: patch /sbin/start for overlayfs
upstart depends on inotify, and overlayfs does not support inotify.
That means that the following results in 'tgt' not running. tgt is simply
used here as an example of a service that installs an upstart job and
starts it on package install.
lxc-clone -s -B overlayfs -o source-precise-amd64 -n test1
lxc-start -n test1
..
apt-get install tgt
The change here is to modify /sbin/start inside the container so that when
something explicitly tries 'start', it results in an explicit call to
'initctl reload-configuration' so that upstart is aware of the newly
placed job.
Should overlayfs ever gain inotify support, this should still not cause
any harm.
Signed-off-by: Scott Moser <smoser@ubuntu.com> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Serge Hallyn [Thu, 15 Aug 2013 17:22:26 +0000 (12:22 -0500)]
bdev_create: don't default to btrfs if possible
Ideally it would be great to default to a btrfs subvolume for each new
container created. However, this is not as we previously thought
without consequence. 'rsync --one-file-system' will not descend into
btrfs subvolumes. This means that 'lxc-create -B _unset' will cause
different behavior for rsync -vax /var/lib/lxc based on whether that
fs is btrfs or not.
So don't do that. If -B is not specified, use -B dir.
lxc-fedrora: New patch for systemd detection and init configuration.
Satoshi Matsumoto certainly had the right idea and in spotting a bug in
the lxc-fedora template for systemd detection. Heart was in the right
spot but patch was not what we needed.
I've looked the patch code over for systemd support and init/upstart
support and modified the logic appropriately. If /etc/systemd/system
exists, we'll do the right thing by systemd. If /etc/rc.sysinit exists,
we'll do the right thing by init / upstart. If both are installed,
we'll trying and accommodate both in case someone is playing games with
the two (I've done this).
Patch was trivial, just took more time to actually test it and create
some containers with it and verify them, than it did to code them.
Signed-off-by: Michael H. Warfield <mhw@WittsEnd.com> Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
Christian Seiler [Tue, 13 Aug 2013 21:04:37 +0000 (23:04 +0200)]
attach: implement remaining options of lxc_attach_set_environment
This patch implements the extra_env and extra_keep options of
lxc_attach_set_environment.
The Python implementation, the C container API and the lxc-attach
utility are able to utilize this feature; lxc-attach has gained two new
command line options for this.
Signed-off-by: Christian Seiler <christian@iwakd.de> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
Christian Seiler [Tue, 21 May 2013 12:57:06 +0000 (14:57 +0200)]
python: add attach support
Add methods attach() and attach_wait() to the Python API that give
access to the attach functionality of LXC. Both accept two main
arguments:
1. run: A python function that is executed inside the container
2. payload: (optional) A parameter that will be passed to the python
function
Additionally, the following keyword arguments are supported:
attach_flags: How attach should operate, i.e. whether to attach to
cgroups, whether to drop capabilities, etc. The following
constants are defined as part of the lxc module that may
be OR'd together for this option:
LXC_ATTACH_MOVE_TO_CGROUP
LXC_ATTACH_DROP_CAPABILITIES
LXC_ATTACH_SET_PERSONALITY
LXC_ATTACH_APPARMOR
LXC_ATTACH_REMOUNT_PROC_SYS
LXC_ATTACH_DEFAULT
namespaces: Which namespaces to attach to, as defined as the flags that
may be passed to the clone(2) system call. Note: maybe we
should export these flags too.
personality: The personality of the process, it will be passed to the
personality(2) syscall. Note: maybe we should provide
access to the function that converts arch into
personality.
initial_cwd: The initial working directory after attaching.
uid: The user id after attaching.
gid: The group id after attaching.
env_policy: The environment policy, may be one of:
LXC_ATTACH_KEEP_ENV
LXC_ATTACH_CLEAR_ENV
extra_env_vars: A list (or tuple) of environment variables (in the form
KEY=VALUE) that should be set once attach has
succeeded.
extra_keep_env: A list (or tuple) of names of environment variables
that should be kept regardless of policy.
stdin: A file/socket/... object that should be used as stdin for the
attached process. (If not a standard Python object, it has to
implemented the fileno() method and provide a fd as the result.)
stdout, stderr: See stdin.
attach() returns the PID of the attached process, or -1 on failure.
attach_wait() returns the return code of the attached process after
that has finished executing, or -1 on failure. Note that if the exit
status of the process is 255, -1 will also be returned, since attach
failures result in an exit code of 255.
Two default run functions are also provided in the lxc module:
attach_run_command: Runs the specified command
attach_run_shell: Runs a shell in the container
Examples (assumeing c is a Container object):
c.attach_wait(lxc.attach_run_command, 'id')
c.attach_wait(lxc.attach_run_shell)
def foo():
print("Hello World")
# the following line is important, otherwise the exit code of
# the attached program will be -1
# sys.exit(0) will also work
return 0
c.attach_wait(foo)
c.attach_wait(lxc.attach_run_command, ['cat', '/proc/self/cgroup'])
c.attach_wait(lxc.attach_run_command, ['cat', '/proc/self/cgroup'],
attach_flags=(lxc.LXC_ATTACH_DEFAULT &
~lxc.LXC_ATTACH_MOVE_TO_CGROUP))
Note that while it is possible to execute Python code inside the
container by passing a function (see example), it is unwise to import
modules, since there is no guarantee that the Python installation
inside the container is in any way compatible with that outside of it.
If you want to run Python code directly, please import all modules
before attaching and only use them within the container.
Signed-off-by: Christian Seiler <christian@iwakd.de> Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>