Commit 5e97c3fc by dlezcano

Initial revision

parents
Makefile
Makefile.in
configure
config.status
config.log
autom4te.cache
aclocal.m4
IBM Corporation.
This diff is collapsed. Click to expand it.
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
# Makefile.am
SUBDIRS = src test etc
DIST_SUBDIRS = config src test etc
EXTRA_DIST = lxc.spec
rpm: dist
rpmbuild --clean -ta ${distdir}.tar.gz
Linux Container - LXC:
----------------------
This document provides a quick help to use the linux container.
Change log:
-----------
version 0.1.0 : initial document, Daniel Lezcano <dlezcano@fr.ibm.com>, Aug 01, 2008
Contents:
---------
0) Quick start
1) Overview
2) Requirements
3) Functional Specification
4) Future work
0) Quick start
--------------
You are in a hurry, and you don't want to read this README. Ok,
without warranty, here are the commands to launch a shell inside a
container with a predefined configuration template, it may work.
lxc-create -n foo -f /etc/lxc/lxc-macvlan.conf
lxc-execute -n foo /bin/bash
When your bash exits, you don't have to create 'foo' again, just call
lxc-execute again.
1) Overview
-----------
The container technology is actively being pushed into the mainstream
linux kernel. It provides the resource management through the control
groups aka process containers and resource isolation through the
namespaces.
The LXC aims to use these new functionnalities to provide an userspace
container object which provides full resource isolation and resource
control for an applications or a system.
The first objective of this project is to make the life easier for the
kernel developpers involved in the containers project and especially
to continue working on the Checkpoint/Restart new features. The LXC is
small enough to easily manage a container with simple command lines
and complete enough to be used for other purposes.
2) Requirements
---------------
The LXC relies on a set of functionnalies provided by the kernel which
needs to be active. Depending of the missing functionnality the LXC
will work with a restricted number of functionnality or will simply
fails.
This is the list of the kernel features which needs to be compiled in:
* General
* Control Group support
-> namespace cgroup subsystem
-> cpuset support
-> Group CPU scheduler
-> control group freeze subsystem
-> Basis for grouping tasks (Control Groups)
-> Simple CPU accounting
-> Resource counters
-> Memory resource controllers for Control Groups
-> Namespace support
-> UTS namespace
-> IPC namespace
-> User namespace
-> Pid namespace
* Network support
-> Networking options
-> Network namespace support
For the moment the easiest way to have all the features in the kernel
is to use the git tree at:
git://git.kernel.org/pub/scm/linux/kernel/git/daveh/linux-2.6-lxc.git
Otherwise the latest version of 2.6.26 kernel is usable with LXC but
without sysfs if the network namespace is activated and without the
freezer subsystem.
Before using LXC, the system should be configured as followed:
* Control group file system must be mounted
mount -t cgroup cgroup /cgroup
* You must have root privileges
3) Functional Specification
---------------------------
A container is an object where the configuration is persistent. The
application will be launched inside this container and it will
use the configuration which was previously created.
3.1 Container life cycle
------------------------
When the container is created, it contains the configuration
information. When a process is launched, the container will be
starting and running. When the last process running inside the
container exits, the container is stopped.
In case of failure when the container is initialized, it will pass
through the aborting state.
---------
| STOPPED |<---------------
--------- |
| |
start |
| |
V |
---------- |
| STARTING |--error- |
---------- | |
| | |
V V |
--------- ---------- |
| RUNNING | | ABORTING | |
--------- ---------- |
| | |
no process | |
| | |
V | |
---------- | |
| STOPPING |<------- |
---------- |
| |
---------------------
3.2 Configuration file
----------------------
The configuration file has the following format:
--------------------------------------------------------------------------------
# the fstab mount file.
lxc.mount = ./fstab
# the hostname to be set into the container
lxc.utsname = virtnode
# the chroot if needed for the running application
lxc.chroot = /mnt/root
# The network has several of kind of configuration:
#
# * veth : the network will use the veth virtual device, the
# specified link must be a bridge
# * macvlan : the network will use the macvlan device, the specified
# link should be an existing interface, usually it is
# eth0
# * phys : the network will use a physical network device, the
# specified link should be an existing interface
lxc.network.type = macvlan
# specify the flags to be used for the network, actually only <up> is
# allowed which mean the network should be set up when created. If the
# network is set up, the loopback is automatically set up too.
lxc.network.flags = up
# specify the physical network device which will communicate with the
# outside world
lxc.network.link = eth0
# NIC ethernet mac address
lxc.network.hwaddr = 4a:49:43:49:79:bd
# specify the ipv4 address of the container. Several lines are allowed
# and will mean several addresses will be assigned to the interface
lxc.network.ipv4 = 1.2.3.5/24
# specify the ipv6 address of the container. Several lines are allowed
# and will mean several addresses will be assigned to the interface
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
--------------------------------------------------------------------------------
* lxc.mount is optional
* lxc.utsname is optional
* lxc.network.xxx are optional, if not specified, the network
namespace will not be created
* lxc.chroot is optional
3.3 Container creation
----------------------
The container is created via the 'lxc-create' command. The command
specifies the container name and the container configuration file.
lxc-create -n foo -f <config>
3.4 Starting a container
------------------------
As the container has been create with the lxc-create command, it is
possible now to start an application inside.
lxc-execute -n foo /bin/bash
When the application has exited, it is possible to continue using the
container configuration to launch another application.
3.5 Stopping a container
------------------------
Usually, a container stops when the last process exits but in some
cases, it is usefully to wipe out such application. The following
command will kill the processes.
lxc-stop -n foo
3.6 Freezing/Unfreezing a container
-----------------------------------
All the processes belonging to a container can be stopped and resumed.
lxc-freeze -n foo
lxc-unfreeze -n foo
3.7 Sending a signal to a container
-----------------------------------
A signal can be sent to all processes running inside the container.
lxc-kill -n foo -s <signal>
3.8 Monitoring container states
-------------------------------
A container has a life cycle and pass though different states as
defined in section 3.1. The following command allows to watch such
states for a specific container.
lxc-monitor -n foo
3.9 Getting the container state
-------------------------------
At any time, the following command will retrieve the state of the
container.
lxc-state -n foo
3.10 Showing processes list for a container
------------------------------------------
The following command will show all the processes for all the running
container.
lxc-ps
4) Future work
--------------
* change the lxc-start command to support system container
* change the lxc-execute to have the first process to exec
* take into account all the resource management
* man pages
* improve monitoring support
* and more :)
#!/bin/sh
set -x
test -d autom4te.cache && rm -rf autom4te.cache
ACLOCAL_AMFLAGS="-I config $ACLOCAL_AMFLAGS"
aclocal $ACLOCAL_AMFLAGS || exit 1
autoheader || exit 1
autoconf || exit 1
automake --add-missing --copy || exit 1
Makefile
Makefile.in
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_INIT([lxc], [0.1.0])
AC_CONFIG_SRCDIR([configure.in])
AC_CONFIG_AUX_DIR([config])
AM_CONFIG_HEADER([src/config.h])
AM_INIT_AUTOMAKE([-Wno-portability])
AC_CANONICAL_HOST
AC_PROG_RANLIB
AM_PROG_CC_C_O
AC_GNU_SOURCE
AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h],, AC_MSG_ERROR([netlink headers not found]), [[]])
AC_PROG_GCC_TRADITIONAL
if test "x$GCC" = "xyes"; then
CFLAGS="$CFLAGS -Wall -Werror"
fi
AC_CONFIG_FILES([
Makefile
lxc.spec
config/Makefile
src/Makefile
src/liblxc/Makefile
src/lxc/Makefile
src/lxc/lxc-ps
etc/Makefile
etc/lxc-macvlan.conf
etc/lxc-no-netns.conf
etc/lxc-phys.conf
etc/lxc-veth.conf
etc/lxc-complex-config
test/Makefile
])
AC_CONFIG_COMMANDS([default],[[]],[[]])
AC_OUTPUT
proc /proc proc defaults 0 0
sysfs /sys sysfs noauto 0 0
# the fstab mount file
lxc.mount = ./fstab
# the hostname to be set into the container
lxc.utsname = virtnode
# The network has several of kind of configuration:
#
# * veth : the network will use the veth virtual device, the specified
# link must be a bridge
# * macvlan : the network will use the macvlan device, the specified link
# should be an existing interface, usually it is eth0
# * phys : the network will use a physical network device, the specified
# link should be an existing interface
lxc.network.type = macvlan
# specify the flags to be used for the network, actually only <up> is allowed
# which mean the network should be set up when created. If the network is set
# up, the loopback is automatically set up too.
lxc.network.flags = up
# specify the physical network device which will communicate with the
# outside world
lxc.network.link = eth0
# NIC ethernet mac address
lxc.network.hwaddr = 4a:49:43:49:79:bd
# specify the ipv4 address of the container. Several lines are allowed and
# will mean several addresses will be assigned to the interface
lxc.network.ipv4 = 1.2.3.5/24
# specify the ipv6 address of the container. Several lines are allowed and
# will mean several addresses will be assigned to the interface
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
Makefile
Makefile.in
lxc-macvlan.conf
lxc-no-netns.conf
lxc-phys.conf
lxc-veth.conf
pkgsysconfdir = $(sysconfdir)/$(PACKAGE)
pkgsysconf_DATA = \
lxc-macvlan.conf \
lxc-no-netns.conf \
lxc-phys.conf \
lxc-veth.conf \
lxc-complex-config
noinst_DATA = \
lxc-macvlan.conf.in \
lxc-no-netns.conf.in \
lxc-phys.conf.in \
lxc-veth.conf.in \
lxc-complex-config.in
# Container with network a complex network mixing macvlan, veth and
# physical network devices
lxc.utsname = complex
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:bf
lxc.network.ipv4 = 1.2.3.5/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0
lxc.network.hwaddr = 4a:49:43:49:79:bd
lxc.network.ipv4 = 1.2.3.4/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
lxc.network.type = phys
lxc.network.flags = up
lxc.network.link = dummy0
lxc.network.hwaddr = 4a:49:43:49:79:ff
lxc.network.ipv4 = 1.2.3.6/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297
# Container with network virtualized using the macvlan device driver
lxc.utsname = alpha
lxc.network.type = macvlan
lxc.network.flags = up
lxc.network.link = eth0
lxc.network.hwaddr = 4a:49:43:49:79:bd
lxc.network.ipv4 = 1.2.3.4/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3596
# Container with non-virtualized network
lxc.utsname = delta
# Container with network virtualized using a physical network device with name
# 'eth0'
lxc.utsname = gamma
lxc.network.type = phys
lxc.network.flags = up
lxc.network.link = eth0
lxc.network.hwaddr = 4a:49:43:49:79:ff
lxc.network.ipv4 = 1.2.3.6/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3297
# Container with network virtualized using a pre-configured bridge named br0 and
# veth pair virtual network devices
lxc.utsname = beta
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 4a:49:43:49:79:bf
lxc.network.ipv4 = 1.2.3.5/24
lxc.network.ipv6 = 2003:db8:1:0:214:1234:fe0b:3597
#
# lxc: linux Container library
#
# (C) Copyright IBM Corp. 2007, 2008
#
# Authors:
# Daniel Lezcano <dlezcano at fr.ibm.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
%define _unpackaged_files_terminate_build 0
%define RELEASE 1
%define rel %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE: %RELEASE}
#
# Arguments that can be passed to the rpm builder:
#
# --define 'confargs <extra args to configure args>' (def. '')
#
%{!?confargs: %{expand:%%define confargs ''}}
# What kernel are we building for?
%{!?kernel: %{expand:%%define kernel %(uname -r)}}
%define _prefix /usr
Name: @PACKAGE@
Version: @VERSION@
Release: %{rel}
Packager: <dlezcano@fr.ibm.com>
URL: http://lxc.sourceforge.net
Summary: %name
Group: Applications/System
License: LGPL
Source: %name/%name-%version.tar.gz
BuildRoot: %_tmppath/%name-%version-root
%description
%name is a set of command line to manage containers
%package devel
Release: %{rel}
Summary: development library for %{name}
Group: Application/System
%description devel
The %{name}-devel package contains header files and library needed for development
of containers
%prep
%setup -q
%build
%configure $args
ncpus=`egrep -c "^cpu[0-9]+" /proc/stat || :`
make -j$ncpus
%install
rm -rf %{buildroot}
%makeinstall
%clean
rm -rf %{buildroot}
%post
%files
%defattr(-,root,root)
%{_sysconfdir}/%{name}/*
%{_bindir}/*
%files devel
%defattr(-,root,root)
%{_includedir}/%{name}/*
%{_libdir}/*.a
%changelog
* Sun Aug 3 2008 Daniel Lezcano <dlezcano@fr.ibm.com>
- Initial RPM release.
# Local variables:
# mode: shell-script
# sh-shell: rpm
# end:
Makefile
Makefile.in
config.h
config.h.in
stamp-h1
SUBDIRS = liblxc lxc
Makefile
Makefile.in
liblxc.la
.deps
lib_LIBRARIES = liblxc.a
pkginclude_HEADERS = lxc.h
liblxc_a_SOURCES = \
create.c \
destroy.c \
start.c \
stop.c \
execute.c \
monitor.c \
kill.c \
state.c \
freezer.c \
cgroup.c cgroup.h \
lxc.h \
utils.h \
lock.c lock.h \
namespace.h \
network.c network.h \
conf.c conf.h \
list.h \
state.c state.h \
log.c log.h \
\
nl.c nl.h \
rtnl.c rtnl.h \
genl.c genl.h
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <mntent.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/inotify.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <log.h>
#define MAXPRIOLEN 24
#define MTAB "/etc/mtab"
static int get_cgroup_mount(const char *mtab, char *mnt)
{
struct mntent *mntent;
FILE *file = NULL;
int err = -1;
file = setmntent(mtab, "r");
if (!file) {
lxc_log_syserror("failed to open %s", mtab);
goto out;
}
while ((mntent = getmntent(file))) {
if (strcmp(mntent->mnt_fsname, "cgroup"))
continue;
strcpy(mnt, mntent->mnt_dir);
err = 0;
break;
};
fclose(file);
out:
return err;
}
int lxc_link_nsgroup(const char *name, pid_t pid)
{
char *lxc, *nsgroup, cgroup[MAXPATHLEN];
int ret;
if (get_cgroup_mount(MTAB, cgroup)) {
lxc_log_info("cgroup is not mounted");
return -1;
}
asprintf(&lxc, LXCPATH "/%s/nsgroup", name);
asprintf(&nsgroup, "%s/%d", cgroup, pid);
ret = symlink(nsgroup, lxc);
if (ret)
lxc_log_syserror("failed to create symlink %s->%s",
nsgroup, lxc);
free(lxc);
free(nsgroup);
return ret;
}
int lxc_unlink_nsgroup(const char *name)
{
char *nsgroup;
int ret;
asprintf(&nsgroup, LXCPATH "/%s/nsgroup", name);
ret = unlink(nsgroup);
free(nsgroup);
return ret;
}
int lxc_set_priority(const char *name, int priority)
{
int fd;
char *path = NULL, *prio = NULL;
asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name);
fd = open(path, O_WRONLY);
if (fd < 0) {
lxc_log_syserror("failed to open '%s'", path);
goto out;
}
asprintf(&prio, "%d", priority);
if (write(fd, prio, strlen(prio) + 1) < 0) {
lxc_log_syserror("failed to write to '%s'", path);
close(fd);
goto out;
}
close(fd);
out:
free(path);
free(prio);
return 0;
}
int lxc_get_priority(const char *name, int *priority)
{
int fd, ret = -1;
char *path, prio[MAXPRIOLEN];
asprintf(&path, LXCPATH "/%s/nsgroup/cpu.shares", name);
fd = open(path, O_RDONLY);
if (fd < 0) {
lxc_log_syserror("failed to open '%s'", path);
goto out;
}
if (read(fd, prio, MAXPRIOLEN) < 0) {
lxc_log_syserror("failed to read from '%s'", path);
close(fd);
goto out;
}
close(fd);
*priority = atoi(prio);
ret = 0;
out:
free(path);
return 0;
}
int lxc_set_memory(const char *name, size_t memmax)
{
return 0;
}
int lxc_get_memory(const char *name, size_t *memmax)
{
return 0;
}
int lxc_get_memstat(const char *name, struct lxc_mem_stat *memstat)
{
return 0;
}
int lxc_set_cpuset(const char *name, long *cpumask, int len, int shared)
{
return 0;
}
int lxc_get_cpuset(const char *name, long *cpumask, int len, int *shared)
{
return 0;
}
int lxc_get_cpu_usage(const char *name, long long *usage)
{
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _cgroup_h
#define _cgroup_h
int lxc_get_cgroup_mount(const char *mtab, char *mnt);
int lxc_link_nsgroup(const char *name, pid_t pid);
int lxc_unlink_nsgroup(const char *name);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _conf_h
#define _conf_h
enum {
VETH,
MACVLAN,
PHYS,
MAXCONFTYPE,
};
/*
* Defines the structure to configure an ipv4 address
* @address : ipv4 address
* @broadcast : ipv4 broadcast address
* @mask : network mask
*/
struct inetdev {
struct in_addr addr;
struct in_addr bcast;
int prefix;
};
struct route {
struct in_addr addr;
};
/*
* Defines the structure to configure an ipv6 address
* @flags : set the address up
* @address : ipv6 address
* @broadcast : ipv6 broadcast address
* @mask : network mask
*/
struct inet6dev {
struct in6_addr addr;
struct in6_addr bcast;
struct in6_addr acast;
int prefix;
};
struct route6 {
struct in6_addr addr;
};
/*
* Defines a structure to configure a network device
* @ifname : network device name
* @flags : flag of the network device (IFF_UP, ... )
* @ipv4 : a list of ipv4 addresses to be set on the network device
* @ipv6 : a list of ipv6 addresses to be set on the network device
*/
struct netdev {
int flags;
char *ifname;
char *newname;
char *hwaddr;
struct list ipv4;
struct list ipv6;
struct list route4;
struct list route6;
};
/*
* Defines the kind of the network to use
* @type : the type of the network virtualization
* @phys : phys configuration type
* @veth : veth configuration type
* @macvlan : macvlan configuration type
*/
struct network {
int type;
struct list netdev;
};
/*
* Defines a structure to configure the control data and path
*/
struct cgroup {
;
};
/*
* Defines the global container configuration
* @chroot : the root directory to run the container
* @mount : the list of mount points
* @network : the network configuration
* @utsname : the container utsname
*/
struct lxc_conf {
char *chroot;
char *fstab;
struct utsname *utsname;
struct cgroup *cgroup;
struct list networks;
};
/*
* Configure the external resources for the container
*/
extern int lxc_configure(const char *name, struct lxc_conf *conf);
/*
* Remove the resources created by the configuration
*/
extern int lxc_unconfigure(const char *name);
extern int conf_create_network(const char *name, pid_t pid);
extern int conf_destroy_network(const char *name);
/*
* Configure the container from inside
*/
extern int lxc_setup(const char *name);
extern int conf_has(const char *name, const char *info);
#define conf_has_fstab(__name) conf_has(__name, "fstab")
#define conf_has_utsname(__name) conf_has(__name, "utsname")
#define conf_has_network(__name) conf_has(__name, "network")
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/inotify.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <list.h>
#include <conf.h>
#include <lock.h>
#include <log.h>
static int dir_filter(const struct dirent *dirent)
{
if (!strcmp(dirent->d_name, ".") ||
!strcmp(dirent->d_name, ".."))
return 0;
return 1;
}
static int is_empty_directory(const char *dirname)
{
struct dirent **namelist;
int n;
n = scandir(dirname, &namelist, dir_filter, alphasort);
if (n < 0)
lxc_log_syserror("failed to scan %s directory", dirname);
return n == 0;
}
static int create_lxc_directory(const char *dirname)
{
char path[MAXPATHLEN];
if (mkdir(LXCPATH, 0755) && errno != EEXIST) {
lxc_log_syserror("failed to created %s directory", LXCPATH);
return -1;
}
sprintf(path, LXCPATH "/%s", dirname);
if (mkdir(path, 0755)) {
lxc_log_syserror("failed to created %s directory", path);
return -1;
}
return 0;
}
static int remove_lxc_directory(const char *dirname)
{
char path[MAXPATHLEN];
sprintf(path, LXCPATH "/%s", dirname);
if (rmdir(path)) {
lxc_log_syserror("failed to remove %s directory", path);
return -1;
}
if (is_empty_directory(LXCPATH)) {
if (rmdir(LXCPATH)) {
lxc_log_syserror("failed to remove %s directory", LXCPATH);
return -1;
}
}
return 0;
}
int lxc_create(const char *name, struct lxc_conf *conf)
{
int lock, err = -1;
if (create_lxc_directory(name)) {
lxc_log_error("failed to create %s directory", name);
return -1;
}
lock = lxc_get_lock(name);
if (!lock) {
lxc_log_error("'%s' is busy", name);
goto err;
}
if (lock < 0) {
lxc_log_error("failed to acquire lock on '%s':%s",
name, strerror(-lock));
goto err;
}
if (mkstate(name)) {
lxc_log_error("failed to create the state file for %s", name);
goto err;
}
if (lxc_setstate(name, STOPPED)) {
lxc_log_error("failed to set state for %s", name);
goto err_state;
}
if (lxc_configure(name, conf)) {
lxc_log_error("failed to set configuration for %s", name);
goto err_state;
}
err = 0;
out:
lxc_put_lock(lock);
return err;
err_state:
lxc_unconfigure(name);
if (rmstate(name))
lxc_log_error("failed to remove state file for %s", name);
err:
if (remove_lxc_directory(name))
lxc_log_error("failed to cleanup lxc directory for %s", name);
goto out;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/inotify.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <list.h>
#include <conf.h>
#include <log.h>
#include <lock.h>
static int dir_filter(const struct dirent *dirent)
{
if (!strcmp(dirent->d_name, ".") ||
!strcmp(dirent->d_name, ".."))
return 0;
return 1;
}
static int is_empty_directory(const char *dirname)
{
struct dirent **namelist;
int n;
n = scandir(dirname, &namelist, dir_filter, alphasort);
if (n < 0)
lxc_log_syserror("failed to scan %s directory", dirname);
return n == 0;
}
static int remove_lxc_directory(const char *dirname)
{
char path[MAXPATHLEN];
sprintf(path, LXCPATH "/%s", dirname);
if (rmdir(path)) {
lxc_log_syserror("failed to remove %s directory", path);
return -1;
}
if (is_empty_directory(LXCPATH)) {
if (rmdir(LXCPATH)) {
lxc_log_syserror("failed to remove %s directory", LXCPATH);
return -1;
}
}
return 0;
}
int lxc_destroy(const char *name)
{
int ret = -1, lock;
lock = lxc_get_lock(name);
if (!lock) {
lxc_log_error("'%s' is busy", name);
goto out;
}
if (lock < 0) {
lxc_log_error("failed to acquire the lock for '%s':%s",
name, strerror(-lock));
goto out;
}
if (rmstate(name)) {
lxc_log_error("failed to remove state file for %s", name);
goto out_lock;
}
if (lxc_unconfigure(name)) {
lxc_log_error("failed to cleanup %s", name);
goto out_lock;
}
if (remove_lxc_directory(name)) {
lxc_log_syserror("failed to remove '%s'", name);
goto out_lock;
}
ret = 0;
out_lock:
lxc_put_lock(lock);
out:
return ret;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <sys/mount.h>
#include <netinet/in.h>
#include <net/if.h>
#include <list.h>
#include <conf.h>
#include <log.h>
#include <lxc.h>
#include <lock.h>
#include <state.h>
#include <cgroup.h>
#include <namespace.h>
#include <utils.h>
LXC_TTY_HANDLER(SIGINT);
LXC_TTY_HANDLER(SIGQUIT);
int lxc_execute(const char *name, int argc, char *argv[],
lxc_callback_t preexec, void *data)
{
char *init = NULL, *val = NULL, *vinit = "[vinit]";
int fd, lock, sv[2], sync = 0, err = -1;
pid_t pid;
int clone_flags;
lock = lxc_get_lock(name);
if (!lock) {
lxc_log_error("'%s' is busy", name);
return -1;
}
if (lock < 0) {
lxc_log_error("failed to acquire lock on '%s':%s",
name, strerror(-lock));
return -1;
}
fcntl(lock, F_SETFD, FD_CLOEXEC);
if (lxc_setstate(name, STARTING)) {
lxc_log_error("failed to set state %s", state2str(STARTING));
goto out;
}
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
lxc_log_syserror("failed to create communication socketpair");
goto err;
}
LXC_TTY_ADD_HANDLER(SIGINT);
LXC_TTY_ADD_HANDLER(SIGQUIT);
clone_flags = CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
if (conf_has_utsname(name))
clone_flags |= CLONE_NEWUTS;
if (conf_has_network(name))
clone_flags |= CLONE_NEWNET;
pid = fork_ns(clone_flags);
if (pid < 0) {
lxc_log_syserror("failed to fork into a new namespace");
goto err_fork_ns;
}
if (!pid) {
pid = fork();
if (pid < 0) {
lxc_log_syserror("failed to fork");
return 1;
}
if (!pid) {
close(sv[1]);
fcntl(sv[0], F_SETFD, FD_CLOEXEC);
if (write(sv[0], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to write socket");
return 1;
}
if (read(sv[0], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to read socket");
return 1;
}
if (lxc_setup(name)) {
lxc_log_error("failed to setup the container");
goto error;
}
if (mount("proc", "/proc", "proc", 0, NULL)) {
lxc_log_error("failed to mount '/proc'");
goto error;
}
if (mount("sysfs", "/sys", "sysfs", 0, NULL)) {
lxc_log_syserror("failed to mount '/sys'");
/* continue: non fatal error until sysfs not per
namespace */
}
if (preexec)
if (preexec(name, argc, argv, data)) {
lxc_log_error("preexec callback has failed");
return -1;
}
execvp(argv[0], argv);
error:
lxc_log_syserror("failed to exec %s", argv[0]);
if (write(sv[0], &sync, sizeof(sync)) < 0)
lxc_log_syserror("failed to write the socket");
return 1;
}
setsid();
close(0);
close(1);
close(2);
if (prctl(PR_SET_NAME, vinit, 0, 0, 0))
lxc_log_syserror("failed to set process name");
close(sv[0]);
close(sv[1]);
for (;;) {
int status;
if (wait(&status) < 0) {
if (errno == ECHILD)
return 0;
if (errno == EINTR)
continue;
lxc_log_syserror("failed to wait child");
return 1;
}
}
}
close(sv[0]);
if (read(sv[1], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to read the socket");
goto err_pipe_read;
}
if (clone_flags & CLONE_NEWNET && conf_create_network(name, pid)) {
lxc_log_error("failed to create the configured network");
goto err_create_network;
}
if (write(sv[1], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to write the socket");
goto err_pipe_write;
}
err = read(sv[1], &sync, sizeof(sync));
if (err < 0) {
lxc_log_error("failed to read the socket");
goto err_pipe_read2;
}
if (err > 0) {
lxc_log_error("something went wrong with %d", pid);
/* TODO : check status etc ... */
waitpid(pid, NULL, 0);
goto err_child_failed;
}
asprintf(&init, LXCPATH "/%s/init", name);
fd = open(init, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
if (fd < 0) {
lxc_log_syserror("failed to open %s", init);
goto err_open;
}
asprintf(&val, "%d", pid);
if (write(fd, val, strlen(val)) < 0) {
lxc_log_syserror("failed to write init pid");
goto err_write;
}
if (lxc_link_nsgroup(name, pid))
lxc_log_warning("cgroupfs not found: cgroup disabled");
if (lxc_setstate(name, RUNNING)) {
lxc_log_error("failed to set state to %s", state2str(RUNNING));
goto err_state_failed;
}
wait_again:
if (waitpid(pid, NULL, 0) < 0) {
if (errno == EINTR)
goto wait_again;
lxc_log_syserror("failed to wait the pid %d", pid);
goto err_waitpid_failed;
}
if (lxc_setstate(name, STOPPING))
lxc_log_error("failed to set state %s", state2str(STOPPING));
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
lxc_log_error("failed to destroy the network");
err = 0;
out:
if (lxc_setstate(name, STOPPED))
lxc_log_error("failed to set state %s", state2str(STOPPED));
lxc_unlink_nsgroup(name);
unlink(init);
free(init);
free(val);
lxc_put_lock(lock);
return err;
err_write:
close(fd);
err_state_failed:
err_child_failed:
err_pipe_read2:
err_pipe_write:
conf_destroy_network(name);
err_create_network:
err_pipe_read:
err_open:
err_waitpid_failed:
if (lxc_setstate(name, ABORTING))
lxc_log_error("failed to set state %s", state2str(STOPPED));
kill(pid, SIGKILL);
err_fork_ns:
LXC_TTY_DEL_HANDLER(SIGQUIT);
LXC_TTY_DEL_HANDLER(SIGINT);
close(sv[0]);
close(sv[1]);
err:
goto out;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/inotify.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <log.h>
static int freeze_unfreeze(const char *name, int freeze)
{
char *freezer, *f = freeze?"FROZEN":"RUNNING";
int fd, ret = -1;
asprintf(&freezer, LXCPATH "/%s/nsgroup/freezer.state", name);
fd = open(freezer, O_WRONLY);
if (fd < 0) {
lxc_log_syserror("failed to open freezer for '%s'", name);
goto out;
}
ret = write(fd, f, strlen(f) + 1) < 0;
close(fd);
if (ret)
lxc_log_syserror("failed to write to '%s'", freezer);
out:
free(freezer);
return ret;
}
int lxc_freeze(const char *name)
{
return freeze_unfreeze(name, 1);
}
int lxc_unfreeze(const char *name)
{
return freeze_unfreeze(name, 0);
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <linux/genetlink.h>
#include <linux/rtnetlink.h>
#include <nl.h>
#include <genl.h>
static int genetlink_resolve_family(const char *family)
{
struct nl_handler handler;
struct nlattr *attr;
struct genlmsg *request, *reply;
struct genlmsghdr *genlmsghdr;
int len, ret;
request = genlmsg_alloc(GENLMSG_GOOD_SIZE);
if (!request)
return -ENOMEM;
reply = genlmsg_alloc(GENLMSG_GOOD_SIZE);
if (!reply) {
genlmsg_free(request);
return -ENOMEM;
}
request->nlmsghdr.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN);
request->nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
request->nlmsghdr.nlmsg_type = GENL_ID_CTRL;
genlmsghdr = NLMSG_DATA(&request->nlmsghdr);
genlmsghdr->cmd = CTRL_CMD_GETFAMILY;
ret = netlink_open(&handler, NETLINK_GENERIC);
if (ret)
return ret;
ret = nla_put_string((struct nlmsg *)&request->nlmsghdr,
CTRL_ATTR_FAMILY_NAME, family);
if (ret)
goto out;
ret = netlink_transaction(&handler, (struct nlmsg *)&request->nlmsghdr,
(struct nlmsg *)&reply->nlmsghdr);
if (ret < 0)
goto out;
genlmsghdr = NLMSG_DATA(&reply->nlmsghdr);
len = reply->nlmsghdr.nlmsg_len;
ret = -ENOMSG;
if (reply->nlmsghdr.nlmsg_type != GENL_ID_CTRL)
goto out;
if (genlmsghdr->cmd != CTRL_CMD_NEWFAMILY)
goto out;
ret = -EMSGSIZE;
len -= NLMSG_LENGTH(GENL_HDRLEN);
if (len < 0)
goto out;
attr = (struct nlattr *)GENLMSG_DATA(reply);
attr = (struct nlattr *)((char *)attr + NLA_ALIGN(attr->nla_len));
ret = -ENOMSG;
if (attr->nla_type != CTRL_ATTR_FAMILY_ID)
goto out;
ret = *(__u16 *) NLA_DATA(attr);
out:
genlmsg_free(request);
genlmsg_free(reply);
netlink_close(&handler);
return ret;
}
extern int genetlink_open(struct genl_handler *handler, const char *family)
{
int ret;
handler->family = genetlink_resolve_family(family);
if (handler->family < 0)
return handler->family;
ret = netlink_open(&handler->nlh, NETLINK_GENERIC);
return ret;
}
extern int genetlink_close(struct genl_handler *handler)
{
return netlink_close(&handler->nlh);
}
extern int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg)
{
return netlink_rcv(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
}
extern int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg)
{
return netlink_send(&handler->nlh, (struct nlmsg *)&genlmsg->nlmsghdr);
}
extern int genetlink_transaction(struct genl_handler *handler,
struct genlmsg *request, struct genlmsg *answer)
{
return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr,
(struct nlmsg *)&answer->nlmsghdr);
}
extern struct genlmsg *genlmsg_alloc(size_t size)
{
size_t len = NLMSG_LENGTH(GENL_HDRLEN) + size;
return (struct genlmsg *)nlmsg_alloc(len);
}
extern void genlmsg_free(struct genlmsg *genlmsg)
{
free(genlmsg);
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef __genl_h
#define __genl_h
/*
* Use this as a good size to allocate generic netlink messages
*/
#define GENLMSG_GOOD_SIZE NLMSG_GOOD_SIZE
#define GENLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + GENL_HDRLEN))
/*
* struct genl_handler : the structure which store the netlink handler
* and the family number resulting of the auto-generating id family
* for the generic netlink protocol
*
* @nlh: the netlink socket handler
* @family: the generic netlink family assigned number
*/
struct genl_handler
{
struct nl_handler nlh;
int family;
};
/*
* struct genlmsg : the struct containing the generic netlink message
* format
*
* @nlmsghdr: a netlink message header
* @genlmsghdr: a generic netlink message header pointer
*
*/
/* __attribute__ ((aligned(4))); */
struct genlmsg {
struct nlmsghdr nlmsghdr;
struct genlmsghdr genlmsghdr;
};
static inline int genetlink_len(const struct genlmsg *genlmsg)
{
return ((genlmsg->nlmsghdr.nlmsg_len) - GENL_HDRLEN - NLMSG_HDRLEN);
}
/*
* genetlink_open : resolve family number id and open a generic netlink socket
*
* @handler: a struct genl_handler pointer
* @family: the family name of the generic netlink protocol
*
* Returns 0 on success, < 0 otherwise
*/
int genetlink_open(struct genl_handler *handler, const char *family);
/*
* genetlink_close : close a generic netlink socket
*
* @handler: the handler of the socket to be closed
*
* Returns 0 on success, < 0 otherwise
*/
int genetlink_close(struct genl_handler *handler);
/*
* genetlink_rcv : receive a generic netlink socket, it is up
* to the caller to manage the allocation of the generic netlink message
*
* @handler: the handler of the generic netlink socket
* @genlmsg: the pointer to a generic netlink message pre-allocated
*
* Returns 0 on success, < 0 otherwise
*/
int genetlink_rcv(struct genl_handler *handler, struct genlmsg *genlmsg);
/*
* genetlink_send : send a generic netlink socket, it is up
* to the caller to manage the allocation of the generic netlink message
*
* @handler: the handler of the generic netlink socket
* @genlmsg: the pointer to a generic netlink message pre-allocated
*
* Returns 0 on success, < 0 otherwise
*/
int genetlink_send(struct genl_handler *handler, struct genlmsg *genlmsg);
struct genlmsg *genlmsg_alloc(size_t size);
void genlmsg_free(struct genlmsg *genlmsg);
/*
* genetlink_transaction : send and receive a generic netlink message in one shot
*
* @handler: the handler of the generic netlink socket
* @request: a generic netlink message containing the request to be sent
* @answer: a pre-allocated generic netlink message to receive the response
*
* Returns 0 on success, < 0 otherwise
*/
int genetlink_transaction(struct genl_handler *handler,
struct genlmsg *request, struct genlmsg *answer);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <list.h>
#include <conf.h>
#include <log.h>
int lxc_kill(const char *name, int signum)
{
char *freezer = NULL, *signal = NULL;
int fd = -1, ret = -1;
if (signum < SIGHUP || signum > SIGRTMAX) {
lxc_log_error("bad signal value %d", signum);
goto out;
}
asprintf(&freezer, LXCPATH "/%s/nsgroup/freezer.kill", name);
asprintf(&signal, "%d", signum);
fd = open(freezer, O_WRONLY);
if (fd < 0) {
lxc_log_syserror("failed to open %s for %s", freezer, name);
goto out;
}
if (write(fd, &signal, strlen(signal)) < 0) {
lxc_log_syserror("failed to write to %s", freezer);
goto out;
}
ret = 0;
out:
close(fd);
free(freezer);
free(signal);
return ret;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <list.h>
#ifndef _list_h
#define _list_h
struct list {
void *elem;
struct list *next;
struct list *prev;
};
#define init_list(l) { .next = l, .prev = l, }
#define list_for_each(__iterator, __list) \
for (__iterator = (__list)->next; \
__iterator != __list; \
__iterator = __iterator->next)
static inline void list_init(struct list *list)
{
list->elem = NULL;
list->next = list->prev = list;
}
static inline void list_add_elem(struct list *list, void *elem)
{
list->elem = elem;
}
static inline void *list_first_elem(struct list *list)
{
return list->next->elem;
}
static inline int list_empty(struct list *list)
{
return list == list->next;
}
static inline void list_add(struct list *list, struct list *new)
{
struct list *next = list->next;
next->prev = new;
new->next = next;
new->prev = list;
list->next = new;
}
static inline void list_del(struct list *list)
{
struct list *next, *prev;
next = list->next;
prev = list->prev;
next->prev = prev;
prev->next = next;
}
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h>
#include <lxc.h>
int lxc_get_lock(const char *name)
{
char *lock;
int fd, ret;
asprintf(&lock, LXCPATH "/%s", name);
fd = open(lock, O_RDONLY|O_DIRECTORY, S_IRUSR|S_IWUSR);
if (fd < 0) {
ret = -errno;
goto out;
}
if (flock(fd, LOCK_EX|LOCK_NB)) {
ret = errno == EWOULDBLOCK ? 0 : -errno;
close(fd);
goto out;
}
ret = fd;
out:
free(lock);
return ret;
}
void lxc_put_lock(int lock)
{
flock(lock, LOCK_UN);
close(lock);
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _lock_h
#define _lock_h
extern int lxc_get_lock(const char *name);
extern int lxc_put_lock(int lock);
#endif
#include <stdio.h>
#include <errno.h>
#include <stdarg.h>
#include <log.h>
#define MAXTIMELEN 47;
#define ERRNO_FORMAT "%d (%s)"
#ifndef _log_h
#define _log_h
#define lxc_log(format, level, ...) do { \
fprintf(stderr, "[%s] \t%s:%d - " format "\n", \
level, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define lxc_log_error(format, ...) lxc_log(format, "error", ##__VA_ARGS__);
#define lxc_log_warning(format, ...) lxc_log(format, "warning", ##__VA_ARGS__);
#define lxc_log_info(format, ...) lxc_log(format, "info", ##__VA_ARGS__);
#define lxc_log_debug(format, ...) lxc_log(format, "debug", ##__VA_ARGS__);
#define lxc_log_trace(format, ...) lxc_log(format, "trace", ##__VA_ARGS__);
#define lxc_log_syserror(format, ...) do { \
fprintf(stderr, "[SYSERROR][%s] \t%s:%d - " format "\n", \
strerror(errno),__FUNCTION__, __LINE__, \
##__VA_ARGS__); \
} while (0)
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef __lxc_h
#define __lxc_h
/**
Following code is for liblxc.
liblxc/lxc.h will contain exports of liblxc
**/
#define LXCPATH "/var/lxc"
#define MAXPIDLEN 20
struct lxc_mem_stat;
struct lxc_conf;
typedef enum {
STOPPED, STARTING, RUNNING, STOPPING,
ABORTING, FREEZING, FROZEN, MAX_STATE,
} lxc_state_t;
typedef int (*lxc_callback_t)(const char *name, int argc,
char *argv[], void *data);
/*
* Create the container object. Creates the /lxc/<name> directory
* and fills it with the files corresponding to the configuration
* structure passed as parameter.
* The first container will create the /lxc directory.
* @name : the name of the container
* @conf : the configuration data for the container
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_create(const char *name, struct lxc_conf *conf);
/*
* Destroy the container object. Removes the files into the /lxc/<name>
* directory and removes the <name> directory.
* The last container will remove the /lxc directory.
* @name : the name of the container to be detroyed
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_destroy(const char *name);
/*
* Start the container previously created with lxc_create.
* @name : the name of the container
* @argc : the number of arguments of the command line
* @argv : an array of char * corresponding to the commande line
* @prestart : hooks will be called just before the command execs
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_start(const char *name, int argc, char *argv[],
lxc_callback_t prestart, void *data);
/*
* Create the container and start it directly, using the argc, argv
* parameter. This command is for application container.
* At the end of the exec'ed command, the container will
* automatically autodestroy.
* @name : the name of the container
* @conf : the configuration data
* @argc : the number of arguments of the command line
* @argv : an array of char * corresponding to the commande line
* @preexec : hooks will be called just before the command execs
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_execute(const char *name, int argc, char *argv[],
lxc_callback_t preexec, void *data);
/*
* Stop the container previously started with lxc_start or lxc_exec
* @name : the name of the container
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_stop(const char *name);
/*
* Monitor the container, each time the state of the container
* is changed, a state data is send through a file descriptor passed to
* the function with output_fd.
* The function will block until the container is destroyed.
* @name : the name of the contaier
* @output_fd : the file descriptor where to send the states
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_monitor(const char *name, int output_fd);
/*
* Show the console of the container.
* @name : the name of container
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_console(const char *name);
/*
* Freeze all the tasks running inside the container <name>
* @name : the container name
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_freeze(const char *name);
/*
* Unfreeze all previously frozen tasks.
* @name : the name of the container
* Return 0 on sucess, < 0 otherwise
*/
extern int lxc_unfreeze(const char *name);
/*
* Retrieve the container state
* @name : the name of the container
* Returns the state of the container on success, < 0 otherwise
*/
extern lxc_state_t lxc_state(const char *name);
/*
* Send a signal to all processes of the container. This is the same
* behavior of the well-known 'killpg' command except it is related
* to all tasks belonging to a container.
* @name : the name of the container
* @signum : the signal number to be sent
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_kill(const char *name, int signum);
/*
* Change the priority of the container
* @name : the name of the container
* @priority : an integer representing the desired priority
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_cgroup_set_priority(const char *name, int priority);
/*
* Retrieve the priority of the container
* @name : the name of the container
* @priority : a pointer to an int where the priority will be stored
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_cgroup_get_priority(const char *name, int *priority);
/*
* Set the maximum memory usable by the container
* @name : the name of the container
* @memmax : the maximum usable memory in bytes
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_set_memory(const char *name, size_t memmax);
/*
* Get the maximum memory usable by the container
* @name : the name of the container
* @memmax : a pointer to a size_t where the value will be stored
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_get_memory(const char *name, size_t *memmax);
/*
* Get the memory statistics of the container
* @name : the name of the container
* @memstat : a pointer to a structure defining the memory statistic
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_get_memstat(const char *name,
struct lxc_mem_stat *memstat);
/*
* Set the cpuset for the container
* @name : the name of the container
* @cpumask : a bitmask representing the cpu maps
* @len : the len of the bitmask
* @shared : a boolean specifying if the cpu could be shared with
* processes not belonging to the container
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_set_cpuset(const char *name, long *cpumask,
int len, int shared);
/*
* Get the actual cpuset for the container
* @cpumask : a bitmask representing the cpu maps
* @len : the len of the bitmask
* @shared : a boolean specifying if the cpu is shared with
* processes not belonging to the container
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_get_cpuset(const char *name, long *cpumask,
int len, int *shared);
/*
* Get the cpu usage of the container
* @name : the name of the container
* @usage : a value to be filled with the current container cpu usage
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_cgroup_get_cpu_usage(const char *name, long long *usage);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/inotify.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <log.h>
int lxc_monitor(const char *name, int output_fd)
{
char path[MAXPATHLEN];
int err = -1, nfd, wfd, state;
nfd = inotify_init();
if (nfd < 0) {
lxc_log_syserror("failed to initialize inotify");
return -1;
}
snprintf(path, MAXPATHLEN, LXCPATH "/%s/state", name);
wfd = inotify_add_watch(nfd, path, IN_DELETE_SELF|IN_CLOSE_WRITE);
if (wfd < 0) {
lxc_log_syserror("failed to add a watch on %s", path);
goto out;
}
for(;;) {
struct inotify_event evt;
if (read(nfd, &evt, sizeof(evt)) < 0) {
lxc_log_syserror("failed to read inotify event");
goto out;
}
if (evt.mask & IN_CLOSE_WRITE) {
state = lxc_getstate(name);
if (state < 0) {
lxc_log_error("failed to get the state for %s",
name);
goto out;
}
if (write(output_fd, &state, sizeof(state)) < 0) {
lxc_log_syserror("failed to send state to %d",
output_fd);
goto out;
}
continue;
}
if (evt.mask & IN_DELETE_SELF) {
close(output_fd);
err = 0;
goto out;
}
lxc_log_error("unknown evt for inotity (%d)", evt.mask);
goto out;
}
out:
inotify_rm_watch(nfd, wfd);
close(nfd);
return err;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef __namespace_h
#define __namespace_h
#include <syscall.h>
#ifndef CLONE_FS
# define CLONE_FS 0x00000200
#endif
#ifndef CLONE_NEWNS
# define CLONE_NEWNS 0x00020000
#endif
#ifndef CLONE_NEWUTS
# define CLONE_NEWUTS 0x04000000
#endif
#ifndef CLONE_NEWIPC
# define CLONE_NEWIPC 0x08000000
#endif
#ifndef CLONE_NEWUSER
# define CLONE_NEWUSER 0x10000000
#endif
#ifndef CLONE_NEWPID
# define CLONE_NEWPID 0x20000000
#endif
#ifndef CLONE_NEWNET
# define CLONE_NEWNET 0x40000000
#endif
#ifndef __NR_unshare
# ifdef __i386__
# define __NR_unshare 310
# elif __x86_64__
# define __NR_unshare 272
# elif __ia64__
# define __NR_unshare 1296
# elif __s390__
# define __NR_unshare 303
# elif __powerpc__
# define __NR_unshare 282
#else
# error "unsupported architecture"
# endif
#endif
#if __i386__ || __x86_64__ || __s390__ || __powerpc__
# define fork_ns(flags) syscall(SYS_clone, flags|SIGCHLD, NULL);
#elif __ia64__
# define fork_ns(flags) syscall(SYS_clone2, flags|SIGCHLD, NULL);
#else
# error "unsupported architecture"
#endif
#define unshare_ns(flags) syscall(__NR_unshare, flags, NULL);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _network_h
#define _network_h
/*
* Create a macvlan network device
*/
extern int lxc_configure_macvlan(const char *link, const char *peer);
/*
* Create a veth pair virtual device
*/
extern int lxc_configure_veth(const char *veth1, const char *veth2,
const char *bridge);
/*
* Convert a string mac address to a socket structure
*/
extern int lxc_convert_mac(char *macaddr, struct sockaddr *sockaddr);
/*
* Move a device between namespaces
*/
extern int device_move(const char *name, pid_t pid);
/*
* Delete a network device
*/
extern int device_delete(const char *name);
/*
* Set the device network up
*/
extern int device_up(const char *name);
/*
* Set the device network down
*/
extern int device_down(const char *name);
/*
* Change the device name
*/
extern int device_rename(const char *oldname, const char *newname);
/*
* Create a veth network device
*/
extern int veth_create(const char *name1, const char *name2);
/*
* Create a macvlan network device
*/
extern int macvlan_create(const char *master, const char *name);
/*
* Activate forwarding
*/
extern int ip_forward_on(const char *name, int family);
/*
* Disable forwarding
*/
extern int ip_forward_off(const char *name, int family);
/*
* Set ip address
*/
extern int ip_addr_add(const char *ifname, const char *addr,
int prefix, const char *bcast);
extern int ip6_addr_add(const char *ifname, const char *addr,
int prefix, const char *bcast);
/*
* Attach an interface to the bridge
*/
extern int bridge_attach(const char *bridge, const char *ifname);
/*
* Detach an interface from the bridge
*/
extern int bridge_detach(const char *bridge, const char *ifname);
/*
* Create default gateway
*/
extern int route_create_default(const char *addr, const char *ifname, int gateway);
/*
* Delete default gateway
*/
extern int route_delete_default(const char *addr, const char *ifname, int gateway);
/*
* Activate neighbor proxying
*/
extern int neigh_proxy_on(const char *name, int family);
/*
* Disable neighbor proxying
*/
extern int neigh_proxy_off(const char *name, int family);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <nl.h>
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
extern size_t nlmsg_len(const struct nlmsg *nlmsg)
{
return nlmsg->nlmsghdr.nlmsg_len - NLMSG_HDRLEN;
}
extern void *nlmsg_data(struct nlmsg *nlmsg)
{
char *data = ((char *)nlmsg) + NLMSG_ALIGN(sizeof(struct nlmsghdr));
if (!nlmsg_len(nlmsg))
return NULL;
return data;
}
static int nla_put(struct nlmsg *nlmsg, int attr,
const void *data, size_t len)
{
struct rtattr *rta;
size_t rtalen = RTA_LENGTH(len);
rta = NLMSG_TAIL(&nlmsg->nlmsghdr);
rta->rta_type = attr;
rta->rta_len = rtalen;
memcpy(RTA_DATA(rta), data, len);
nlmsg->nlmsghdr.nlmsg_len =
NLMSG_ALIGN(nlmsg->nlmsghdr.nlmsg_len) + RTA_ALIGN(rtalen);
return 0;
}
extern int nla_put_buffer(struct nlmsg *nlmsg, int attr,
const void *data, size_t size)
{
return nla_put(nlmsg, attr, data, size);
}
extern int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string)
{
return nla_put(nlmsg, attr, string, strlen(string) + 1);
}
extern int nla_put_u32(struct nlmsg *nlmsg, int attr, int value)
{
return nla_put(nlmsg, attr, &value, sizeof(value));
}
extern int nla_put_attr(struct nlmsg *nlmsg, int attr)
{
return nla_put(nlmsg, attr, NULL, 0);
}
struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr)
{
struct rtattr *rtattr = NLMSG_TAIL(&nlmsg->nlmsghdr);
if (nla_put_attr(nlmsg, attr))
return NULL;
return rtattr;
}
void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr)
{
attr->rta_len = (void *)NLMSG_TAIL(&nlmsg->nlmsghdr) - (void *)attr;
}
extern struct nlmsg *nlmsg_alloc(size_t size)
{
struct nlmsg *nlmsg;
size_t len = NLMSG_ALIGN(size) + NLMSG_ALIGN(sizeof(struct nlmsghdr *));
nlmsg = (struct nlmsg *)malloc(len);
if (!nlmsg)
return NULL;
memset(nlmsg, 0, len);
nlmsg->nlmsghdr.nlmsg_len = NLMSG_ALIGN(size);
return nlmsg;
}
extern void nlmsg_free(struct nlmsg *nlmsg)
{
free(nlmsg);
}
extern int netlink_rcv(struct nl_handler *handler, struct nlmsg *answer)
{
int ret;
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = answer,
.iov_len = answer->nlmsghdr.nlmsg_len,
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0;
nladdr.nl_groups = 0;
again:
ret = recvmsg(handler->fd, &msg, 0);
if (ret < 0) {
if (errno == EINTR)
goto again;
return -errno;
}
if (!ret)
return 0;
if (msg.msg_flags & MSG_TRUNC)
return -EMSGSIZE;
return ret;
}
extern int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg)
{
struct sockaddr_nl nladdr;
struct iovec iov = {
.iov_base = (void*)nlmsg,
.iov_len = nlmsg->nlmsghdr.nlmsg_len,
};
struct msghdr msg = {
.msg_name = &nladdr,
.msg_namelen = sizeof(nladdr),
.msg_iov = &iov,
.msg_iovlen = 1,
};
int ret;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = 0;
nladdr.nl_groups = 0;
ret = sendmsg(handler->fd, &msg, 0);
if (ret < 0) {
return -errno;
}
return ret;
}
extern int netlink_transaction(struct nl_handler *handler,
struct nlmsg *request, struct nlmsg *answer)
{
int ret;
ret = netlink_send(handler, request);
if (ret < 0)
return ret;
ret = netlink_rcv(handler, answer);
if (ret < 0)
return ret;
if (answer->nlmsghdr.nlmsg_type == NLMSG_ERROR) {
struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(answer);
errno = -err->error;
return -errno;
}
return 0;
}
extern int netlink_open(struct nl_handler *handler, int protocol)
{
socklen_t socklen;
int sndbuf = 32768;
int rcvbuf = 32768;
memset(handler, 0, sizeof(*handler));
handler->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
if (handler->fd < 0)
return -errno;
if (setsockopt(handler->fd, SOL_SOCKET, SO_SNDBUF,
&sndbuf, sizeof(sndbuf)) < 0)
return -errno;
if (setsockopt(handler->fd, SOL_SOCKET, SO_RCVBUF,
&rcvbuf,sizeof(rcvbuf)) < 0)
return -errno;
memset(&handler->local, 0, sizeof(handler->local));
handler->local.nl_family = AF_NETLINK;
handler->local.nl_groups = 0;
if (bind(handler->fd, (struct sockaddr*)&handler->local,
sizeof(handler->local)) < 0)
return -errno;
socklen = sizeof(handler->local);
if (getsockname(handler->fd, (struct sockaddr*)&handler->local,
&socklen) < 0)
return -errno;
if (socklen != sizeof(handler->local))
return -EINVAL;
if (handler->local.nl_family != AF_NETLINK)
return -EINVAL;
handler->seq = time(NULL);
return 0;
}
extern int netlink_close(struct nl_handler *handler)
{
close(handler->fd);
handler->fd = -1;
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef __nl_h
#define __nl_h
/*
* Use this as a good size to allocate generic netlink messages
*/
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#define NLMSG_GOOD_SIZE (2*PAGE_SIZE)
#define NLMSG_TAIL(nmsg) \
((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
#define NLA_DATA(na) ((void *)((char*)(na) + NLA_HDRLEN))
#define NLA_NEXT_ATTR(attr) ((void *)((char *)attr) + NLA_ALIGN(attr->nla_len))
/*
* struct nl_handler : the handler for netlink sockets, this structure
* is used all along the netlink socket life cycle to specify the
* netlink socket to be used.
*
* @fd: the file descriptor of the netlink socket
* @seq: the sequence number of the netlink messages
* @local: the bind address
* @peer: the peer address
*/
struct nl_handler {
int fd;
int seq;
struct sockaddr_nl local;
struct sockaddr_nl peer;
};
/*
* struct nlmsg : the netlink message structure, it consists just
* on a definition for a nlmsghdr. This message is to be used to
* be allocated with netlink_alloc.
* @nlmsghdr : a pointer to a netlink message header, this field
* _must_ be always the first field of this structure
*/
struct nlmsg {
struct nlmsghdr nlmsghdr;
};
/*
* netlink_open : open a netlink socket, the function will
* fill the handler with the right value
*
* @handler: a netlink handler to be used all along the netlink
* socket life cycle
* @protocol: specify the protocol to be used when opening the
* netlink socket
*
* Return 0 on success, < 0 otherwise
*/
int netlink_open(struct nl_handler *handler, int protocol);
/*
* netlink_close : close a netlink socket, after this call,
* the handler is no longer valid
*
* @handler: a handler to the netlink socket
*
* Returns 0 on success, < 0 otherwise
*/
int netlink_close(struct nl_handler *handler);
/*
* netlink_rcv : receive a netlink message from the kernel.
* It is up to the caller to manage the allocation of the
* netlink message
*
* @handler: a handler to the netlink socket
* @nlmsg: a netlink message
*
* Returns 0 on success, < 0 otherwise
*/
int netlink_rcv(struct nl_handler *handler, struct nlmsg *nlmsg);
/*
* netlink_send: send a netlink message to the kernel. It is up
* to the caller to manage the allocate of the netlink message
*
* @handler: a handler to the netlink socket
* @nlmsg: a netlink message
*
* Returns 0 on success, < 0 otherwise
*/
int netlink_send(struct nl_handler *handler, struct nlmsg *nlmsg);
/*
* netlink_transaction: send a request to the kernel and read the response.
* This is useful for transactional protocol. It is up to the caller
* to manage the allocation of the netlink message.
*
* @handler: a handler to a opened netlink socket
* @request: a netlink message pointer containing the request
* @answer: a netlink message pointer to receive the result
*
* Returns 0 on success, < 0 otherwise
*/
int netlink_transaction(struct nl_handler *handler,
struct nlmsg *request, struct nlmsg *anwser);
/*
* nla_put_string: copy a null terminated string to a netlink message
* attribute
*
* @nlmsg: the netlink message to be filled
* @attr: the attribute name of the string
* @string: a null terminated string to be copied to the netlink message
*
* Returns 0 on success, < 0 otherwise
*/
int nla_put_string(struct nlmsg *nlmsg, int attr, const char *string);
/*
* nla_put_buffer: copy a buffer with a specified size to a netlink
* message attribute
*
* @nlmsg: the netlink message to be filled
* @attr: the attribute name of the string
* @data: a pointer to a buffer
* @size: the size of the buffer
*
* Returns 0 on success, < 0 otherwise
*/
int nla_put_buffer(struct nlmsg *nlmsg, int attr,
const void *data, size_t size);
/*
* nla_put_u32: copy an integer to a netlink message attribute
*
* @nlmsg: the netlink message to be filled
* @attr: the attribute name of the integer
* @string: an integer to be copied to the netlink message
*
* Returns 0 on success, < 0 otherwise
*/
int nla_put_u32(struct nlmsg *nlmsg, int attr, int value);
/*
* nla_put_attr: add an attribute name to a netlink
*
* @nlmsg: the netlink message to be filled
* @attr: the attribute name of the integer
*
* Returns 0 on success, < 0 otherwise
*/
int nla_put_attr(struct nlmsg *nlmsg, int attr);
/*
* nla_begin_nested: begin the nesting attribute
*
* @nlmsg: the netlink message to be filled
* @attr: the netsted attribute name
*
* Returns current nested pointer to be reused
* to nla_end_nested.
*/
struct rtattr *nla_begin_nested(struct nlmsg *nlmsg, int attr);
/*
* nla_end_nested: end the nesting attribute
*
* @nlmsg: the netlink message
* @nested: the nested pointer
*
* Returns the current
*/
void nla_end_nested(struct nlmsg *nlmsg, struct rtattr *attr);
/*
* nlmsg_allocate : allocate a netlink message. The netlink format message
* is a header, a padding, a payload and a padding again.
* When a netlink message is allocated, the size specify the
* payload we want. So the real size of the allocated message
* is sizeof(header) + sizeof(padding) + payloadsize + sizeof(padding),
* in other words, the function will allocate more than specified. When
* the buffer is allocated, the content is zeroed.
* The function will also fill the field nlmsg_len with computed size.
* If the allocation must be for the specified size, just use malloc.
*
* @size: the size of the payload to be allocated
*
* Returns a pointer to the newly allocated netlink message, NULL otherwise
*/
struct nlmsg *nlmsg_alloc(size_t size);
/*
* nlmsg_free : free a previously allocate message
*
* @nlmsg: the netlink message to be freed
*/
void nlmsg_free(struct nlmsg *nlmsg);
/*
* nlmsg_data : returns a pointer to the data contained in the netlink message
*
* @nlmsg : the netlink message to get the data
*
* Returns a pointer to the netlink data or NULL if there is no data
*/
void *nlmsg_data(struct nlmsg *nlmsg);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <nl.h>
#include <rtnl.h>
extern int rtnetlink_open(struct rtnl_handler *handler)
{
return netlink_open(&handler->nlh, NETLINK_ROUTE);
}
extern int rtnetlink_close(struct rtnl_handler *handler)
{
return netlink_close(&handler->nlh);
}
extern int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg)
{
return netlink_rcv(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr);
}
extern int rtnetlink_send(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg)
{
return netlink_send(&handler->nlh, (struct nlmsg *)&rtnlmsg->nlmsghdr);
}
extern int rtnetlink_transaction(struct rtnl_handler *handler,
struct rtnlmsg *request, struct rtnlmsg *answer)
{
return netlink_transaction(&handler->nlh, (struct nlmsg *)&request->nlmsghdr,
(struct nlmsg *)&answer->nlmsghdr);
}
extern struct rtnlmsg *rtnlmsg_alloc(size_t size)
{
/* size_t len = NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct rtnlmsghdr))) + size; */
/* return (struct rtnlmsg *)nlmsg_alloc(len); */
return NULL;
}
extern void rtnlmsg_free(struct rtnlmsg *rtnlmsg)
{
free(rtnlmsg);
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef __genl_h
#define __genl_h
/*
* Use this as a good size to allocate route netlink messages
*/
#define RTNLMSG_GOOD_SIZE NLMSG_GOOD_SIZE
#define RTNLMSG_DATA(glh) ((void *)(NLMSG_DATA(glh) + RTNL_HDRLEN))
/*
* struct genl_handler : the structure which store the netlink handler
* and the family number
*
* @nlh: the netlink socket handler
*/
struct rtnl_handler
{
struct nl_handler nlh;
};
/*
* struct rtnlmsg : the struct containing the route netlink message
* format
*
* @nlmsghdr: a netlink message header
* @rtnlmsghdr: a route netlink message header pointer
*
*/
struct rtnlmsg {
struct nlmsghdr nlmsghdr;
};
/*
* rtnetlink_open : open a route netlink socket
*
* @handler: a struct rtnl_handler pointer
*
* Returns 0 on success, < 0 otherwise
*/
int rtnetlink_open(struct rtnl_handler *handler);
/*
* genetlink_close : close a route netlink socket
*
* @handler: the handler of the socket to be closed
*
* Returns 0 on success, < 0 otherwise
*/
int rtnetlink_close(struct rtnl_handler *handler);
/*
* rtnetlink_rcv : receive a route netlink socket, it is up
* to the caller to manage the allocation of the route netlink message
*
* @handler: the handler of the route netlink socket
* @rtnlmsg: the pointer to a route netlink message pre-allocated
*
* Returns 0 on success, < 0 otherwise
*/
int rtnetlink_rcv(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg);
/*
* rtnetlink_send : send a route netlink socket, it is up
* to the caller to manage the allocation of the route netlink message
*
* @handler: the handler of the route netlink socket
* @rtnlmsg: the pointer to a netlink message pre-allocated
*
* Returns 0 on success, < 0 otherwise
*/
int rtnetlink_send(struct rtnl_handler *handler, struct rtnlmsg *rtnlmsg);
struct genlmsg *genlmsg_alloc(size_t size);
void rtnlmsg_free(struct rtnlmsg *rtnlmsg);
/*
* rtnetlink_transaction : send and receive a route netlink message in one shot
*
* @handler: the handler of the route netlink socket
* @request: a route netlink message containing the request to be sent
* @answer: a pre-allocated route netlink message to receive the response
*
* Returns 0 on success, < 0 otherwise
*/
int rtnetlink_transaction(struct rtnl_handler *handler,
struct rtnlmsg *request, struct rtnlmsg *answer);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <mntent.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <namespace.h>
#include <network.h>
#include <state.h>
#include <cgroup.h>
#include <utils.h>
#include <list.h>
#include <conf.h>
#include <log.h>
#include <lock.h>
LXC_TTY_HANDLER(SIGINT);
LXC_TTY_HANDLER(SIGQUIT);
int lxc_start(const char *name, int argc, char *argv[],
lxc_callback_t prestart, void *data)
{
char *init = NULL, *val = NULL;
int fd, lock, sv[2], sync = 0, err = -1;
pid_t pid;
int clone_flags;
lock = lxc_get_lock(name);
if (!lock) {
lxc_log_error("'%s' is busy", name);
return -1;
}
if (lock < 0) {
lxc_log_error("failed to acquire lock on '%s':%s",
name, strerror(-lock));
return -1;
}
fcntl(lock, F_SETFD, FD_CLOEXEC);
/* Begin the set the state to STARTING*/
if (lxc_setstate(name, STARTING)) {
lxc_log_error("failed to set state %s", state2str(STARTING));
goto out;
}
/* Synchro socketpair */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
lxc_log_syserror("failed to create communication socketpair");
goto err;
}
/* Avoid signals from terminal */
LXC_TTY_ADD_HANDLER(SIGINT);
LXC_TTY_ADD_HANDLER(SIGQUIT);
clone_flags = CLONE_NEWPID|CLONE_NEWIPC;
if (conf_has_fstab(name))
clone_flags |= CLONE_NEWNS;
if (conf_has_utsname(name))
clone_flags |= CLONE_NEWUTS;
if (conf_has_network(name))
clone_flags |= CLONE_NEWNET;
/* Create a process in a new set of namespaces */
pid = fork_ns(clone_flags);
if (pid < 0) {
lxc_log_syserror("failed to fork into a new namespace");
goto err_fork_ns;
}
if (!pid) {
close(sv[1]);
/* Be sure we don't inherit this after the exec */
fcntl(sv[0], F_SETFD, FD_CLOEXEC);
/* Tell our father he can begin to configure the container */
if (write(sv[0], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to write socket");
return 1;
}
/* Wait for the father to finish the configuration */
if (read(sv[0], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to read socket");
return 1;
}
/* Setup the container, ip, names, utsname, ... */
if (lxc_setup(name)) {
lxc_log_error("failed to setup the container");
if (write(sv[0], &sync, sizeof(sync)) < 0)
lxc_log_syserror("failed to write the socket");
return -1;
}
/* If a callback has been passed, call it before doing exec */
if (prestart)
if (prestart(name, argc, argv, data)) {
lxc_log_error("prestart callback has failed");
return -1;
}
execvp(argv[0], argv);
lxc_log_syserror("failed to exec %s", argv[0]);
/* If the exec fails, tell that to our father */
if (write(sv[0], &sync, sizeof(sync)) < 0)
lxc_log_syserror("failed to write the socket");
return 1;
}
close(sv[0]);
/* Wait for the child to be ready */
if (read(sv[1], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to read the socket");
goto err_pipe_read;
}
/* Create the network configuration */
if (clone_flags & CLONE_NEWNET && conf_create_network(name, pid)) {
lxc_log_error("failed to create the configured network");
goto err_create_network;
}
/* Tell the child to continue its initialization */
if (write(sv[1], &sync, sizeof(sync)) < 0) {
lxc_log_syserror("failed to write the socket");
goto err_pipe_write;
}
/* Wait for the child to exec or returning an error */
err = read(sv[1], &sync, sizeof(sync));
if (err < 0) {
lxc_log_error("failed to read the socket");
goto err_pipe_read2;
}
if (err > 0) {
lxc_log_error("something went wrong with %d", pid);
/* TODO : check status etc ... */
waitpid(pid, NULL, 0);
goto err_child_failed;
}
asprintf(&val, "%d\n", pid);
asprintf(&init, LXCPATH "/%s/init", name);
fd = open(init, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
if (fd < 0) {
lxc_log_syserror("failed to open '%s'", init);
goto err_write;
}
if (write(fd, val, strlen(val)) < 0) {
lxc_log_syserror("failed to write the init pid");
goto err_write;
}
close(fd);
if (lxc_link_nsgroup(name, pid))
lxc_log_warning("cgroupfs not found: cgroup disabled");
if (lxc_setstate(name, RUNNING)) {
lxc_log_error("failed to set state to %s", state2str(RUNNING));
goto err_state_failed;
}
wait_again:
if (waitpid(pid, NULL, 0) < 0) {
if (errno == EINTR)
goto wait_again;
lxc_log_syserror("failed to wait the pid %d", pid);
goto err_waitpid_failed;
}
if (lxc_setstate(name, STOPPING))
lxc_log_error("failed to set state %s", state2str(STOPPING));
if (clone_flags & CLONE_NEWNET && conf_destroy_network(name))
lxc_log_error("failed to destroy the network");
err = 0;
out:
if (lxc_setstate(name, STOPPED))
lxc_log_error("failed to set state %s", state2str(STOPPED));
lxc_unlink_nsgroup(name);
unlink(init);
free(init);
free(val);
lxc_put_lock(lock);
return err;
err_write:
close(fd);
err_state_failed:
err_child_failed:
err_pipe_read2:
err_pipe_write:
if (clone_flags & CLONE_NEWNET)
conf_destroy_network(name);
err_create_network:
err_pipe_read:
err_waitpid_failed:
if (lxc_setstate(name, ABORTING))
lxc_log_error("failed to set state %s", state2str(STOPPED));
kill(pid, SIGKILL);
err_fork_ns:
LXC_TTY_DEL_HANDLER(SIGQUIT);
LXC_TTY_DEL_HANDLER(SIGINT);
close(sv[0]);
close(sv[1]);
err:
goto out;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <lxc.h>
#include <state.h>
#include <log.h>
static char *strstate[] = {
"STOPPED", "STARTING", "RUNNING", "STOPPING",
"ABORTING", "FREEZING", "FROZEN",
};
const char *state2str(lxc_state_t state)
{
if (state < STOPPED || state > MAX_STATE - 1)
return NULL;
return strstate[state];
}
lxc_state_t str2state(const char *state)
{
int i, len;
len = sizeof(strstate)/sizeof(strstate[0]);
for (i = 0; i < len; i++)
if (!strcmp(strstate[i], state))
return i;
return -1;
}
int lxc_setstate(const char *name, lxc_state_t state)
{
int fd, err;
char file[MAXPATHLEN];
const char *str = state2str(state);
if (!str)
return -1;
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
fd = open(file, O_WRONLY);
if (fd < 0) {
lxc_log_syserror("failed to open %s file", file);
return -1;
}
if (flock(fd, LOCK_EX)) {
lxc_log_syserror("failed to take the lock to %s", file);
goto out;
}
if (ftruncate(fd, 0)) {
lxc_log_syserror("failed to truncate the file %s", file);
goto out;
}
if (write(fd, str, strlen(str)) < 0) {
lxc_log_syserror("failed to write state to %s", file);
goto out;
}
err = 0;
out:
close(fd);
/* let the event to be propagated, crappy but that works,
* otherwise the events will be folded into only one event,
* and I want to have them to be one by one in order
* to follow the different states of the container.
*/
usleep(200000);
return -err;
}
int mkstate(const char *name)
{
int fd;
char file[MAXPATHLEN];
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
fd = creat(file, S_IRUSR|S_IWUSR);
if (fd < 0) {
lxc_log_syserror("failed to create file %s", file);
return -1;
}
close(fd);
return 0;
}
int rmstate(const char *name)
{
char file[MAXPATHLEN];
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
unlink(file);
return 0;
}
lxc_state_t lxc_getstate(const char *name)
{
int fd, err;
char file[MAXPATHLEN];
snprintf(file, MAXPATHLEN, LXCPATH "/%s/state", name);
fd = open(file, O_RDONLY);
if (fd < 0) {
lxc_log_syserror("failed to open %s", file);
return -1;
}
if (flock(fd, LOCK_SH)) {
lxc_log_syserror("failed to take the lock to %s", file);
close(fd);
return -1;
}
err = read(fd, file, strlen(file));
if (err < 0) {
lxc_log_syserror("failed to read file %s", file);
close(fd);
return -1;
}
file[err] = '\0';
close(fd);
return str2state(file);
}
static int freezer_state(const char *name)
{
char freezer[MAXPATHLEN];
char status[MAXPATHLEN];
FILE *file;
int err;
snprintf(freezer, MAXPATHLEN,
LXCPATH "/%s/freezer.freeze", name);
file = fopen(freezer, "r");
if (file < 0) {
lxc_log_syserror("failed to open %s", freezer);
return -1;
}
err = fscanf(file, "%s", status);
fclose(file);
if (err == EOF) {
lxc_log_syserror("failed to read %s", freezer);
return -1;
}
return str2state(status);
}
lxc_state_t lxc_state(const char *name)
{
int state = freezer_state(name);
if (state != FROZEN && state != FREEZING)
state = lxc_getstate(name);
return state;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _state_h
#define _state_h
extern const char *state2str(lxc_state_t state);
extern lxc_state_t str2state(const char *state);
extern int mkstate(const char *name);
extern int rmstate(const char *name);
extern int lxc_setstate(const char *name, lxc_state_t state);
extern lxc_state_t lxc_getstate(const char *name);
#endif
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#define _GNU_SOURCE
#include <stdio.h>
#undef _GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <log.h>
#include <lock.h>
int lxc_stop(const char *name)
{
char *init;
char val[MAXPIDLEN];
int fd, lock, ret = -1;
size_t pid;
lock = lxc_get_lock(name);
if (lock > 0) {
lxc_log_error("'%s' is not running", name);
lxc_put_lock(lock);
return -1;
}
if (lock < 0) {
lxc_log_error("failed to acquire the lock on '%s':%s",
name, strerror(-lock));
return -1;
}
asprintf(&init, LXCPATH "/%s/init", name);
fd = open(init, O_RDONLY);
if (fd < 0) {
lxc_log_syserror("failed to open init file for %s", name);
goto out_free;
}
if (read(fd, val, sizeof(val)) < 0) {
lxc_log_syserror("failed to read %s", init);
goto out_close;
}
pid = atoi(val);
if (kill(pid, SIGKILL)) {
lxc_log_syserror("failed to kill %zd", pid);
goto out_close;
}
if (unlink(init)) {
lxc_log_syserror("failed to unlink %s", init);
goto out_close;
}
ret = 0;
out_close:
close(fd);
out_free:
free(init);
return ret;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#ifndef _utils_h
#define _utils_h
#define LXC_TTY_HANDLER(s) \
static struct sigaction lxc_tty_sa_##s; \
static void tty_##s##_handler(int sig, siginfo_t *info, void *ctx) \
{ \
if (lxc_tty_sa_##s.sa_handler == SIG_DFL || \
lxc_tty_sa_##s.sa_handler == SIG_IGN) \
return; \
(*lxc_tty_sa_##s.sa_sigaction)(sig, info, ctx); \
}
#define LXC_TTY_ADD_HANDLER(s) \
do { \
struct sigaction sa; \
sa.sa_sigaction = tty_##s##_handler; \
sa.sa_flags = SA_SIGINFO; \
sigfillset(&sa.sa_mask); \
/* No error expected with sigaction. */ \
sigaction(s, &sa, &lxc_tty_sa_##s); \
} while (0)
#define LXC_TTY_DEL_HANDLER(s) \
do { \
sigaction(s, &lxc_tty_sa_##s, NULL); \
} while (0)
#endif
.deps
Makefile
Makefile.in
lxc-console
lxc-create
lxc-destroy
lxc-execute
lxc-freeze
lxc-kill
lxc-monitor
lxc-start
lxc-state
lxc-stop
lxc-unfreeze
lxc-ps
INCLUDES= -I$(top_srcdir)/src/liblxc
bin_SCRIPTS = \
lxc-ps
bin_PROGRAMS = \
lxc-create \
lxc-destroy \
lxc-stop \
lxc-start \
lxc-execute \
lxc-monitor \
lxc-console \
lxc-state \
lxc-kill \
lxc-freeze \
lxc-unfreeze
lxc_create_SOURCES = lxc_create.c config.c config.h
lxc_create_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_destroy_SOURCES = lxc_destroy.c
lxc_destroy_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_start_SOURCES = lxc_start.c
lxc_start_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_stop_SOURCES = lxc_stop.c
lxc_stop_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_execute_SOURCES = lxc_execute.c config.c
lxc_execute_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_monitor_SOURCES = lxc_monitor.c
lxc_monitor_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_console_SOURCES = lxc_console.c
lxc_console_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_state_SOURCES = lxc_state.c
lxc_state_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_kill_SOURCES = lxc_kill.c
lxc_kill_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_freeze_SOURCES = lxc_freeze.c
lxc_freeze_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
lxc_unfreeze_SOURCES = lxc_unfreeze.c
lxc_unfreeze_LDADD = \
$(top_builddir)/src/liblxc/liblxc.a
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
extern int config_init(struct lxc_conf *conf);
extern int config_read(const char *file, struct lxc_conf *conf);
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <lxc.h>
int main(int argc, char *argv[])
{
return 0;
}
#!/bin/bash
LXCPATH=/var/lxc
if [ ! -r $LXCPATH ]; then
exit 0
fi
LXCS=$(ls $LXCPATH)
for i in $LXCS; do
if [ -d $LXCPATH/$i/nsgroup ]; then
echo "Container : $(basename $i)"
cat $LXCPATH/$i/nsgroup/tasks
fi
done
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <lxc.h>
int main(int argc, char *argv[])
{
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <libgen.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
#include <state.h>
#include <list.h>
#include <conf.h>
#include "config.h"
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
fprintf(stderr, "\t -f <confile> : path of the configuration file\n");
_exit(1);
}
int main(int argc, char *argv[])
{
const char *name = NULL, *file = NULL;
struct lxc_conf lxc_conf;
int opt;
while ((opt = getopt(argc, argv, "f:n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
case 'f':
file = optarg;
break;
}
}
if (!name || !file)
usage(argv[0]);
if (config_init(&lxc_conf)) {
fprintf(stderr, "failed to initialize the configuration\n");
return 1;
}
if (config_read(file, &lxc_conf)) {
fprintf(stderr, "invalid configuration file\n");
return 1;
}
if (lxc_create(name, &lxc_conf)) {
fprintf(stderr, "failed to create the container %s\n", name);
return 1;
}
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/types.h>
#include <lxc.h>
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
_exit(1);
}
int main(int argc, char *argv[])
{
char opt;
char *name = NULL;
int nbargs = 0;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
}
nbargs++;
}
if (!name)
usage(argv[0]);
if (lxc_destroy(name)) {
fprintf(stderr, "failed to destroy %s\n", name);
return 1;
}
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <libgen.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <lxc.h>
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
_exit(1);
}
int main(int argc, char *argv[])
{
char opt;
char *name = NULL;
char **args;
int nbargs = 0;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
}
nbargs++;
}
if (!name || !argv[optind] || !strlen(argv[optind]))
usage(argv[0]);
args = &argv[optind];
argc -= nbargs;
if (lxc_execute(name, argc, args, NULL, NULL)) {
fprintf(stderr, "failed to start %s\n", name);
return 1;
}
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <libgen.h>
#include <string.h>
#include <lxc.h>
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
_exit(1);
}
int main(int argc, char *argv[])
{
char opt;
char *name = NULL;
int nbargs = 0;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
}
nbargs++;
}
if (!name)
usage(argv[0]);
if (lxc_freeze(name)) {
fprintf(stderr, "failed to freeze '%s'\n", name);
return 1;
}
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <lxc.h>
int main(int argc, char *argv[])
{
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <libgen.h>
#include <unistd.h>
#include <sys/types.h>
#include <lxc.h>
#include <state.h>
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
_exit(1);
}
int main(int argc, char *argv[])
{
char opt;
char *name = NULL;
int fds[2];
pid_t pid;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
}
}
if (!name)
usage(argv[0]);
if (pipe(fds)) {
perror("pipe");
return 1;
}
pid = fork();
if (pid < 0) {
perror("fork");
return 1;
}
if (!pid) {
close(fds[0]);
if (lxc_monitor(name, fds[1])) {
fprintf(stderr, "failed to monitor %s\n", name);
return 1;
}
return 0;
}
close(fds[1]);
for (;;) {
int err, state;
err = read(fds[0], &state, sizeof(state));
if (err < 0) {
perror("read");
return 1;
}
if (!err) {
printf("container has been destroyed\n");
return 0;
}
printf("container has changed the state to %d - %s\n",
state, state2str(state));
}
return 0;
}
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.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
*/
#include <stdio.h>
#include <libgen.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <lxc.h>
void usage(char *cmd)
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
_exit(1);
}
int main(int argc, char *argv[])
{
char opt;
char *name = NULL;
char **args;
int nbargs = 0;
while ((opt = getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
name = optarg;
break;
}
nbargs++;
}
if (!name || !argv[optind] || !strlen(argv[optind]))
usage(argv[0]);
args = &argv[optind];
argc -= nbargs;
if (lxc_start(name, argc, args, NULL, NULL)) {
fprintf(stderr, "failed to start %s\n", name);
return 1;
}
return 0;
}
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
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