Commit 89db34e7 by Daniel Lezcano
parents 56655134 83c98d82
......@@ -24,6 +24,7 @@ libtool
lxc.spec
lxc.pc
templates/lxc-alpine
templates/lxc-altlinux
templates/lxc-archlinux
templates/lxc-busybox
......@@ -54,8 +55,6 @@ src/lxc/lxc-monitor
src/lxc/lxc-netstat
src/lxc/lxc-ps
src/lxc/lxc-restart
src/lxc/lxc-setcap
src/lxc/lxc-setuid
src/lxc/lxc-shutdown
src/lxc/lxc-start
src/lxc/lxc-start-ephemeral
......
......@@ -5,6 +5,15 @@ ACLOCAL_AMFLAGS = -I config
SUBDIRS = config src templates doc
DIST_SUBDIRS = config src templates doc
EXTRA_DIST = autogen.sh lxc.spec CONTRIBUTING MAINTAINERS ChangeLog
RPMARGS =
if ENABLE_LUA
RPMARGS += --with lua
endif
if ENABLE_PYTHON
RPMARGS += --with python
endif
pcdatadir = $(libdir)/pkgconfig
pcdata_DATA = lxc.pc
......@@ -17,4 +26,4 @@ ChangeLog::
@touch ChangeLog
rpm: dist
rpmbuild --clean -ta ${distdir}.tar.gz
rpmbuild --clean -ta ${distdir}.tar.gz $(RPMARGS)
......@@ -36,7 +36,7 @@ Downloading the current source code:
For detailed build instruction refer to INSTALL and man lxc man page
but a short command line should work:
./autogen.sh && ./configure && make && sudo make install && sudo lxc-setcap
./autogen.sh && ./configure && make && sudo make install
preceded by ./autogen.sh if configure do not exist yet.
Getting help:
......
configdir = $(sysconfdir)/lxc
config_DATA = lxc.conf
conffile = @LXC_CONFFILE@
config_DATA = default.conf
defaultconf = @LXC_DEFAULT_CONF@
EXTRA_DIST = lxc.conf.ubuntu lxc.conf.libvirt lxc.conf.unknown
EXTRA_DIST = default.conf.ubuntu default.conf.libvirt default.conf.unknown
lxc.conf:
cp $(conffile) $@
default.conf:
cp $(defaultconf) $@
clean-local:
@$(RM) -f lxc.conf
@$(RM) -f default.conf
distclean-local:
@$(RM) -f lxc.conf
@$(RM) -f default.conf
@$(RM) -f compile config.guess config.sub depcomp install-sh ltmain.sh missing Makefile.in Makefile
......@@ -7,33 +7,46 @@ EXTRA_DIST = \
if ENABLE_DOCBOOK
man_MANS = \
lxc-attach.1 \
lxc-cgroup.1 \
lxc-checkconfig.1 \
lxc-checkpoint.1 \
lxc-clone.1 \
lxc-console.1 \
lxc-create.1 \
lxc-destroy.1 \
lxc-execute.1 \
lxc-freeze.1 \
lxc-info.1 \
lxc-kill.1 \
lxc-monitor.1 \
lxc-netstat.1 \
lxc-ps.1 \
lxc-restart.1 \
lxc-shutdown.1 \
lxc-start.1 \
lxc-stop.1 \
lxc-checkpoint.1 \
lxc-restart.1 \
lxc-console.1 \
lxc-freeze.1 \
lxc-unfreeze.1 \
lxc-monitor.1 \
lxc-unshare.1 \
lxc-version.1 \
lxc-wait.1 \
lxc-ps.1 \
lxc-cgroup.1 \
lxc-kill.1 \
lxc-attach.1 \
\
lxc.conf.5 \
\
lxc.7
if ENABLE_PYTHON
man_MANS += lxc-device.1
man_MANS += lxc-ls.1
man_MANS += lxc-start-ephemeral.1
else
man_MANS += legacy/lxc-ls.1
endif
if ENABLE_LUA
man_MANS += lxc-top.1
endif
%.1 : %.sgml
$(db2xman) $<
test "$(shell basename $@)" != "$@" && mv $(shell basename $@) $@ || true
......
<!--
(C) Copyright Canonical Ltd. 2013
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-checkconfig</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-checkconfig</refname>
<refpurpose>
check the current kernel for lxc support
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-checkconfig</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-checkconfig</command> check the current kernel for
lxc support
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-checkconfig</term>
<listitem>
<para>
check the current kernel.
CONFIG can be set in the environment to an alternate location.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
<!--
lxc: linux Container library
(C) Copyright IBM Corp. 2007, 2008
Authors:
Daniel Lezcano <dlezcano at fr.ibm.com>
Serge Hallyn <serge.hallyn at ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY commonoptions SYSTEM "@builddir@/common_options.sgml">
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-clone</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-clone</refname>
<refpurpose>
clone a new container from an existing one.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-clone</command>
<arg choice="req">-o <replaceable>orig</replaceable></arg>
<arg choice="req">-n <replaceable>new</replaceable></arg>
<arg choice="opt">-s </arg>
<arg choice="opt">-L <replaceable>fssize</replaceable></arg>
<arg choice="opt">-v <replaceable>vgname</replaceable></arg>
<arg choice="opt">-p <replaceable>lxc_lv_prefix</replaceable></arg>
<arg choice="opt">-t <replaceable>fstype</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-clone</command> Creates a new container as a copy of an existing
container. When the original container's rootfs is an LVM block device or
is on a btrfs filesystem, then a snapshotted clone can be created, taking up
very little initial disk space.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option>-o, --orig <replaceable>orig</replaceable></option>
</term>
<listitem>
<para>
The name of the original container to clone.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-n, --new <replaceable>new</replaceable></option>
</term>
<listitem>
<para>
The name of the new container to create.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-s, --snapshot</option>
</term>
<listitem>
<para>
The new container's rootfs should be a LVM or btrfs snapshot of the original.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-L, --fssize <replaceable>fssize</replaceable></option>
</term>
<listitem>
<para>
In the case of a LVM-backed container, a size for the new
block device. By default, the new device will be made the
same size as the original.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-v, --vgname <replaceable>vgname</replaceable></option>
</term>
<listitem>
<para>
For an LVM-backed container, the volume group name to use. By
default it is 'lxc'.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-p, --lvprefix <replaceable>lxc_lv_prefix</replaceable></option>
</term>
<listitem>
<para>
For an LVM-backed container, a string to prefix to the container name to
form the logical volume name. For instance, specifying
<command>-n c1 -p lxc_</command> will cause the container rootfs to
be on a logical volume called <replaceable>lxc_c1</replaceable>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-t, --fstype <replaceable>fstype</replaceable></option>
</term>
<listitem>
<para>
For a non-snapshot LVM clone, the file system to use for the new
container. Note this option is ignored when requesting a
snapshotted container.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Serge Hallyn <email>serge.hallyn@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
......@@ -50,6 +50,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<cmdsynopsis>
<command>lxc-console</command>
<arg choice="req">-n <replaceable>name</replaceable></arg>
<arg choice="opt">-e <replaceable>escape character</replaceable></arg>
<arg choice="opt">-t <replaceable>ttynum</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
......@@ -66,8 +67,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<para>
The available tty are free slots taken by this command. That
means if the container has four ttys available and the command
has been launched four times taking the different tty, the fifth
command will fail because no console will be available.
has been launched four times each taking a different tty, the
fifth command will fail because no console will be available.
</para>
<para>
......@@ -76,6 +77,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
the state it was before the disconnection.
</para>
<para>
A keyboard escape sequence may be used to disconnect from the tty
and quit lxc-console. The default escape sequence is &lt;Ctrl+a q&gt;.
</para>
</refsect1>
<refsect1>
......@@ -84,6 +90,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<varlistentry>
<term>
<option>-e <optional><replaceable>escape character</replaceable></optional></option>
</term>
<listitem>
<para>
Specify the escape sequence prefix to use instead of
&lt;Ctrl a&gt;.
This may be given as '^letter' or just 'letter'. For example
to use &lt;Ctrl+b q&gt; as the escape sequence use -e '^b'.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-t <optional><replaceable>ttynum</replaceable></optional></option>
</term>
<listitem>
......
<!--
(C) Copyright Canonical Ltd. 2013
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-device</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-device</refname>
<refpurpose>
manage deices of running containers
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-device</command>
<arg choice="opt">-h</arg>
<arg choice="opt">-n <replaceable>name</replaceable></arg>
<arg choice="opt">add</arg>
<arg choice="opt">DEVICE</arg>
<arg choice="opt">NAME</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-device</command> manages devices in running container.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option><optional>-h</optional></option>
</term>
<listitem>
<para>
The full command help message.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-n</option>
</term>
<listitem>
<para>
The name of the target container.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>action</option>
</term>
<listitem>
<para>
What action to perform. Only 'add' is supported at this point.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>DEVICE</option>
</term>
<listitem>
<para>
The device to add to the container.
It can either be the path to a device under /dev or a network
interface name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>NAME</optional></option>
</term>
<listitem>
<para>
Name for the device within the container.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-device -n p1 add /dev/video0</term>
<listitem>
<para>
Creates a /dev/video0 device in container p1 based on the matching
device on the host.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-device -n p1 add eth0 eth1</term>
<listitem>
<para>
Moves eth0 from the host as eth1 in p1.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
<!--
(C) Copyright Canonical Ltd. 2013
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY commonoptions SYSTEM "@builddir@/common_options.sgml">
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-info</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-info</refname>
<refpurpose>
query information about a container
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-info</command>
<arg choice="req">-n <replaceable>name</replaceable></arg>
<arg choice="req">-s</arg>
<arg choice="req">-p</arg>
<arg choice="req">-t <replaceable>state</replaceable></arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-info</command> queries and shows information about a
container.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option>-n <replaceable>name</replaceable></option>
</term>
<listitem>
<para>
The container name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-s</optional></option>
</term>
<listitem>
<para>
Just print the container's state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-p</optional></option>
</term>
<listitem>
<para>
Just print the container's pid.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-t <replaceable>state</replaceable></optional></option>
</term>
<listitem>
<para>
Check whether the container is in the provided state.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&commonoptions;
<refsect1>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-info -n foo</term>
<listitem>
<para>
Show information for foo.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-info -n foo -t RUNNING</term>
<listitem>
<para>
exits 0 if foo is RUNNING, 1 otherwise.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
......@@ -197,6 +197,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
......
<!--
(C) Copyright Canonical Ltd. 2013
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-netstat</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-netstat</refname>
<refpurpose>
run netstat for the specified container
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-netstat</command>
<arg choice="opt">--name <replaceable>name</replaceable></arg>
<arg choice="opt">-- netstat option</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-netstat</command> is a wrapper to the netstat command.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option>-n, --name <replaceable>name</replaceable></option>
</term>
<listitem>
<para>
The container name.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>netstat options</optional></option>
</term>
<listitem>
<para>
The <command>netstat</command> options must be separated
from <command>lxc-netstat</command> options by
the <option>--</option> parameter.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Example</title>
<variablelist>
<varlistentry>
<term>lxc-netstat --name foo -- -lnp</term>
<listitem>
<para>
Call netstat -lnp for container foo.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<citerefentry>
<refentrytitle>netstat</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
</simpara>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
......@@ -58,7 +58,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<refsect1>
<title>Description</title>
<para>
<command>lxc-ps</command> is a wrapper tp ps command
<command>lxc-ps</command> is a wrapper to the ps command
to report the name of lxc container associated
to reported processes.
</para>
......
<!--
(C) Copyright Canonical Ltd. 2013
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-start-ephemeral</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-start-ephemeral</refname>
<refpurpose>
start an ephemeral copy of an existing container
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-start-ephemeral</command>
<arg choice="opt">-o</arg>
<arg choice="opt">-n</arg>
<arg choice="opt">-d</arg>
<arg choice="opt">--bdir</arg>
<arg choice="opt">--user</arg>
<arg choice="opt">--key</arg>
<arg choice="opt">--union-type</arg>
<arg choice="opt">--keep-data</arg>
<arg choice="opt">COMMAND</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-start-ephemeral</command> start an ephemeral copy of an
existing container.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option>-o</option>
</term>
<listitem>
<para>
Original container name
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-n</optional></option>
</term>
<listitem>
<para>
Name of the ephemeral container (defaults to a random suffix).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-d</optional></option>
</term>
<listitem>
<para>
Start the container in background and print the name and IP.
This option can't be used if a command is passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>--bdir</optional></option>
</term>
<listitem>
<para>
Directory to bind mount into container.
Can be passed multiple times.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>--user</optional></option>
</term>
<listitem>
<para>
The user to connect to the container as.
Used when passing a command to lxc-start-ephemeral.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>--key</optional></option>
</term>
<listitem>
<para>
Copy the provided SSH public key into the container.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>--union-type</optional></option>
</term>
<listitem>
<para>
Force a specific union file system.
Can be one of: overlayfs aufs
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>--keep-data</optional></option>
</term>
<listitem>
<para>
Use a persistent backend instead of tmpfs.
With this option, you can lxc-stop and lxc-start the no longer so
ephemeral container (it's still an overlay, but a persistent one).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>COMMAND</optional></option>
</term>
<listitem>
<para>
Immediately run the provided command in the container.
This currently uses ssh (not attach) and is incompatible
with daemon mode.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>See Also</title>
<simpara>
<citerefentry>
<refentrytitle>lxc-start</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>,
</simpara>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-start-ephemeral -o p1</term>
<listitem>
<para>
Simply start an ephemeral container and attach to the console.
This container will be based on existing container "p1".
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>lxc-start-ephemeral -o p1 -n p1-ephemeral -d</term>
<listitem>
<para>
Start an ephemeral container based on p1 called p1-ephemeral and
print its IP and name to the console instead of attaching.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
......@@ -51,7 +51,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<command>lxc-start</command>
<arg choice="req">-n <replaceable>name</replaceable></arg>
<arg choice="opt">-f <replaceable>config_file</replaceable></arg>
<arg choice="opt">-c <replaceable>console_file</replaceable></arg>
<arg choice="opt">-c <replaceable>console_device</replaceable></arg>
<arg choice="opt">-L <replaceable>console_logfile</replaceable></arg>
<arg choice="opt">-d</arg>
<arg choice="opt">-p <replaceable>pid_file</replaceable></arg>
<arg choice="opt">-s KEY=VAL</arg>
......@@ -76,11 +77,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
defined, the default isolation is used.
</para>
<para>
The orphan process group
and daemon are not supported by this command, use
the <command>lxc-execute</command> command instead.
</para>
<para>
If no command is specified, <command>lxc-start</command> will
use the default
<command>"/sbin/init"</command> command to run a system
......@@ -139,13 +135,25 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<varlistentry>
<term>
<option>-c,
--console <replaceable>console_file</replaceable></option>
--console <replaceable>console_device</replaceable></option>
</term>
<listitem>
<para>
Specify a device to use for the container's console, for example
/dev/tty8. If this option is not specified the current terminal
will be used unless <option>-d</option> is specified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-L,
--console-log <replaceable>console_logfile</replaceable></option>
</term>
<listitem>
<para>
Specify a file to output the container console. If the
option is not specified the output will go the terminal
except if the <option>-d</option> is specified.
Specify a file to log the container's console output to.
</para>
</listitem>
</varlistentry>
......
<!--
Copyright © 2012 Oracle.
Authors:
Dwight Engen <dwight.engen@oracle.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-top</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-top</refname>
<refpurpose>
monitor container statistics
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-top</command>
<arg choice="opt">--help</arg>
<arg choice="opt">--max <replaceable>count</replaceable></arg>
<arg choice="opt">--delay <replaceable>delay</replaceable></arg>
<arg choice="opt">--sort <replaceable>sortby</replaceable></arg>
<arg choice="opt">--reverse</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-top</command> displays container statistics. The output
is updated every <replaceable>delay</replaceable> seconds, and is
ordered according to the <replaceable>sortby</replaceable> value
given. Specifying <replaceable>count</replaceable> will limit the
number of containers displayed, otherwise <command>lxc-top</command>
will display as many containers as can fit in your terminal.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option><optional>-m, --max <replaceable>count</replaceable></optional></option>
</term>
<listitem>
<para>
Limit the number of containers displayed to
<replaceable>count</replaceable>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-d, --delay <replaceable>delay</replaceable></optional></option>
</term>
<listitem>
<para>
Amount of time in seconds to delay between screen updates.
This can be specified as less than a second by giving a
rational number, for example 0.5 for a half second delay. The
default is 3 seconds.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-s, --sort <replaceable>sortby</replaceable></optional></option>
</term>
<listitem>
<para>
Sort the containers by name, cpu use, or memory use. The
<replaceable>sortby</replaceable> argument should be one of
the letters n,c,d,m to sort by name, cpu use, disk I/O, or
memory use respectively. The default is 'n'.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option><optional>-r, --reverse</optional></option>
</term>
<listitem>
<para>
Reverse the default sort order. By default, names sort in
ascending alphabetical order and values sort in descending
amounts (ie. largest value first).
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Example</title>
<variablelist>
<varlistentry>
<term>lxc-top --delay 1 --sort m</term>
<listitem>
<para>
Display containers, updating every second, sorted by memory use.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Dwight Engen <email>dwight.engen@oracle.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
<!--
lxc: linux Container library
(C) Copyright IBM Corp. 2007, 2008
Authors:
Daniel Lezcano <dlezcano at fr.ibm.com>
Serge Hallyn <serge.hallyn at ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY commonoptions SYSTEM "@builddir@/common_options.sgml">
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-unshare</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-unshare</refname>
<refpurpose>
Run a task in a new set of namespaces.
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-clone</command>
<arg choice="req">-s <replaceable>namespaces</replaceable></arg>
<arg choice="req">-u <replaceable>user</replaceable></arg>
<arg choice="req">command</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-unshare</command> can be used to run a task in a cloned set
of namespaces. This command is mainly provided for testing purposes.
Despite its name, it always uses clone rather than unshare to create
the new task with fresh namespaces. Apart from testing kernel
regressions this should make no difference.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<variablelist>
<varlistentry>
<term>
<option>-s <replaceable>namespaces</replaceable></option>
</term>
<listitem>
<para>
Specify the namespaces to attach to, as a pipe-separated list,
e.g. <replaceable>NETWORK|IPC</replaceable>. Allowed values are
<replaceable>MOUNT</replaceable>, <replaceable>PID</replaceable>,
<replaceable>UTSNAME</replaceable>, <replaceable>IPC</replaceable>,
<replaceable>USER </replaceable> and
<replaceable>NETWORK</replaceable>. This allows one to change
the context of the process to e.g. the network namespace of the
container while retaining the other namespaces as those of the
host.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-u <replaceable>user</replaceable></option>
</term>
<listitem>
<para>
Specify a user which the new task should become. This option is
only valid if a user namespace is unshared.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
To spawn a new shell with its own UTS (hostname) namespace,
<programlisting>
lxc-clone -s UTSNAME /bin/bash
</programlisting>
If the hostname is changed in that shell, the change will not be
reflected on the host.
</para>
<para>
To spawn a shell in a new network, pid, and mount namespace,
<programlisting>
lxc-clone -s "NETWORK|PID|MOUNT" /bin/bash
</programlisting>
The resulting shell will have pid 1 and will see no network interfaces.
After re-mounting /proc in that shell,
<programlisting>
mount -t proc proc /proc
</programlisting>
ps output will show there are no other processes in the namespace.
</para>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
<!--
(C) Copyright Canonical Ltd.
Authors:
Stéphane Graber <stgraber@ubuntu.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
]>
<refentry>
<docinfo><date>@LXC_GENERATE_DATE@</date></docinfo>
<refmeta>
<refentrytitle>lxc-version</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>
<refnamediv>
<refname>lxc-version</refname>
<refpurpose>
print the currently installed lxc version
</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-version</command>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>lxc-version</command> print the currently installed lxc version
</para>
</refsect1>
<refsect1>
<title>Examples</title>
<variablelist>
<varlistentry>
<term>lxc-version</term>
<listitem>
<para>
print the currently installed lxc version.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
&seealso;
<refsect1>
<title>Author</title>
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
</refsect1>
</refentry>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:2
sgml-indent-data:t
sgml-parent-document:nil
sgml-default-dtd-file:nil
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->
......@@ -510,6 +510,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
rootfs. If lxc.autodev is set to 1, then after mounting the container's
rootfs LXC will mount a fresh tmpfs under <filename>/dev</filename>
(limited to 100k) and fill in a minimal set of initial devices.
This is generally required when starting a container containing
a "systemd" based "init" but may be optional at other times. Addional
devices in the containers /dev directory may be created through the
use of the <option>lxc.hook.autodev</option> hook.
</para>
<variablelist>
<varlistentry>
......@@ -686,6 +690,46 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</refsect2>
<refsect2>
<title>UID mappings</title>
<para>
A container can be started in a private user namespace with
user and group id mappings. For instance, you can map userid
0 in the container to userid 200000 on the host. The root
user in the container will be privileged in the container,
but unprivileged on the host. Normally a system container
will want a range of ids, so you would map, for instance,
user and group ids 0 through 20,000 in the container to the
ids 200,000 through 220,000.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.id_map</option>
</term>
<listitem>
<para>
Four values must be provided. First a character, either
'U', or 'G', to specify whether user or group ids are
being mapped. Next is the first userid as seen on the
host. Next is the userid to be mapped in the container.
Finally, a range indicating the number of consecutive
ids to map. For instance
</para>
<programlisting>
lxc.id_map = U 200000 0 20000
lxc.id_map = G 200000 0 20000
</programlisting>
<para>
will map both user and group ids in the
range 0-19999 in the container to the ids
200000-219999 on the host.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Startup hooks</title>
<para>
Startup hooks are programs or scripts which can be executed
......@@ -737,6 +781,27 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
<variablelist>
<varlistentry>
<term>
<option>lxc.hook.autodev</option>
</term>
<listitem>
<para>
A hook to be run in the container's namespace after
mounting has been done and after any mount hooks have
run, but before the pivot_root, if
<option>lxc.autodev</option> == 1.
The purpose of this hook is to assist in populating the
/dev directory of the container when using the autodev
option for systemd based containers. The container's /dev
directory is relative to the
${<option>LXC_ROOTFS_MOUNT</option>} environment
variable available when the hook is run.
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>lxc.hook.start</option>
</term>
<listitem>
......@@ -763,6 +828,103 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
</variablelist>
</refsect2>
<refsect2>
<title>Startup hooks Environment Variables</title>
<para>
A number of environment variables are made available to the startup
hooks to provide configuration information and assist in the
functioning of the hooks. Not all variables are valid in all
contexts. In particular, all paths are relative to the host system
and, as such, not valid during the <option>lxc.hook.start</option> hook.
</para>
<variablelist>
<varlistentry>
<term>
<option>LXC_NAME</option>
</term>
<listitem>
<para>
The LXC name of the container. Useful for logging messages
in commmon log environments. [<option>-n</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>LXC_CONFIG_FILE</option>
</term>
<listitem>
<para>
Host relative path to the container configuration file. This
gives the container to reference the original, top level,
configuration file for the container in order to locate any
addotional configuration information not otherwise made
available. [<option>-f</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>LXC_CONSOLE</option>
</term>
<listitem>
<para>
The path to the console output of the container if not NULL.
[<option>-c</option>] [<option>lxc.console</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>LXC_CONSOLE_LOGPATH</option>
</term>
<listitem>
<para>
The path to the console log output of the container if not NULL.
[<option>-L</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>LXC_ROOTFS_MOUNT</option>
</term>
<listitem>
<para>
The mount location to which the container is initially bound.
This will be the host relative path to the container rootfs
for the container instance being started and is where changes
should be made for that instance.
[<option>lxc.rootfs.mount</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
<variablelist>
<varlistentry>
<term>
<option>LXC_ROOTFS_PATH</option>
</term>
<listitem>
<para>
The host relative path to the container root which has been
mounted to the rootfs.mount location.
[<option>lxc.rootfs</option>]
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<refsect1>
......
......@@ -32,6 +32,18 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
Requires: libcap openssl rsync
BuildRequires: libcap libcap-devel docbook2X
%define with_python %{?_with_python: 1} %{?!_with_python: 0}
%if %{with_python}
Requires: python3
BuildRequires: python3-devel
%endif
%define with_lua %{?_with_lua: 1} %{?!_with_lua: 0}
%if %{with_lua}
Requires: lua-filesystem
BuildRequires: lua-devel
%endif
%description
The package "%{name}" provides the command lines to create and manage
......@@ -62,7 +74,14 @@ development of the linux containers.
%prep
%setup
%build
PATH=$PATH:/usr/sbin:/sbin %configure $args --disable-rpath
PATH=$PATH:/usr/sbin:/sbin %configure $args \
%if %{with_lua}
--enable-lua \
%endif
%if %{with_python}
--enable-python \
%endif
--disable-rpath
make %{?_smp_mflags}
%install
......@@ -97,6 +116,13 @@ rm -rf %{buildroot}
%defattr(-,root,root)
%{_libdir}/*.so.*
%{_libdir}/%{name}
%if %{with_lua}
%{_datadir}/lua
%{_libdir}/lua
%endif
%if %{with_python}
%{_libdir}/python*
%endif
%{_localstatedir}/*
%attr(4555,root,root) %{_libexecdir}/%{name}/lxc-init
......
SUBDIRS = lxc tests python-lxc
SUBDIRS = lxc tests python-lxc lua-lxc
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Emulate glibc getline() via BSD fgetln().
* Note that outsize is not changed unless memory is allocated.
*/
ssize_t
getline(char **outbuf, size_t *outsize, FILE *fp)
{
size_t len;
char *buf;
buf = fgetln(fp, &len);
if (buf == NULL)
return (-1);
/* Assumes realloc() accepts NULL for ptr (C99) */
if (*outbuf == NULL || *outsize < len + 1) {
void *tmp = realloc(*outbuf, len + 1);
if (tmp == NULL)
return (-1);
*outbuf = tmp;
*outsize = len + 1;
}
memcpy(*outbuf, buf, len);
(*outbuf)[len] = '\0';
return (len);
}
#ifndef _getline_h
#define _getline_h
extern ssize_t getline(char **outbuf, size_t *outsize, FILE *fp);
#endif
#include <stdio.h>
#include <string.h>
#include <mntent.h>
/* Since the values in a line are separated by spaces, a name cannot
contain a space. Therefore some programs encode spaces in names
by the strings "\040". We undo the encoding when reading an entry.
The decoding happens in place. */
static char *
decode_name (char *buf)
{
char *rp = buf;
char *wp = buf;
do
if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '4' && rp[3] == '0')
{
/* \040 is a SPACE. */
*wp++ = ' ';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '1')
{
/* \011 is a TAB. */
*wp++ = '\t';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '0' && rp[2] == '1' && rp[3] == '2')
{
/* \012 is a NEWLINE. */
*wp++ = '\n';
rp += 3;
}
else if (rp[0] == '\\' && rp[1] == '\\')
{
/* We have to escape \\ to be able to represent all characters. */
*wp++ = '\\';
rp += 1;
}
else if (rp[0] == '\\' && rp[1] == '1' && rp[2] == '3' && rp[3] == '4')
{
/* \134 is also \\. */
*wp++ = '\\';
rp += 3;
}
else
*wp++ = *rp;
while (*rp++ != '\0');
return buf;
}
/* Read one mount table entry from STREAM. Returns a pointer to storage
reused on the next call, or null for EOF or error (use feof/ferror to
check). */
struct mntent *getmntent_r (FILE *stream, struct mntent *mp, char *buffer, int bufsiz)
{
char *cp;
char *head;
do
{
char *end_ptr;
if (fgets (buffer, bufsiz, stream) == NULL)
{
return NULL;
}
end_ptr = strchr (buffer, '\n');
if (end_ptr != NULL) /* chop newline */
*end_ptr = '\0';
else
{
/* Not the whole line was read. Do it now but forget it. */
char tmp[1024];
while (fgets (tmp, sizeof tmp, stream) != NULL)
if (strchr (tmp, '\n') != NULL)
break;
}
head = buffer + strspn (buffer, " \t");
/* skip empty lines and comment lines: */
}
while (head[0] == '\0' || head[0] == '#');
cp = strsep (&head, " \t");
mp->mnt_fsname = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_dir = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_type = cp != NULL ? decode_name (cp) : (char *) "";
if (head)
head += strspn (head, " \t");
cp = strsep (&head, " \t");
mp->mnt_opts = cp != NULL ? decode_name (cp) : (char *) "";
switch (head ? sscanf (head, " %d %d ", &mp->mnt_freq, &mp->mnt_passno) : 0)
{
case 0:
mp->mnt_freq = 0;
case 1:
mp->mnt_passno = 0;
case 2:
break;
}
return mp;
}
struct mntent *getmntent (FILE *stream)
{
static struct mntent m;
static char *getmntent_buffer;
#define BUFFER_SIZE 4096
if (getmntent_buffer == NULL) {
getmntent_buffer = (char *) malloc (BUFFER_SIZE);
}
return getmntent_r (stream, &m, getmntent_buffer, BUFFER_SIZE);
#undef BUFFER_SIZE
}
/* Prepare to begin reading and/or writing mount table entries from the
beginning of FILE. MODE is as for `fopen'. */
FILE *setmntent (const char *file, const char *mode)
{
/* Extend the mode parameter with "c" to disable cancellation in the
I/O functions and "e" to set FD_CLOEXEC. */
size_t modelen = strlen (mode);
char newmode[modelen + 3];
memcpy (newmode, mode, modelen);
memcpy (newmode + modelen, "ce", 3);
FILE *result = fopen (file, newmode);
return result;
}
/* Close a stream opened with `setmntent'. */
int endmntent (FILE *stream)
{
if (stream) /* SunOS 4.x allows for NULL stream */
fclose (stream);
return 1; /* SunOS 4.x says to always return 1 */
}
/* Search MNT->mnt_opts for an option matching OPT.
Returns the address of the substring, or null if none found. */
char *hasmntopt (const struct mntent *mnt, const char *opt)
{
const size_t optlen = strlen (opt);
char *rest = mnt->mnt_opts, *p;
while ((p = strstr (rest, opt)) != NULL)
{
if ((p == rest || p[-1] == ',')
&& (p[optlen] == '\0' || p[optlen] == '=' || p[optlen] == ','))
return p;
rest = strchr (p, ',');
if (rest == NULL)
break;
++rest;
}
return NULL;
}
#ifndef _lxcmntent_h
#define _lxcmntent_h
#include <../config.h>
#if IS_BIONIC
struct mntent
{
char* mnt_fsname;
char* mnt_dir;
char* mnt_type;
char* mnt_opts;
int mnt_freq;
int mnt_passno;
};
extern struct mntent *getmntent (FILE *stream);
#endif
#ifndef HAVE_SETMNTENT
FILE *setmntent (const char *file, const char *mode);
#endif
#ifndef HAVE_ENDMNTENT
int endmntent (FILE *stream);
#endif
#ifndef HAVE_HASMNTOPT
extern char *hasmntopt (const struct mntent *mnt, const char *opt);
#endif
#endif
/* Copyright (C) 1998, 1999, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#define _XOPEN_SOURCE /* See feature_test_macros(7) */
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#define _PATH_DEVPTMX "/dev/ptmx"
int openpty (int *amaster, int *aslave, char *name, struct termios *termp,
struct winsize *winp)
{
char buf[PATH_MAX];
int master, slave;
master = open(_PATH_DEVPTMX, O_RDWR);
if (master == -1)
return -1;
if (grantpt(master))
goto fail;
if (unlockpt(master))
goto fail;
if (ptsname_r(master, buf, sizeof buf))
goto fail;
slave = open(buf, O_RDWR | O_NOCTTY);
if (slave == -1)
goto fail;
/* XXX Should we ignore errors here? */
if (termp)
tcsetattr(slave, TCSAFLUSH, termp);
if (winp)
ioctl(slave, TIOCSWINSZ, winp);
*amaster = master;
*aslave = slave;
if (name != NULL)
strcpy(name, buf);
return 0;
fail:
close(master);
return -1;
}
#ifndef _openpty_h
#define _openpty_h
#include <termios.h>
#include <sys/ioctl.h>
/* Create pseudo tty master slave pair with NAME and set terminal
attributes according to TERMP and WINP and return handles for both
ends in AMASTER and ASLAVE. */
extern int openpty (int *__amaster, int *__aslave, char *__name,
const struct termios *__termp,
const struct winsize *__winp);
#endif
if ENABLE_LUA
luadir=$(datadir)/lua/5.1
sodir=$(libdir)/lua/5.1/lxc
lua_SCRIPTS=lxc.lua
EXTRA_DIST=lxc.lua
so_PROGRAMS = core.so
core_so_SOURCES = core.c
AM_CFLAGS=-I$(top_srcdir)/src $(LUA_CFLAGS) -DVERSION=\"$(VERSION)\" -DLXCPATH=\"$(LXCPATH)\"
core_so_CFLAGS = -fPIC -DPIC $(AM_CFLAGS)
core_so_LDFLAGS = \
-shared \
-L$(top_srcdir)/src/lxc \
-Wl,-soname,core.so.$(firstword $(subst ., ,$(VERSION)))
core_so_LDADD = -llxc $(LUA_LIBS)
lxc.lua:
endif
#!/usr/bin/env lua
--
-- test the lxc lua api
--
-- Copyright © 2012 Oracle.
--
-- Authors:
-- Dwight Engen <dwight.engen@oracle.com>
--
-- This library is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2, as
-- published by the Free Software Foundation.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--
local lxc = require("lxc")
local lfs = require("lfs")
local getopt = require("alt_getopt")
local LXC_PATH = lxc.default_config_path_get()
local container
local cfg_containers = {}
local optarg = {}
local optind = {}
function printf(...)
local function wrapper(...) io.write(string.format(...)) end
local status, result = pcall(wrapper, ...)
if not status then
error(result, 2)
end
end
function log(level, ...)
if (optarg["v"] >= level) then
printf(os.date("%Y-%m-%d %T "))
printf(...)
printf("\n")
end
end
function die(...)
printf(...)
os.exit(1)
end
function test_global_info()
local cfg_containers
local run_containers
log(0, "%-20s %s", "LXC version:", lxc.version_get())
log(0, "%-20s %s", "Container name:", optarg["n"])
if (optarg["c"]) then
log(0, "%-20s %s", "Creating container:", "yes")
log(0, "%-20s %s", "With template:", optarg["t"])
end
log(0, "%-20s %s", "Containers path:", LXC_PATH)
cfg_containers = lxc.containers_configured()
log(0, "%-20s", "Containers configured:")
for _,v in ipairs(cfg_containers) do
log(0, " %s", v)
end
run_containers = lxc.containers_running(true)
log(0, "%-20s", "Containers running:")
for _,v in ipairs(run_containers) do
log(0, " %s", v)
end
end
function test_container_new()
container = lxc.container:new(optarg["n"])
assert(container ~= nil)
assert(container:config_file_name() == string.format("%s/%s/config", LXC_PATH, optarg["n"]))
end
function test_container_config_path()
local cfgcontainer
local cfgpath = "/tmp/" .. optarg["n"]
local cfgname = cfgpath .. "/config"
log(0, "Test container config path...")
-- create a config file in the new location from container's config
assert(lfs.mkdir(cfgpath))
assert(container:save_config(cfgname))
cfgcontainer = lxc.container:new(optarg["n"], "/tmp")
assert(cfgcontainer ~= nil)
log(0, "cfgname:%s cfgpath:%s", cfgcontainer:config_file_name(), cfgcontainer:get_config_path())
assert(cfgcontainer:config_file_name() == cfgname)
assert(cfgcontainer:get_config_path() == "/tmp")
assert(cfgcontainer:set_config_path(LXC_PATH))
assert(cfgcontainer:get_config_path() == LXC_PATH)
assert(os.remove(cfgname))
assert(lfs.rmdir(cfgpath))
end
function test_container_create()
if (optarg["c"]) then
log(0, "%-20s %s", "Destroy existing container:", optarg["n"])
container:destroy()
assert(container:defined() == false)
else
local cfg_containers = lxc.containers_configured()
if (cfg_containers[optarg["n"]]) then
log(0, "%-20s %s", "Use existing container:", optarg["n"])
return
end
end
log(0, "%-20s %s", "Creating rootfs using:", optarg["t"])
container:create(optarg["t"])
assert(container:defined() == true)
assert(container:name() == optarg["n"])
end
function test_container_started()
local now_running
log(2, "state:%s pid:%d\n", container:state(), container:init_pid())
assert(container:init_pid() > 1)
assert(container:running() == true)
assert(container:state() == "RUNNING")
now_running = lxc.containers_running(true)
assert(now_running[optarg["n"]] ~= nil)
log(1, "%-20s %s", "Running, init pid:", container:init_pid())
end
function test_container_stopped()
local now_running
assert(container:init_pid() == -1)
assert(container:running() == false)
assert(container:state() == "STOPPED")
now_running = lxc.containers_running(true)
assert(now_running[optarg["n"]] == nil)
end
function test_container_frozen()
local now_running
assert(container:init_pid() > 1)
assert(container:running() == true)
assert(container:state() == "FROZEN")
now_running = lxc.containers_running(true)
assert(now_running[optarg["n"]] ~= nil)
end
function test_container_start()
log(0, "Starting...")
if (not container:start()) then
log(1, "Start returned failure, waiting another 10 seconds...")
container:wait("RUNNING", 10)
end
container:wait("RUNNING", 1)
end
function test_container_stop()
log(0, "Stopping...")
if (not container:stop()) then
log(1, "Stop returned failure, waiting another 10 seconds...")
container:wait("STOPPED", 10)
end
container:wait("STOPPED", 1)
end
function test_container_freeze()
log(0, "Freezing...")
if (not container:freeze()) then
log(1, "Freeze returned failure, waiting another 10 seconds...")
container:wait("FROZEN", 10)
end
end
function test_container_unfreeze()
log(0, "Unfreezing...")
if (not container:unfreeze()) then
log(1, "Unfreeze returned failure, waiting another 10 seconds...")
container:wait("RUNNING", 10)
end
end
function test_container_shutdown()
log(0, "Shutting down...")
container:shutdown(5)
if (container:running()) then
test_container_stop()
end
end
function test_container_in_cfglist(should_find)
local cfg_containers = lxc.containers_configured()
if (should_find) then
assert(cfg_containers[container:name()] ~= nil)
else
assert(cfg_containers[container:name()] == nil)
end
end
function test_config_items()
log(0, "Test set/clear configuration items...")
-- test setting a 'single type' item
assert(container:get_config_item("lxc.utsname") == optarg["n"])
container:set_config_item("lxc.utsname", "foobar")
assert(container:get_config_item("lxc.utsname") == "foobar")
container:set_config_item("lxc.utsname", optarg["n"])
assert(container:get_config_item("lxc.utsname") == optarg["n"])
-- test clearing/setting a 'list type' item
container:clear_config_item("lxc.cap.drop")
container:set_config_item("lxc.cap.drop", "new_cap1")
container:set_config_item("lxc.cap.drop", "new_cap2")
local cap_drop = container:get_config_item("lxc.cap.drop")
assert(cap_drop["new_cap1"] ~= nil)
assert(cap_drop["new_cap2"] ~= nil)
-- note: clear_config_item only works on list type items
container:clear_config_item("lxc.cap.drop")
assert(container:get_config_item("lxc.cap.drop") == nil)
local altname = "/tmp/" .. optarg["n"] .. ".altconfig"
log(0, "Test saving to an alternate (%s) config file...", altname)
assert(container:save_config(altname))
assert(os.remove(altname))
end
function test_config_mount_entries()
local mntents
-- mount entries are a list type item
mntents = container:get_config_item("lxc.mount.entry")
log(0, "Mount entries:")
for _,v in ipairs(mntents) do
log(0, " %s", v)
end
end
function test_config_keys()
local keys
keys = container:get_keys()
log(0, "Top level keys:")
for k,v in pairs(keys) do
log(0, " %s = %s", k, v or "")
end
end
function test_config_network(net_nr)
log(0, "Test network %d config...", net_nr)
local netcfg
netcfg = container:get_keys("lxc.network." .. net_nr)
if (netcfg == nil) then
return
end
for k,v in pairs(netcfg) do
log(0, " %s = %s", k, v or "")
end
assert(netcfg["flags"] == "up")
assert(container:get_config_item("lxc.network."..net_nr..".type") == "veth")
end
function usage()
die("Usage: apitest <options>\n" ..
" -v|--verbose increase verbosity with each -v\n" ..
" -h|--help print help message\n" ..
" -n|--name name of container to use for testing\n" ..
" -c|--create create the test container anew\n" ..
" -l|--login do interactive login test\n" ..
" -t|--template template to use when creating test container\n"
)
end
local long_opts = {
verbose = "v",
help = "h",
name = "n",
create = "c",
template = "t",
}
optarg,optind = alt_getopt.get_opts (arg, "hvn:ct:", long_opts)
optarg["v"] = tonumber(optarg["v"]) or 0
optarg["n"] = optarg["n"] or "lua-apitest"
optarg["c"] = optarg["c"] or nil
optarg["t"] = optarg["t"] or "busybox"
if (optarg["h"] ~= nil) then
usage()
end
test_global_info()
test_container_new()
test_container_create()
test_container_stopped()
test_container_in_cfglist(true)
test_container_config_path()
test_config_items()
test_config_keys()
test_config_mount_entries()
test_config_network(0)
test_container_start()
test_container_started()
test_container_freeze()
test_container_frozen()
test_container_unfreeze()
test_container_started()
test_container_shutdown()
test_container_stopped()
container:destroy()
test_container_in_cfglist(false)
log(0, "All tests passed")
......@@ -17,6 +17,18 @@ pkginclude_HEADERS = \
lxccontainer.h \
lxclock.h
if IS_BIONIC
pkginclude_HEADERS += \
../include/openpty.h \
../include/lxcmntent.h
endif
if !HAVE_GETLINE
if HAVE_FGETLN
pkginclude_HEADERS += ../include/getline.h
endif
endif
sodir=$(libdir)
# use PROGRAMS to avoid complains from automake
so_PROGRAMS = liblxc.so
......@@ -56,21 +68,39 @@ liblxc_so_SOURCES = \
mainloop.c mainloop.h \
af_unix.c af_unix.h \
\
utmp.c utmp.h \
lxcutmp.c lxcutmp.h \
apparmor.c apparmor.h \
lxclock.h lxclock.c \
lxccontainer.c lxccontainer.h
if IS_BIONIC
liblxc_so_SOURCES += \
../include/openpty.c ../include/openpty.h \
../include/lxcmntent.c ../include/lxcmntent.h
endif
if !HAVE_GETLINE
if HAVE_FGETLN
liblxc_so_SOURCES += ../include/getline.c ../include/getline.h
endif
endif
AM_CFLAGS=-I$(top_srcdir)/src \
-DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
-DLXCPATH=\"$(LXCPATH)\" \
-DLXC_GLOBAL_CONF=\"$(LXC_GLOBAL_CONF)\" \
-DLXCINITDIR=\"$(LXCINITDIR)\" \
-DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\"
-DLXCTEMPLATEDIR=\"$(LXCTEMPLATEDIR)\" \
-DLOGPATH=\"$(LOGPATH)\"
if ENABLE_APPARMOR
AM_CFLAGS += -DHAVE_APPARMOR
endif
if USE_CONFIGPATH_LOGS
AM_CFLAGS += -DUSE_CONFIGPATH_LOGS
endif
if ENABLE_SECCOMP
AM_CFLAGS += -DHAVE_SECCOMP
liblxc_so_SOURCES += seccomp.c
......@@ -82,21 +112,25 @@ liblxc_so_LDFLAGS = \
-shared \
-Wl,-soname,liblxc.so.$(firstword $(subst ., ,$(VERSION)))
liblxc_so_LDADD = -lutil $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS) -lrt
liblxc_so_LDADD = $(CAP_LIBS) $(APPARMOR_LIBS) $(SECCOMP_LIBS)
if !IS_BIONIC
liblxc_so_LDADD += -lutil -lrt
endif
bin_SCRIPTS = \
lxc-ps \
lxc-netstat \
lxc-checkconfig \
lxc-setcap \
lxc-setuid \
lxc-version \
lxc-create \
lxc-clone \
lxc-shutdown \
lxc-destroy
EXTRA_DIST=
if ENABLE_PYTHON
EXTRA_DIST += lxc-device lxc-ls
bin_SCRIPTS += lxc-device
bin_SCRIPTS += lxc-ls
bin_SCRIPTS += lxc-start-ephemeral
......@@ -104,6 +138,11 @@ else
bin_SCRIPTS += legacy/lxc-ls
endif
if ENABLE_LUA
EXTRA_DIST += lxc-top
bin_SCRIPTS += lxc-top
endif
bin_PROGRAMS = \
lxc-attach \
lxc-unshare \
......@@ -124,11 +163,18 @@ bin_PROGRAMS = \
pkglibexec_PROGRAMS = \
lxc-init
#pkglibexec_SCRIPTS = \
# lxc.functions
AM_LDFLAGS = -Wl,-E
if ENABLE_RPATH
AM_LDFLAGS += -Wl,-rpath -Wl,$(libdir)
endif
LDADD=liblxc.so @CAP_LIBS@ @APPARMOR_LIBS@ @SECCOMP_LIBS@ -lrt
LDADD=liblxc.so @CAP_LIBS@ @APPARMOR_LIBS@ @SECCOMP_LIBS@
if !IS_BIONIC
LDADD += -lrt
endif
lxc_attach_SOURCES = lxc_attach.c
lxc_cgroup_SOURCES = lxc_cgroup.c
......@@ -148,9 +194,12 @@ lxc_wait_SOURCES = lxc_wait.c
lxc_kill_SOURCES = lxc_kill.c
install-exec-local: install-soPROGRAMS
mkdir -p $(DESTDIR)$(datadir)/lxc
install -c -m 644 lxc.functions $(DESTDIR)$(datadir)/lxc
mv $(DESTDIR)$(libdir)/liblxc.so $(DESTDIR)$(libdir)/liblxc.so.$(VERSION)
/sbin/ldconfig -l $(DESTDIR)$(libdir)/liblxc.so.$(VERSION)
cd $(DESTDIR)$(libdir); \
ln -sf liblxc.so.$(VERSION) liblxc.so.$(firstword $(subst ., ,$(VERSION))); \
ln -sf liblxc.so.$(firstword $(subst ., ,$(VERSION))) liblxc.so
uninstall-local:
......
......@@ -45,6 +45,7 @@ struct lxc_arguments {
int daemonize;
const char *rcfile;
const char *console;
const char *console_log;
const char *pidfile;
/* for lxc-checkpoint/restart */
......
......@@ -31,6 +31,7 @@
#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <linux/unistd.h>
#if !HAVE_DECL_PR_CAPBSET_DROP
......@@ -46,15 +47,38 @@
lxc_log_define(lxc_attach, lxc);
int setns(int fd, int nstype)
/* Define setns() if missing from the C library */
#ifndef HAVE_SETNS
static int setns(int fd, int nstype)
{
#ifndef __NR_setns
errno = ENOSYS;
return -1;
#ifdef __NR_setns
return syscall(__NR_setns, fd, nstype);
#else
return syscall(__NR_setns, fd, nstype);
errno = ENOSYS;
return -1;
#endif
}
#endif
/* Define unshare() if missing from the C library */
#ifndef HAVE_UNSHARE
static int unshare(int flags)
{
#ifdef __NR_unshare
return syscall(__NR_unshare, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
#endif
/* Define getline() if missing from the C library */
#ifndef HAVE_GETLINE
#ifdef HAVE_FGETLN
#include <../include/getline.h>
#endif
#endif
struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
{
......
......@@ -27,13 +27,20 @@
#include <stdlib.h>
#include <limits.h>
#include <sys/prctl.h>
#include <sys/capability.h>
#include <errno.h>
#include "config.h"
#include "log.h"
lxc_log_define(lxc_caps, lxc);
#if HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#ifndef PR_CAPBSET_READ
#define PR_CAPBSET_READ 23
#endif
int lxc_caps_reset(void)
{
cap_t cap = cap_init();
......@@ -258,3 +265,4 @@ int lxc_caps_check(void)
return 1;
}
#endif
......@@ -20,9 +20,12 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#ifndef _caps_h
#define _caps_h
#if HAVE_SYS_CAPABILITY_H
extern int lxc_caps_reset(void);
extern int lxc_caps_down(void);
extern int lxc_caps_up(void);
......@@ -30,30 +33,53 @@ extern int lxc_caps_init(void);
extern int lxc_caps_check(void);
extern int lxc_caps_last_cap(void);
#else
static inline int lxc_caps_reset(void) {
return 0;
}
static inline int lxc_caps_down(void) {
return 0;
}
static inline int lxc_caps_up(void) {
return 0;
}
static inline int lxc_caps_init(void) {
return 0;
}
static inline int lxc_caps_check(void) {
return 1;
}
static inline int lxc_caps_last_cap(void) {
return 0;
}
#endif
#define lxc_priv(__lxc_function) \
({ \
int __ret, __ret2, __errno = 0; \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_up(); \
if (__ret) \
goto __out; \
goto out; \
__ret = __lxc_function; \
if (__ret) \
__errno = errno; \
___errno = errno; \
__ret2 = lxc_caps_down(); \
__out: __ret ? errno = __errno,__ret : __ret2; \
out: __ret ? errno = ___errno,__ret : __ret2; \
})
#define lxc_unpriv(__lxc_function) \
#define lxc_unpriv(__lxc_function) \
({ \
int __ret, __ret2, __errno = 0; \
__label__ out; \
int __ret, __ret2, ___errno = 0; \
__ret = lxc_caps_down(); \
if (__ret) \
goto __out; \
goto out; \
__ret = __lxc_function; \
if (__ret) \
__errno = errno; \
___errno = errno; \
__ret2 = lxc_caps_up(); \
__out: __ret ? errno = __errno,__ret : __ret2; \
out: __ret ? errno = ___errno,__ret : __ret2; \
})
#endif
......@@ -25,7 +25,6 @@
#undef _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <mntent.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
......@@ -44,6 +43,12 @@
#include <lxc/cgroup.h>
#include <lxc/start.h>
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
#include <mntent.h>
#endif
lxc_log_define(lxc_cgroup, lxc);
#define MTAB "/proc/mounts"
......@@ -59,7 +64,7 @@ enum {
static char *mount_has_subsystem(const struct mntent *mntent)
{
FILE *f;
char *c, *ret;
char *c, *ret = NULL;
char line[MAXPATHLEN];
/* read the list of subsystems from the kernel */
......
......@@ -30,10 +30,13 @@
#include <sys/un.h>
#include <sys/poll.h>
#include <sys/param.h>
#include <malloc.h>
#include <stdlib.h>
#include <lxc/log.h>
#include <lxc/conf.h>
#include <lxc/start.h> /* for struct lxc_handler */
#include <lxc/utils.h>
#include "commands.h"
#include "mainloop.h"
......@@ -56,7 +59,29 @@
lxc_log_define(lxc_commands, lxc);
#define abstractname LXCPATH "/%s/command"
static int fill_sock_name(char *path, int len, const char *name,
const char *inpath)
{
char *lxcpath = NULL;
int ret;
if (!inpath) {
lxcpath = default_lxc_path();
if (!lxcpath) {
ERROR("Out of memory getting lxcpath");
return -1;
}
}
ret = snprintf(path, len, "%s/%s/command", lxcpath ? lxcpath : inpath, name);
if (lxcpath)
free(lxcpath);
if (ret < 0 || ret >= len) {
ERROR("Name too long");
return -1;
}
return 0;
}
static int receive_answer(int sock, struct lxc_answer *answer)
{
......@@ -70,19 +95,16 @@ static int receive_answer(int sock, struct lxc_answer *answer)
}
static int __lxc_command(const char *name, struct lxc_command *command,
int *stopped, int stay_connected)
int *stopped, int stay_connected, const char *lxcpath)
{
int sock, ret = -1;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
char *offset = &path[1];
int rc, len;
int len;
len = sizeof(path)-1;
rc = snprintf(offset, len, abstractname, name);
if (rc < 0 || rc >= len) {
ERROR("Name too long");
if (fill_sock_name(offset, len, name, lxcpath))
return -1;
}
sock = lxc_af_unix_connect(path);
if (sock < 0 && errno == ECONNREFUSED) {
......@@ -116,19 +138,21 @@ out:
}
extern int lxc_command(const char *name,
struct lxc_command *command, int *stopped)
struct lxc_command *command, int *stopped,
const char *lxcpath)
{
return __lxc_command(name, command, stopped, 0);
return __lxc_command(name, command, stopped, 0, lxcpath);
}
extern int lxc_command_connected(const char *name,
struct lxc_command *command, int *stopped)
struct lxc_command *command, int *stopped,
const char *lxcpath)
{
return __lxc_command(name, command, stopped, 1);
return __lxc_command(name, command, stopped, 1, lxcpath);
}
pid_t get_init_pid(const char *name)
pid_t get_init_pid(const char *name, const char *lxcpath)
{
struct lxc_command command = {
.request = { .type = LXC_COMMAND_PID },
......@@ -136,7 +160,7 @@ pid_t get_init_pid(const char *name)
int ret, stopped = 0;
ret = lxc_command(name, &command, &stopped);
ret = lxc_command(name, &command, &stopped, lxcpath);
if (ret < 0 && stopped)
return -1;
......@@ -154,7 +178,7 @@ pid_t get_init_pid(const char *name)
return command.answer.pid;
}
int lxc_get_clone_flags(const char *name)
int lxc_get_clone_flags(const char *name, const char *lxcpath)
{
struct lxc_command command = {
.request = { .type = LXC_COMMAND_CLONE_FLAGS },
......@@ -162,7 +186,7 @@ int lxc_get_clone_flags(const char *name)
int ret, stopped = 0;
ret = lxc_command(name, &command, &stopped);
ret = lxc_command(name, &command, &stopped, lxcpath);
if (ret < 0 && stopped)
return -1;
......@@ -287,19 +311,17 @@ out_close:
goto out;
}
extern int lxc_command_init(const char *name, struct lxc_handler *handler)
extern int lxc_command_init(const char *name, struct lxc_handler *handler,
const char *lxcpath)
{
int fd;
char path[sizeof(((struct sockaddr_un *)0)->sun_path)] = { 0 };
char *offset = &path[1];
int rc, len;
int len;
len = sizeof(path)-1;
rc = snprintf(offset, len, abstractname, name);
if (rc < 0 || rc >= len) {
ERROR("Name too long");
if (fill_sock_name(offset, len, name, lxcpath))
return -1;
}
fd = lxc_af_unix_open(path, SOCK_STREAM, 0);
if (fd < 0) {
......
......@@ -48,19 +48,20 @@ struct lxc_command {
struct lxc_answer answer;
};
extern pid_t get_init_pid(const char *name);
extern int lxc_get_clone_flags(const char *name);
extern pid_t get_init_pid(const char *name, const char *lxcpath);
extern int lxc_get_clone_flags(const char *name, const char *lxcpath);
extern int lxc_command(const char *name, struct lxc_command *command,
int *stopped);
int *stopped, const char *lxcpath);
extern int lxc_command_connected(const char *name, struct lxc_command *command,
int *stopped);
int *stopped, const char *lxcpath);
struct lxc_epoll_descr;
struct lxc_handler;
extern int lxc_command_init(const char *name, struct lxc_handler *handler);
extern int lxc_command_init(const char *name, struct lxc_handler *handler,
const char *lxcpath);
extern int lxc_command_mainloop_add(const char *name, struct lxc_epoll_descr *descr,
struct lxc_handler *handler);
......
......@@ -26,6 +26,7 @@
#include <netinet/in.h>
#include <net/if.h>
#include <sys/param.h>
#include <sys/types.h>
#include <stdbool.h>
#include <lxc/list.h>
......@@ -87,8 +88,8 @@ struct ifla_veth {
struct ifla_vlan {
uint flags;
uint fmask;
ushort vid;
ushort pad;
unsigned short vid;
unsigned short pad;
};
struct ifla_macvlan {
......@@ -141,6 +142,26 @@ struct lxc_cgroup {
char *value;
};
enum idtype {
ID_TYPE_UID,
ID_TYPE_GID
};
/*
* id_map is an id map entry. Form in confile is:
* lxc.id_map = U 9800 0 100
* lxc.id_map = U 9900 1000 100
* lxc.id_map = G 9800 0 100
* lxc.id_map = G 9900 1000 100
* meaning the container can use uids and gids 0-100 and 1000-1100,
* with uid 0 mapping to uid 9800 on the host, and gid 1000 to
* gid 9900 on the host.
*/
struct id_map {
enum idtype idtype;
int hostid, nsid, range;
};
/*
* Defines a structure containing a pty information for
* virtualizing a tty
......@@ -175,6 +196,8 @@ struct lxc_console {
int master;
int peer;
char *path;
char *log_path;
int log_fd;
char name[MAXPATHLEN];
struct termios *tios;
};
......@@ -211,8 +234,8 @@ struct lxc_rootfs {
#endif
*/
enum lxchooks {
LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_START,
LXCHOOK_POSTSTOP, NUM_LXC_HOOKS};
LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV,
LXCHOOK_START, LXCHOOK_POSTSTOP, NUM_LXC_HOOKS};
extern char *lxchook_names[NUM_LXC_HOOKS];
struct saved_nic {
......@@ -229,6 +252,7 @@ struct lxc_conf {
int personality;
struct utsname *utsname;
struct lxc_list cgroup;
struct lxc_list id_map;
struct lxc_list network;
struct saved_nic *saved_nics;
int num_savednics;
......@@ -243,8 +267,6 @@ struct lxc_conf {
#if HAVE_APPARMOR
char *aa_profile;
#endif
char *logfile;
int loglevel;
#if HAVE_APPARMOR /* || HAVE_SELINUX || HAVE_SMACK */
int lsm_umount_proc;
......@@ -255,10 +277,14 @@ struct lxc_conf {
#endif
int maincmd_fd;
int autodev; // if 1, mount and fill a /dev at start
char *rcfile; // Copy of the top level rcfile we read
};
int run_lxc_hooks(const char *name, char *hook, struct lxc_conf *conf);
extern int setup_cgroup(const char *name, struct lxc_list *cgroups);
extern int detect_shared_rootfs(void);
/*
* Initialize the lxc configuration structure
*/
......@@ -270,6 +296,7 @@ extern int pin_rootfs(const char *rootfs);
extern int lxc_create_network(struct lxc_handler *handler);
extern void lxc_delete_network(struct lxc_handler *handler);
extern int lxc_assign_network(struct lxc_list *networks, pid_t pid);
extern int lxc_map_ids(struct lxc_list *idmap, pid_t pid);
extern int lxc_find_gateway_addresses(struct lxc_handler *handler);
extern int lxc_create_tty(const char *name, struct lxc_conf *conf);
......@@ -282,6 +309,10 @@ extern int lxc_clear_cgroups(struct lxc_conf *c, const char *key);
extern int lxc_clear_mount_entries(struct lxc_conf *c);
extern int lxc_clear_hooks(struct lxc_conf *c, const char *key);
extern int setup_cgroup(const char *name, struct lxc_list *cgroups);
extern int uid_shift_ttys(int pid, struct lxc_conf *conf);
/*
* Configure the container from inside
*/
......
......@@ -27,17 +27,16 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pty.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/utsname.h>
#include <sys/personality.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include "parse.h"
#include "config.h"
#include "confile.h"
#include "utils.h"
......@@ -45,6 +44,10 @@
#include <lxc/conf.h>
#include "network.h"
#if HAVE_SYS_PERSONALITY_H
#include <sys/personality.h>
#endif
lxc_log_define(lxc_confile, lxc);
static int config_personality(const char *, const char *, struct lxc_conf *);
......@@ -55,6 +58,7 @@ static int config_ttydir(const char *, const char *, struct lxc_conf *);
static int config_aa_profile(const char *, const char *, struct lxc_conf *);
#endif
static int config_cgroup(const char *, const char *, struct lxc_conf *);
static int config_idmap(const char *, const char *, struct lxc_conf *);
static int config_loglevel(const char *, const char *, struct lxc_conf *);
static int config_logfile(const char *, const char *, struct lxc_conf *);
static int config_mount(const char *, const char *, struct lxc_conf *);
......@@ -94,6 +98,7 @@ static struct lxc_config_t config[] = {
{ "lxc.aa_profile", config_aa_profile },
#endif
{ "lxc.cgroup", config_cgroup },
{ "lxc.id_map", config_idmap },
{ "lxc.loglevel", config_loglevel },
{ "lxc.logfile", config_logfile },
{ "lxc.mount", config_mount },
......@@ -104,6 +109,7 @@ static struct lxc_config_t config[] = {
{ "lxc.hook.pre-start", config_hook },
{ "lxc.hook.pre-mount", config_hook },
{ "lxc.hook.mount", config_hook },
{ "lxc.hook.autodev", config_hook },
{ "lxc.hook.start", config_hook },
{ "lxc.hook.post-stop", config_hook },
{ "lxc.network.type", config_network_type },
......@@ -577,7 +583,11 @@ static int config_network_ipv4(const char *key, const char *value,
lxc_list_init(list);
list->elem = inetdev;
addr = strdupa(value);
addr = strdup(value);
if (!addr) {
ERROR("no address specified");
return -1;
}
cursor = strstr(addr, " ");
if (cursor) {
......@@ -591,18 +601,15 @@ static int config_network_ipv4(const char *key, const char *value,
prefix = slash + 1;
}
if (!addr) {
ERROR("no address specified");
return -1;
}
if (!inet_pton(AF_INET, addr, &inetdev->addr)) {
SYSERROR("invalid ipv4 address: %s", value);
free(addr);
return -1;
}
if (bcast && !inet_pton(AF_INET, bcast, &inetdev->bcast)) {
SYSERROR("invalid ipv4 broadcast address: %s", value);
free(addr);
return -1;
}
......@@ -619,8 +626,9 @@ static int config_network_ipv4(const char *key, const char *value,
htonl(INADDR_BROADCAST >> inetdev->prefix);
}
lxc_list_add(&netdev->ipv4, list);
lxc_list_add_tail(&netdev->ipv4, list);
free(addr);
return 0;
}
......@@ -690,7 +698,12 @@ static int config_network_ipv6(const char *key, const char *value,
lxc_list_init(list);
list->elem = inet6dev;
valdup = strdupa(value);
valdup = strdup(value);
if (!valdup) {
ERROR("no address specified");
return -1;
}
inet6dev->prefix = 64;
slash = strstr(valdup, "/");
if (slash) {
......@@ -701,11 +714,13 @@ static int config_network_ipv6(const char *key, const char *value,
if (!inet_pton(AF_INET6, value, &inet6dev->addr)) {
SYSERROR("invalid ipv6 address: %s", value);
free(valdup);
return -1;
}
lxc_list_add(&netdev->ipv6, list);
lxc_list_add_tail(&netdev->ipv6, list);
free(valdup);
return 0;
}
......@@ -821,6 +836,8 @@ static int config_hook(const char *key, const char *value,
return add_hook(lxc_conf, LXCHOOK_PRESTART, copy);
else if (strcmp(key, "lxc.hook.pre-mount") == 0)
return add_hook(lxc_conf, LXCHOOK_PREMOUNT, copy);
else if (strcmp(key, "lxc.hook.autodev") == 0)
return add_hook(lxc_conf, LXCHOOK_AUTODEV, copy);
else if (strcmp(key, "lxc.hook.mount") == 0)
return add_hook(lxc_conf, LXCHOOK_MOUNT, copy);
else if (strcmp(key, "lxc.hook.start") == 0)
......@@ -910,46 +927,26 @@ static int config_aa_profile(const char *key, const char *value,
static int config_logfile(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
char *path;
// if given a blank entry, null out any previous entries.
if (!value || strlen(value) == 0) {
if (lxc_conf->logfile) {
free(lxc_conf->logfile);
lxc_conf->logfile = NULL;
}
return 0;
}
path = strdup(value);
if (!path) {
SYSERROR("failed to strdup '%s': %m", value);
return -1;
}
if (lxc_log_set_file(path)) {
free(path);
return -1;
}
if (lxc_conf->logfile)
free(lxc_conf->logfile);
lxc_conf->logfile = path;
return 0;
return lxc_log_set_file(value);
}
static int config_loglevel(const char *key, const char *value,
struct lxc_conf *lxc_conf)
{
int newlevel;
if (!value || strlen(value) == 0)
return 0;
if (lxc_log_get_level() != LXC_LOG_PRIORITY_NOTSET) {
DEBUG("Log level already set - ignoring new value");
return 0;
}
if (value[0] >= '0' && value[0] <= '9')
lxc_conf->loglevel = atoi(value);
newlevel = atoi(value);
else
lxc_conf->loglevel = lxc_log_priority_to_int(value);
return lxc_log_set_level(lxc_conf->loglevel);
newlevel = lxc_log_priority_to_int(value);
return lxc_log_set_level(newlevel);
}
static int config_autodev(const char *key, const char *value,
......@@ -1021,6 +1018,64 @@ out:
return -1;
}
static int config_idmap(const char *key, const char *value, struct lxc_conf *lxc_conf)
{
char *token = "lxc.id_map";
char *subkey;
struct lxc_list *idmaplist = NULL;
struct id_map *idmap = NULL;
int hostid, nsid, range;
char type;
int ret;
subkey = strstr(key, token);
if (!subkey)
return -1;
if (!strlen(subkey))
return -1;
idmaplist = malloc(sizeof(*idmaplist));
if (!idmaplist)
goto out;
idmap = malloc(sizeof(*idmap));
if (!idmap)
goto out;
memset(idmap, 0, sizeof(*idmap));
idmaplist->elem = idmap;
lxc_list_add_tail(&lxc_conf->id_map, idmaplist);
ret = sscanf(value, "%c %d %d %d", &type, &hostid, &nsid, &range);
if (ret != 4)
goto out;
INFO("read uid map: type %c hostid %d nsid %d range %d", type, hostid, nsid, range);
if (type == 'U')
idmap->idtype = ID_TYPE_UID;
else if (type == 'G')
idmap->idtype = ID_TYPE_GID;
else
goto out;
idmap->hostid = hostid;
idmap->nsid = nsid;
idmap->range = range;
return 0;
out:
if (idmaplist)
free(idmaplist);
if (idmap) {
free(idmap);
}
return -1;
}
static int config_path_item(const char *key, const char *value,
struct lxc_conf *lxc_conf, char **conf_item)
{
......@@ -1265,6 +1320,10 @@ int lxc_config_readline(char *buffer, struct lxc_conf *conf)
int lxc_config_read(const char *file, struct lxc_conf *conf)
{
/* Catch only the top level config file name in the structure */
if( ! conf->rcfile ) {
conf->rcfile = strdup( file );
}
return lxc_file_for_each_line(file, parse_line, conf);
}
......@@ -1302,6 +1361,7 @@ int lxc_config_define_load(struct lxc_list *defines, struct lxc_conf *conf)
signed long lxc_config_parse_arch(const char *arch)
{
#if HAVE_SYS_PERSONALITY_H
struct per_name {
char *name;
unsigned long per;
......@@ -1319,6 +1379,7 @@ signed long lxc_config_parse_arch(const char *arch)
if (!strcmp(pername[i].name, arch))
return pername[i].per;
}
#endif
return -1;
}
......@@ -1334,18 +1395,22 @@ static int lxc_get_conf_int(struct lxc_conf *c, char *retv, int inlen, int v)
static int lxc_get_arch_entry(struct lxc_conf *c, char *retv, int inlen)
{
int len, fulllen = 0;
int fulllen = 0;
if (!retv)
inlen = 0;
else
memset(retv, 0, inlen);
#if HAVE_SYS_PERSONALITY_H
int len = 0;
switch(c->personality) {
case PER_LINUX32: strprint(retv, inlen, "x86"); break;
case PER_LINUX: strprint(retv, inlen, "x86_64"); break;
default: break;
}
#endif
return fulllen;
}
......@@ -1594,9 +1659,9 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv,
v = c->aa_profile;
#endif
else if (strcmp(key, "lxc.logfile") == 0)
v = c->logfile;
v = lxc_log_get_file();
else if (strcmp(key, "lxc.loglevel") == 0)
v = lxc_log_priority_to_string(c->loglevel);
v = lxc_log_priority_to_string(lxc_log_get_level());
else if (strcmp(key, "lxc.cgroup") == 0) // all cgroup info
return lxc_get_cgroup_entry(c, retv, inlen, "all");
else if (strncmp(key, "lxc.cgroup.", 11) == 0) // specific cgroup info
......@@ -1665,19 +1730,21 @@ void write_config(FILE *fout, struct lxc_conf *c)
fprintf(fout, "lxc.pts = %d\n", c->pts);
if (c->ttydir)
fprintf(fout, "lxc.devttydir = %s\n", c->ttydir);
#if HAVE_SYS_PERSONALITY_H
switch(c->personality) {
case PER_LINUX32: fprintf(fout, "lxc.arch = x86\n"); break;
case PER_LINUX: fprintf(fout, "lxc.arch = x86_64\n"); break;
default: break;
}
#endif
#if HAVE_APPARMOR
if (c->aa_profile)
fprintf(fout, "lxc.aa_profile = %s\n", c->aa_profile);
#endif
if (c->loglevel != LXC_LOG_PRIORITY_NOTSET)
fprintf(fout, "lxc.loglevel = %s\n", lxc_log_priority_to_string(c->loglevel));
if (c->logfile)
fprintf(fout, "lxc.logfile = %s\n", c->logfile);
if (lxc_log_get_level() != LXC_LOG_PRIORITY_NOTSET)
fprintf(fout, "lxc.loglevel = %s\n", lxc_log_priority_to_string(lxc_log_get_level()));
if (lxc_log_get_file())
fprintf(fout, "lxc.logfile = %s\n", lxc_log_get_file());
lxc_list_for_each(it, &c->cgroup) {
struct lxc_cgroup *cg = it->elem;
fprintf(fout, "lxc.cgroup.%s = %s\n", cg->subsystem, cg->value);
......
......@@ -21,6 +21,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#ifndef _confile_h
#define _confile_h
......
......@@ -26,28 +26,34 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pty.h>
#include <sys/types.h>
#include <sys/un.h>
#include <termios.h>
#include "log.h"
#include "conf.h"
#include "config.h"
#include "start.h" /* for struct lxc_handler */
#include "caps.h"
#include "commands.h"
#include "mainloop.h"
#include "af_unix.h"
#if HAVE_PTY_H
#include <pty.h>
#else
#include <../include/openpty.h>
#endif
lxc_log_define(lxc_console, lxc);
extern int lxc_console(const char *name, int ttynum, int *fd)
extern int lxc_console(const char *name, int ttynum, int *fd, const char *lxcpath)
{
int ret, stopped = 0;
struct lxc_command command = {
.request = { .type = LXC_COMMAND_TTY, .data = ttynum },
};
ret = lxc_command_connected(name, &command, &stopped);
ret = lxc_command_connected(name, &command, &stopped, lxcpath);
if (ret < 0 && stopped) {
ERROR("'%s' is stopped", name);
return -1;
......@@ -145,7 +151,7 @@ static int get_default_console(char **console)
if (!access("/dev/tty", F_OK)) {
fd = open("/dev/tty", O_RDWR);
if (fd > 0) {
if (fd >= 0) {
close(fd);
*console = strdup("/dev/tty");
goto out;
......@@ -195,11 +201,21 @@ int lxc_create_console(struct lxc_conf *conf)
goto err;
}
if (console->log_path) {
fd = lxc_unpriv(open(console->log_path, O_CLOEXEC | O_RDWR | O_CREAT | O_APPEND, 0600));
if (fd < 0) {
SYSERROR("failed to open '%s'", console->log_path);
goto err;
}
DEBUG("using '%s' as console log", console->log_path);
console->log_fd = fd;
}
fd = lxc_unpriv(open(console->path, O_CLOEXEC | O_RDWR | O_CREAT |
O_APPEND, 0600));
if (fd < 0) {
SYSERROR("failed to open '%s'", console->path);
goto err;
goto err_close_console_log;
}
DEBUG("using '%s' as console", console->path);
......@@ -212,7 +228,7 @@ int lxc_create_console(struct lxc_conf *conf)
console->tios = malloc(sizeof(tios));
if (!console->tios) {
SYSERROR("failed to allocate memory");
goto err;
goto err_close_console;
}
/* Get termios */
......@@ -241,26 +257,54 @@ int lxc_create_console(struct lxc_conf *conf)
err_free:
free(console->tios);
err_close_console:
close(console->peer);
console->peer = -1;
err_close_console_log:
if (console->log_fd >= 0) {
close(console->log_fd);
console->log_fd = -1;
}
err:
close(console->master);
console->master = -1;
close(console->slave);
console->slave = -1;
return -1;
}
void lxc_delete_console(const struct lxc_console *console)
void lxc_delete_console(struct lxc_console *console)
{
if (console->tios &&
tcsetattr(console->peer, TCSAFLUSH, console->tios))
WARN("failed to set old terminal settings");
free(console->tios);
console->tios = NULL;
close(console->peer);
console->peer = -1;
if (console->log_fd >= 0) {
close(console->log_fd);
console->log_fd = -1;
}
close(console->master);
console->master = -1;
close(console->slave);
console->slave = -1;
}
static int console_handler(int fd, void *data, struct lxc_epoll_descr *descr)
{
struct lxc_console *console = (struct lxc_console *)data;
char buf[1024];
int r;
int r,w;
r = read(fd, buf, sizeof(buf));
if (r < 0) {
......@@ -280,10 +324,14 @@ static int console_handler(int fd, void *data, struct lxc_epoll_descr *descr)
return 0;
if (console->peer == fd)
r = write(console->master, buf, r);
else
r = write(console->peer, buf, r);
w = write(console->master, buf, r);
else {
w = write(console->peer, buf, r);
if (console->log_fd > 0)
w = write(console->log_fd, buf, r);
}
if (w != r)
WARN("console short write");
return 0;
}
......
......@@ -127,7 +127,7 @@ static struct lxc_operations execute_start_ops = {
};
int lxc_execute(const char *name, char *const argv[], int quiet,
struct lxc_conf *conf)
struct lxc_conf *conf, const char *lxcpath)
{
struct execute_args args = {
.argv = argv,
......@@ -137,5 +137,5 @@ int lxc_execute(const char *name, char *const argv[], int quiet,
if (lxc_check_inherited(conf, -1))
return -1;
return __lxc_start(name, conf, &execute_start_ops, &args);
return __lxc_start(name, conf, &execute_start_ops, &args, lxcpath);
}
......@@ -32,6 +32,8 @@
#include <sys/param.h>
#include "error.h"
#include "state.h"
#include "monitor.h"
#include <lxc/log.h>
#include <lxc/cgroup.h>
......@@ -95,7 +97,10 @@ static int freeze_unfreeze(const char *name, int freeze)
ret = strncmp(f, tmpf, strlen(f));
if (!ret)
{
lxc_monitor_send_state(name, freeze ? FROZEN : THAWED);
break; /* Success */
}
sleep(1);
......@@ -119,6 +124,7 @@ out:
int lxc_freeze(const char *name)
{
lxc_monitor_send_state(name, FREEZING);
return freeze_unfreeze(name, 1);
}
......
#!/bin/bash
#!/bin/sh
#
# lxc: linux Container library
......@@ -17,7 +17,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
lxc_path=@LXCPATH@
. @DATADIR@/lxc/lxc.functions
usage()
{
......@@ -35,8 +35,6 @@ help() {
get_parent_cgroup()
{
local hierarchies hierarchy fields subsystems init_cgroup mountpoint
parent_cgroup=""
# Obtain a list of hierarchies that contain one or more subsystems
......@@ -56,16 +54,16 @@ get_parent_cgroup()
init_cgroup=${fields#*:}
# Get the filesystem mountpoint of the hierarchy
mountpoint=$(grep -E "^[^ ]+ [^ ]+ cgroup ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2)
mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
'$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
if [ -z "$mountpoint" ]; then continue; fi
# Return the absolute path to the containers' parent cgroup
# (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
if [[ ",$subsystems," == *,ns,* ]]; then
parent_cgroup="${mountpoint}${init_cgroup%/}"
else
parent_cgroup="${mountpoint}${init_cgroup%/}/lxc"
fi
case ",$subsystems," in
*,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
*) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
esac
break
done
}
......@@ -82,12 +80,12 @@ for i in "$@"; do
shift; break;;
*)
break;;
esac
esac
done
containers=""
if [ ! -z "$directory" ]; then
containers=$(find $directory -mindepth 1 -maxdepth 1 -type d -printf "%f\n" 2>/dev/null)
containers=$(find $directory -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')
fi
cd "$directory"
......
......@@ -41,7 +41,9 @@
int lxc_log_fd = -1;
static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
int lxc_loglevel_specified = 0;
static int lxc_loglevel_specified = 0;
// if logfile was specifed on command line, it won't be overridden by lxc.logfile
static int lxc_log_specified = 0;
lxc_log_define(lxc_log, lxc);
......@@ -123,6 +125,36 @@ extern void lxc_log_setprefix(const char *prefix)
log_prefix[sizeof(log_prefix) - 1] = 0;
}
static int build_dir(const char *name)
{
char *n = strdup(name); // because we'll be modifying it
char *p, *e;
int ret;
if (!n) {
ERROR("Out of memory while creating directory '%s'.", name);
return -1;
}
e = &n[strlen(n)];
for (p = n+1; p < e; p++) {
if (*p != '/')
continue;
*p = '\0';
if (access(n, F_OK)) {
ret = lxc_unpriv(mkdir(n, 0755));
if (ret && errno != -EEXIST) {
SYSERROR("failed to create directory '%s'.", n);
free(n);
return -1;
}
}
*p = '/';
}
free(n);
return 0;
}
/*---------------------------------------------------------------------------*/
static int log_open(const char *name)
{
......@@ -148,11 +180,46 @@ static int log_open(const char *name)
return newfd;
}
static char *build_log_path(const char *name)
{
char *p;
int len, ret;
/*
* '$logpath' + '/' + '$name' + '.log' + '\0'
* or
* '$logpath' + '/' + '$name' + '/' + '$name' + '.log' + '\0'
* sizeof(LOGPATH) includes its \0
*/
len = sizeof(LOGPATH) + strlen(name) + 6;
#if USE_CONFIGPATH_LOGS
len += strlen(name) + 1; /* add "/$container_name/" */
#endif
p = malloc(len);
if (!p)
return p;
#if USE_CONFIGPATH_LOGS
ret = snprintf(p, len, "%s/%s/%s.log", LOGPATH, name, name);
#else
ret = snprintf(p, len, "%s/%s.log", LOGPATH, name);
#endif
if (ret < 0 || ret >= len) {
free(p);
return NULL;
}
return p;
}
int do_lxc_log_set_file(const char *fname, int from_default);
/*---------------------------------------------------------------------------*/
extern int lxc_log_init(const char *file, const char *priority,
const char *prefix, int quiet)
extern int lxc_log_init(const char *name, const char *file,
const char *priority, const char *prefix, int quiet)
{
int lxc_priority = LXC_LOG_PRIORITY_ERROR;
int ret;
char *tmpfile = NULL;
int want_lxc_log_specified = 0;
if (lxc_log_fd != -1)
return 0;
......@@ -176,19 +243,38 @@ extern int lxc_log_init(const char *file, const char *priority,
if (prefix)
lxc_log_setprefix(prefix);
if (file) {
int fd;
if (file && strcmp(file, "none") == 0) {
want_lxc_log_specified = 1;
return 0;
}
fd = log_open(file);
if (fd == -1) {
ERROR("failed to initialize log service");
if (!file) {
tmpfile = build_log_path(name);
if (!tmpfile) {
ERROR("could not build log path");
return -1;
}
} else {
want_lxc_log_specified = 1;
}
lxc_log_fd = fd;
ret = do_lxc_log_set_file(tmpfile ? tmpfile : file, !want_lxc_log_specified);
if (want_lxc_log_specified)
lxc_log_specified = 1;
/*
* If !want_lxc_log_specified, that is, if the user did not request
* this logpath, then ignore failures and continue logging to console
*/
if (!want_lxc_log_specified && ret != 0) {
INFO("Ignoring failure to open default logfile.");
ret = 0;
}
return 0;
if (tmpfile)
free(tmpfile);
return ret;
}
/*
......@@ -208,21 +294,59 @@ extern int lxc_log_set_level(int level)
return 0;
}
char *log_fname; // default to NULL, set in lxc_log_set_file.
/*
* This is called when we read a lxc.logfile entry in a lxc.conf file. This
* happens after processing command line arguments, which override the .conf
* settings. So only set the logfile if previously unset.
* This can be called:
* 1. when a program calls lxc_log_init with no logfile parameter (in which
* case the default is used). In this case lxc.logfile can override this.
* 2. when a program calls lxc_log_init with a logfile parameter. In this
* case we don't want lxc.logfile to override this.
* 3. When a lxc.logfile entry is found in config file.
*/
extern int lxc_log_set_file(char *fname)
int do_lxc_log_set_file(const char *fname, int from_default)
{
if (lxc_log_fd != -1) {
INFO("Configuration file was specified on command line, configuration file entry being ignored");
if (lxc_log_specified) {
INFO("lxc.logfile overriden by command line");
return 0;
}
lxc_log_fd = log_open(fname);
if (lxc_log_fd == -1) {
ERROR("failed to open log file %s\n", fname);
if (lxc_log_fd != -1) {
// we are overriding the default.
close(lxc_log_fd);
free(log_fname);
}
#if USE_CONFIGPATH_LOGS
// we don't build_dir for the default if the default is
// i.e. /var/lib/lxc/$container/$container.log
if (!from_default)
#endif
if (build_dir(fname)) {
ERROR("failed to create dir for log file \"%s\" : %s", fname,
strerror(errno));
return -1;
}
lxc_log_fd = log_open(fname);
if (lxc_log_fd == -1)
return -1;
log_fname = strdup(fname);
return 0;
}
extern int lxc_log_set_file(const char *fname)
{
return do_lxc_log_set_file(fname, 0);
}
extern int lxc_log_get_level(void)
{
if (!lxc_loglevel_specified)
return LXC_LOG_PRIORITY_NOTSET;
return lxc_log_category_lxc.priority;
}
extern const char *lxc_log_get_file(void)
{
return log_fname;
}
......@@ -287,10 +287,12 @@ extern struct lxc_log_category lxc_log_category_lxc;
extern int lxc_log_fd;
extern int lxc_log_init(const char *file, const char *priority,
const char *prefix, int quiet);
extern int lxc_log_init(const char *name, const char *file,
const char *priority, const char *prefix, int quiet);
extern void lxc_log_setprefix(const char *a_prefix);
extern int lxc_log_set_level(int level);
extern int lxc_log_set_file(char *fname);
extern int lxc_log_set_file(const char *fname);
extern int lxc_log_get_level(void);
extern const char *lxc_log_get_file(void);
#endif
......@@ -4,10 +4,10 @@
: ${CONFIG:=/proc/config.gz}
: ${GREP:=zgrep}
SETCOLOR_SUCCESS="printf \\e[1;32m"
SETCOLOR_FAILURE="printf \\e[1;31m"
SETCOLOR_WARNING="printf \\e[1;33m"
SETCOLOR_NORMAL="printf \\e[0;39m"
SETCOLOR_SUCCESS="printf \\033[1;32m"
SETCOLOR_FAILURE="printf \\033[1;31m"
SETCOLOR_WARNING="printf \\033[1;33m"
SETCOLOR_NORMAL="printf \\033[0;39m"
is_set() {
$GREP -q "$1=[y|m]" $CONFIG
......
#!/bin/bash
#!/bin/sh
#
# lxc: linux Container library
......@@ -37,75 +37,84 @@ help() {
echo " -o ORIG_NAME specify the name of the original container" >&2
echo " -n NEW_NAME specify the name of the new container" >&2
echo " -s make the new rootfs a snapshot of the original" >&2
echo " -L FS_SIZE specify the new filesystem size (default: 2G)" >&2
echo " -L FS_SIZE specify the new filesystem size (default: same as original)" >&2
echo " -v VG_NAME specify the new LVM volume group name (default: lxc)" >&2
echo " -p LV_PREFIX add a prefix to new LVM logical volume names" >&2
echo " -t FS_TYPE specify the new filesystem type (default: ext3;" >&2
echo " only works for non-snapshot LVM)" >&2
}
shortoptions='ho:n:sL:v:p:t:'
longoptions='help,orig:,name:,snapshot,fssize:,vgname:,lvprefix:,fstype:'
lxc_path=@LXCPATH@
bindir=@BINDIR@
usage_err() {
[ -n "$1" ] && echo "$1" >&2
usage
exit 1
}
optarg_check() {
[ -n "$2" ] || usage_err "option $1 requires an argument"
}
. @DATADIR@/lxc/lxc.functions
snapshot=no
lxc_defsize=2G
lxc_size=_unset
lxc_vg=lxc
lxc_lv_prefix=""
fstype=ext3
getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")
if [ $? != 0 ]; then
usage
exit 1;
fi
eval set -- "$getopt"
while true; do
case "$1" in
while [ $# -gt 0 ]; do
opt="$1"
shift
case "$opt" in
-h|--help)
help
exit 1
;;
-s|--snapshot)
shift
snapshot=yes
snapshot_opt="-s"
;;
-o|--orig)
shift
optarg_check $opt $1
lxc_orig=$1
shift
;;
-L|--fssize)
shift
optarg_check $opt $1
lxc_size=$1
shift
;;
-v|--vgname)
-t|--fstype)
optarg_check $opt $1
fstype=$1
shift
;;
-v|--vgname)
optarg_check $opt $1
lxc_vg=$1
shift
;;
-n|--name)
shift
optarg_check $opt $1
lxc_new=$1
shift
;;
-p|--lvprefix)
shift
optarg_check $opt $1
lxc_lv_prefix=$1
shift
;;
--)
shift
break
;;
-?)
usage_err "Unknown option: '$opt'"
;;
-*)
# split opts -abc into -a -b -c
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
;;
*)
usage
exit 1
usage_err
;;
esac
done
......@@ -187,11 +196,11 @@ oldroot=`grep lxc.rootfs $lxc_path/$lxc_orig/config | awk -F'[= \t]+' '{ print $
rootfs=`echo $oldroot |sed "s/$lxc_orig/$lxc_new/"`
container_running=True
lxc-info -s -n $lxc_orig|grep RUNNING >/dev/null 2>&1 || container_running=False
lxc-info -n $lxc_orig --state-is RUNNING || container_running=False
sed -i '/lxc.rootfs/d' $lxc_path/$lxc_new/config
if [ -b $oldroot ]; then
type vgscan || { echo "$(basename $0): lvm is not installed" >&2; false; }
which vgscan >/dev/null 2>&1 || { echo "$(basename $0): lvm is not installed" >&2; false; }
lvdisplay $oldroot > /dev/null 2>&1 || { echo "$(basename $0): non-lvm blockdev cloning is not supported" >&2; false; }
lvm=TRUE
# ok, create a snapshot of the lvm device
......@@ -204,7 +213,7 @@ if [ -b $oldroot ]; then
fi
newlv="${lxc_lv_prefix}${lxc_new}_snapshot"
lvcreate -s -L $lxc_size -n $newlv $oldroot
type xfs_admin > /dev/null 2>&1 && {
which xfs_admin > /dev/null 2>&1 && {
# change filesystem UUID if it is an xfs filesystem
xfs_admin -u /dev/$lxc_vg/$newlv && xfs_admin -U generate /dev/$lxc_vg/$newlv
}
......@@ -272,7 +281,7 @@ c=$lxc_path/$lxc_new/config
mv ${c} ${c}.old
(
while read line; do
if [ "${line:0:18}" = "lxc.network.hwaddr" ]; then
if echo $line | grep -q -w '^lxc.network.hwaddr'; then
echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')"
else
echo "$line"
......
......@@ -73,9 +73,7 @@ optarg_check() {
fi
}
lxc_path=@LXCPATH@
bindir=@BINDIR@
templatedir=@LXCTEMPLATEDIR@
. @DATADIR@/lxc/lxc.functions
backingstore=_unset
fstype=ext4
fssize=500M
......@@ -222,7 +220,7 @@ if [ "$backingstore" = "_unset" ] || [ "$backingstore" = "btrfs" ]; then
fi
if [ "$backingstore" = "lvm" ]; then
which vgscan > /dev/null
which vgscan > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$(basename $0): vgscan not found (is lvm2 installed?)" >&2
exit 1
......@@ -274,7 +272,7 @@ trap cleanup HUP INT TERM
mkdir -p $lxc_path/$lxc_name
if [ -z "$lxc_config" ]; then
lxc_config="@SYSCONFDIR@/lxc/lxc.conf"
lxc_config="@SYSCONFDIR@/lxc/default.conf"
echo
echo "$(basename $0): No config file specified, using the default config $lxc_config"
fi
......@@ -302,11 +300,12 @@ if [ ! -z "$lxc_template" ]; then
if [ -n "$*" ]; then
echo "# Parameters passed to the template: $*" >> $lxc_path/$lxc_name/config
fi
echo "# Checksum of the template script (SHA-1): $sum" >> $lxc_path/$lxc_name/config
echo "# Template script checksum (SHA-1): $sum" >> $lxc_path/$lxc_name/config
echo "" >> $lxc_path/$lxc_name/config
fi
cat $lxc_config >> $lxc_path/$lxc_name/config
echo "" >> $lxc_path/$lxc_name/config
if [ -n "$custom_rootfs" ]; then
if grep -q "lxc.rootfs" $lxc_path/$lxc_name/config ; then
......
#!/bin/bash
#!/bin/sh
#
# lxc: linux Container library
......@@ -39,38 +39,47 @@ help() {
echo " -f stop the container if it is running (rather than abort)" >&2
}
shortoptions='hn:f'
longoptions='help,name:'
lxc_path=@LXCPATH@
force=0
getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")
if [ $? != 0 ]; then
usage_err() {
[ -n "$1" ] && echo "$1" >&2
usage
exit 1;
fi
exit 1
}
eval set -- "$getopt"
optarg_check() {
if [ -z "$2" ]; then
usage_err "option '$1' requires an argument"
fi
}
while true; do
case "$1" in
. @DATADIR@/lxc/lxc.functions
force=0
while [ $# -gt 0 ]; do
opt="$1"
shift
case "$opt" in
-h|--help)
help
exit 1
;;
-n|--name)
shift
optarg_check "$opt" "$1"
lxc_name=$1
shift
;;
-f)
force=1
shift
;;
--)
shift
break
;;
-?)
usage_err "unknown option '$opt'"
;;
-*)
# split opts -abc into -a -b -c
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
;;
*)
usage
exit 1
......@@ -94,14 +103,13 @@ if [ ! -d "$lxc_path/$lxc_name" ]; then
exit 1
fi
# make sure the container isn't running
lxc-info -n $lxc_name 2>/dev/null | grep -q RUNNING
if [ $? -eq 0 ]; then
# make sure the container is stopped
if ! lxc-info -n $lxc_name --state-is "STOPPED"; then
if [ $force -eq 1 ]; then
lxc-stop -n $lxc_name
lxc-wait -n $lxc_name -s STOPPED
else
echo "$(basename $0): '$lxc_name' is running; aborted" >&2
echo "$(basename $0): '$lxc_name' $(lxc-info -n $lxc_name -s); aborted" >&2
exit 1
fi
fi
......
#!/bin/bash
#!/bin/sh
#
# lxc: linux Container library
......@@ -32,8 +32,6 @@ help() {
get_parent_cgroup()
{
local hierarchies hierarchy fields subsystems init_cgroup mountpoint
parent_cgroup=""
# Obtain a list of hierarchies that contain one or more subsystems
......@@ -53,16 +51,16 @@ get_parent_cgroup()
init_cgroup=${fields#*:}
# Get the filesystem mountpoint of the hierarchy
mountpoint=$(grep -E "^cgroup [^ ]+ [^ ]+ ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2)
mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
'$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
if [ -z "$mountpoint" ]; then continue; fi
# Return the absolute path to the containers' parent cgroup
# (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
if [[ ",$subsystems," == *,ns,* ]]; then
parent_cgroup="${mountpoint}${init_cgroup%/}"
else
parent_cgroup="${mountpoint}${init_cgroup%/}/lxc"
fi
case ",$subsystems," in
*,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
*) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
esac
break
done
}
......@@ -98,8 +96,7 @@ if [ -z "$exec" ]; then
exec @BINDIR@/lxc-unshare -s MOUNT -- $0 -n $name --exec "$@"
fi
lxc-info -n $name 2>&1 | grep -q 'STOPPED'
if [ $? -eq 0 ]; then
if lxc-info -n $name --state-is 'STOPPED'; then
echo "$(basename $0): container '$name' is not running" >&2
exit 1
fi
......
#!/bin/bash
#!/bin/sh
#
# lxc: linux Container library
......@@ -56,16 +56,16 @@ get_parent_cgroup()
init_cgroup=${fields#*:}
# Get the filesystem mountpoint of the hierarchy
mountpoint=$(grep -E "^cgroup [^ ]+ [^ ]+ ([^ ]+,)?$subsystems(,[^ ]+)? " /proc/self/mounts | cut -d ' ' -f 2)
mountpoint=$(awk -v subsysregex="(^|,)$subsystems(,|\$)" \
'$3 == "cgroup" && $4 ~ subsysregex {print $2}' /proc/self/mounts)
if [ -z "$mountpoint" ]; then continue; fi
# Return the absolute path to the containers' parent cgroup
# (do not append '/lxc' if the hierarchy contains the 'ns' subsystem)
if [[ ",$subsystems," == *,ns,* ]]; then
parent_cgroup="${mountpoint}${init_cgroup%/}"
else
parent_cgroup="${mountpoint}${init_cgroup%/}/lxc"
fi
case ",$subsystems," in
*,ns,*) parent_cgroup="${mountpoint}${init_cgroup%/}";;
*) parent_cgroup="${mountpoint}${init_cgroup%/}/lxc";;
esac
break
done
}
......@@ -97,46 +97,67 @@ if [ ! -d "$parent_cgroup" ]; then
exit 1
fi
declare -a container_of_pid
container_field_width=9
IFS=","
if [ -z "$containers" ]; then
containers=( $(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d -printf "%f," 2>/dev/null) )
else
containers=( $containers )
containers="$(find $parent_cgroup -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sed 's:.*/::')"
fi
declare -i pid
IFS=$'\n'
for container in ${containers[@]}; do
container_field_width=9
tasks_files=
for container in ${containers}; do
if [ "${#container}" -gt "$container_field_width" ]; then
container_field_width=${#container}
fi
if [ -f "$parent_cgroup/$container/tasks" ]; then
while read pid; do
container_of_pid[$pid]=$container
done < "$parent_cgroup/$container/tasks"
tasks_files="$tasks_files $parent_cgroup/$container/tasks"
fi
done
declare -i line_pid_end_position
while read line; do
if [ -z "$line_pid_end_position" ]; then
if [[ "$line" != *" PID"* ]]; then
echo "$(basename $0): no PID column found in \`ps' output" >&2
exit 1
fi
buffer=${line%" PID"*}
let line_pid_end_position=${#buffer}+4
printf "%-${container_field_width}s %s\n" "CONTAINER" "$line"
continue
fi
# first file is stdin, the rest are the container tasks
ps "$@" | awk -v container_field_width="$container_field_width" \
-v list_container_processes="$list_container_processes" '
# first line is PS header
NR == 1 {
# find pid field index
for (i = 1; i<=NF; i++)
if ($i == "PID") {
pididx = i
break
}
if (pididx == "") {
print("No PID field found") > "/dev/stderr"
exit 1
}
header = $0
next
}
buffer=${line:0:$line_pid_end_position}
pid=${buffer##* }
if [ "$list_container_processes" -eq "0" -o ! -z "${container_of_pid[pid]}" ]; then
printf "%-${container_field_width}s %s\n" "${container_of_pid[pid]}" "$line"
fi
done < <(ps "$@")
# store lines from ps with pid as index
NR == FNR {
ps_line[NR] = $0
pid_of_line[NR] = $pididx
next
}
# find container name from filename on first line
FNR == 1 {
container = FILENAME
sub(/\/tasks/, "", container)
sub(/.*\//, "", container)
}
# container tasks
{
container_of_pid[$0] = container
}
END {
printf("%-" container_field_width "s %s\n", "CONTAINER", header)
for (i in ps_line) {
container = container_of_pid[pid_of_line[i]]
if (list_container_processes == 0 || container != "")
printf("%-" container_field_width "s %s\n", container, ps_line[i])
}
}
' - $tasks_files
#!/bin/sh
#
# lxc: linux Container library
# Authors:
# Daniel Lezcano <daniel.lezcano@free.fr>
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# This script allows to set or remove the capabilities on the lxc tools.
# When the capabilities are set, a non root user can manage the containers.
#
LXC_ATTACH_CAPS="cap_sys_admin,cap_dac_override"
LXC_CREATE_CAPS="cap_sys_admin"
LXC_NETSTAT_CAPS="cap_sys_admin"
LXC_INIT_CAPS="cap_sys_admin,cap_dac_override"
LXC_COMMON_CAPS="cap_net_admin,cap_net_raw,cap_sys_admin,cap_dac_override"
LXC_UNSHARE_CAPS=$LXC_COMMON_CAPS
LXC_START_CAPS="$LXC_COMMON_CAPS,cap_fowner,cap_sys_chroot,cap_setpcap"
LXC_EXECUTE_CAPS=$LXC_START_CAPS
LXC_RESTART_CAPS="$LXC_START_CAPS,cap_mknod"
LXC_CHECKPOINT_CAPS="$LXC_COMMON_CAPS,cap_sys_ptrace,cap_mknod"
LXC_DROP_CAPS=""
usage() {
echo "usage: $(basename $0) [-d]" >&2
}
help() {
usage
echo >&2
echo "Set or drop file capabilities on the lxc tools." >&2
echo >&2
echo "Options:" >&2
echo " -d drop file capabilities" >&2
}
lxc_setcaps()
{
setcap $LXC_ATTACH_CAPS=ep @BINDIR@/lxc-attach
setcap $LXC_CREATE_CAPS=ep @BINDIR@/lxc-create
setcap $LXC_EXECUTE_CAPS=ep @BINDIR@/lxc-execute
setcap $LXC_START_CAPS=ep @BINDIR@/lxc-start
setcap $LXC_RESTART_CAPS=ep @BINDIR@/lxc-restart
setcap $LXC_UNSHARE_CAPS=ep @BINDIR@/lxc-unshare
setcap $LXC_NETSTAT_CAPS=ep @BINDIR@/lxc-netstat
setcap $LXC_CHECKPOINT_CAPS=ep @BINDIR@/lxc-checkpoint
setcap $LXC_INIT_CAPS=ep @LXCINITDIR@/lxc-init
test -e @LXCPATH@ || mkdir -p @LXCPATH@
chmod 0777 @LXCPATH@
}
lxc_dropcaps()
{
setcap -r @BINDIR@/lxc-attach
setcap -r @BINDIR@/lxc-create
setcap -r @BINDIR@/lxc-execute
setcap -r @BINDIR@/lxc-start
setcap -r @BINDIR@/lxc-restart
setcap -r @BINDIR@/lxc-unshare
setcap -r @BINDIR@/lxc-netstat
setcap -r @BINDIR@/lxc-checkpoint
setcap -r @LXCINITDIR@/lxc-init
chmod 0755 @LXCPATH@
}
usage_err() {
[ -n "$1" ] && echo "$1" >&2
usage
exit 1
}
optarg_check() {
if [ -z "$2" ]; then
usage_err "option '$1' requires an argument"
fi
}
while [ $# -gt 0 ]; do
opt="$1"
shift
case "$opt" in
-d)
LXC_DROP_CAPS="yes"
;;
-h|--help)
help
exit 0
;;
--)
break
;;
-?)
usage_err "unknown option '$opt'"
;;
-*)
# split opts -abc into -a -b -c
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
;;
*)
usage
exit 1
;;
esac
done;
if [ "$(id -u)" != "0" ]; then
echo "$(basename $0): must be run as root" >&2
exit 1
fi
if [ -z "$LXC_DROP_CAPS" ]; then
lxc_setcaps
else
lxc_dropcaps
fi
#!/bin/sh
#
# lxc: linux Container library
# Authors:
# Daniel Lezcano <daniel.lezcano@free.fr>
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# This script allows to set or remove the setuid execution bit on the lxc tools.
# When the capabilities are set, a non root user can manage the containers.
#
usage() {
echo "usage: $(basename $0) [-d]" >&2
}
help() {
usage
echo >&2
echo "Set or drop the setuid attribute on the lxc tools." >&2
echo >&2
echo "Options:" >&2
echo " -d drop the setuid attribute" >&2
}
setuid()
{
if [ "$1" = "-r" ]; then
chmod -s $2
else
chmod +s $1
fi
}
lxc_setuid()
{
setuid @BINDIR@/lxc-attach
setuid @BINDIR@/lxc-create
setuid @BINDIR@/lxc-execute
setuid @BINDIR@/lxc-start
setuid @BINDIR@/lxc-restart
setuid @BINDIR@/lxc-unshare
setuid @BINDIR@/lxc-netstat
setuid @BINDIR@/lxc-checkpoint
setuid @LXCINITDIR@/lxc-init
test -e @LXCPATH@ || mkdir -p @LXCPATH@
chmod 0777 @LXCPATH@
}
lxc_dropuid()
{
setuid -r @BINDIR@/lxc-attach
setuid -r @BINDIR@/lxc-create
setuid -r @BINDIR@/lxc-execute
setuid -r @BINDIR@/lxc-start
setuid -r @BINDIR@/lxc-restart
setuid -r @BINDIR@/lxc-unshare
setuid -r @BINDIR@/lxc-netstat
setuid -r @BINDIR@/lxc-checkpoint
setuid -r @LXCINITDIR@/lxc-init
chmod 0755 @LXCPATH@
}
usage_err() {
[ -n "$1" ] && echo "$1" >&2
usage
exit 1
}
optarg_check() {
if [ -z "$2" ]; then
usage_err "option '$1' requires an argument"
fi
}
while [ $# -gt 0 ]; do
opt="$1"
shift
case "$opt" in
-d)
LXC_DROP_CAPS="yes"
;;
-h|--help)
help
exit 0
;;
--)
break
;;
-?)
usage_err "unknown option '$opt'"
;;
-*)
# split opts -abc into -a -b -c
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
;;
*)
usage
exit 1
;;
esac
done;
if [ "$(id -u)" != "0" ]; then
echo "$(basename $0): must be run as root" >&2
exit 1
fi
if [ -z "$LXC_DROP_CAPS" ]; then
lxc_setuid
else
lxc_dropuid
fi
#!/bin/bash
#!/bin/sh
# (C) Copyright Canonical 2011,2012
......@@ -41,53 +41,57 @@ dolxcstop()
exit 0
}
shortoptions='hn:rwt:'
longoptions='help,name:,wait,reboot,timeout:'
timeout="-1"
getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")
if [ $? != 0 ]; then
usage_err() {
[ -n "$1" ] && echo "$1" >&2
usage
exit 1;
fi
exit 1
}
optarg_check() {
[ -n "$2" ] || usage_err "option '$1' requires an argument"
}
eval set -- "$getopt"
timeout="-1"
reboot=0
dowait=0
while true; do
case "$1" in
while [ $# -gt 0 ]; do
opt="$1"
shift
case "$opt" in
-h|--help)
usage
exit 1
exit 0
;;
-n|--name)
shift
optarg_check $opt "$1"
lxc_name=$1
shift
;;
-w|--wait)
dowait=1
shift
;;
-r|--reboot)
reboot=1
shift
;;
-t|--timeout)
shift
optarg_check $opt "$1"
timeout=$1
dowait=1
shift
;;
--)
shift
break;;
-?)
usage_err "unknown option '$opt'"
;;
-*)
# split opts -abc into -a -b -c
set -- $(echo "${opt#-}" | sed 's/\(.\)/ -\1/g') "$@"
;;
*)
echo $1
usage
usage_err "unknown option '$opt'"
exit 1
;;
esac
......@@ -104,8 +108,8 @@ if [ "$(id -u)" != "0" ]; then
exit 1
fi
type lxc-info > /dev/null || { echo "lxc-info not found."; exit 1; }
type lxc-wait > /dev/null || { echo "lxc-wait not found."; exit 1; }
which lxc-info > /dev/null 2>&1 || { echo "lxc-info not found."; exit 1; }
which lxc-wait > /dev/null 2>&1 || { echo "lxc-wait not found."; exit 1; }
pid=`lxc-info -n $lxc_name -p 2>/dev/null | awk '{ print $2 }'`
if [ "$pid" = "-1" ]; then
......@@ -114,10 +118,10 @@ if [ "$pid" = "-1" ]; then
fi
if [ $reboot -eq 1 ]; then
kill -INT $pid
kill -s INT $pid
exit 0
else
kill -PWR $pid
kill -s PWR $pid
fi
if [ $dowait -eq 0 ]; then
......@@ -130,11 +134,7 @@ if [ $timeout != "-1" ]; then
alarmpid=$!
fi
while [ 1 ]; do
s=`lxc-info -s -n $lxc_name | awk '{ print $2 }'`
if [ "$s" = "STOPPED" ]; then
break;
fi
while ! lxc-info -n $lxc_name --state-is STOPPED; do
sleep 1
done
......
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment