confile.c revision 74a2b5864f2ece87bf522d1c1cbd590dc24c0c53
/*
* lxc: linux Container library
*
* (C) Copyright IBM Corp. 2007, 2008
*
* Authors:
* Daniel Lezcano <dlezcano at fr.ibm.com>
*
* 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <pty.h>
#include <sys/personality.h>
#include "parse.h"
#include "confile.h"
#include "utils.h"
static int config_personality(const char *, char *, struct lxc_conf *);
static int config_pts(const char *, char *, struct lxc_conf *);
static int config_tty(const char *, char *, struct lxc_conf *);
static int config_ttydir(const char *, char *, struct lxc_conf *);
#if HAVE_APPARMOR
static int config_aa_profile(const char *, char *, struct lxc_conf *);
#endif
static int config_cgroup(const char *, char *, struct lxc_conf *);
static int config_mount(const char *, char *, struct lxc_conf *);
static int config_rootfs(const char *, char *, struct lxc_conf *);
static int config_rootfs_mount(const char *, char *, struct lxc_conf *);
static int config_pivotdir(const char *, char *, struct lxc_conf *);
static int config_utsname(const char *, char *, struct lxc_conf *);
static int config_network_type(const char *, char *, struct lxc_conf *);
static int config_network_flags(const char *, char *, struct lxc_conf *);
static int config_network_link(const char *, char *, struct lxc_conf *);
static int config_network_name(const char *, char *, struct lxc_conf *);
static int config_network_veth_pair(const char *, char *, struct lxc_conf *);
static int config_network_macvlan_mode(const char *, char *, struct lxc_conf *);
static int config_network_hwaddr(const char *, char *, struct lxc_conf *);
static int config_network_vlan_id(const char *, char *, struct lxc_conf *);
static int config_network_mtu(const char *, char *, struct lxc_conf *);
static int config_network_ipv4(const char *, char *, struct lxc_conf *);
static int config_network_ipv4_gateway(const char *, char *, struct lxc_conf *);
static int config_network_script(const char *, char *, struct lxc_conf *);
static int config_network_ipv6(const char *, char *, struct lxc_conf *);
static int config_network_ipv6_gateway(const char *, char *, struct lxc_conf *);
static int config_cap_drop(const char *, char *, struct lxc_conf *);
static int config_console(const char *, char *, struct lxc_conf *);
static int config_seccomp(const char *, char *, struct lxc_conf *);
static int config_includefile(const char *, char *, struct lxc_conf *);
struct config {
char *name;
};
{ "lxc.arch", config_personality },
{ "lxc.pts", config_pts },
{ "lxc.tty", config_tty },
{ "lxc.devttydir", config_ttydir },
#if HAVE_APPARMOR
{ "lxc.aa_profile", config_aa_profile },
#endif
{ "lxc.cgroup", config_cgroup },
{ "lxc.mount", config_mount },
{ "lxc.rootfs.mount", config_rootfs_mount },
{ "lxc.rootfs", config_rootfs },
{ "lxc.pivotdir", config_pivotdir },
{ "lxc.utsname", config_utsname },
{ "lxc.hook.pre-start", config_hook },
{ "lxc.hook.mount", config_hook },
{ "lxc.hook.start", config_hook },
{ "lxc.hook.post-stop", config_hook },
{ "lxc.network.type", config_network_type },
{ "lxc.network.flags", config_network_flags },
{ "lxc.network.link", config_network_link },
{ "lxc.network.name", config_network_name },
{ "lxc.network.macvlan.mode", config_network_macvlan_mode },
{ "lxc.network.veth.pair", config_network_veth_pair },
{ "lxc.network.script.up", config_network_script },
{ "lxc.network.script.down", config_network_script },
{ "lxc.network.hwaddr", config_network_hwaddr },
{ "lxc.network.mtu", config_network_mtu },
{ "lxc.network.vlan.id", config_network_vlan_id },
{ "lxc.network.ipv4.gateway", config_network_ipv4_gateway },
{ "lxc.network.ipv4", config_network_ipv4 },
{ "lxc.network.ipv6.gateway", config_network_ipv6_gateway },
{ "lxc.network.ipv6", config_network_ipv6 },
{ "lxc.cap.drop", config_cap_drop },
{ "lxc.console", config_console },
{ "lxc.seccomp", config_seccomp },
{ "lxc.include", config_includefile },
};
{
int i;
for (i = 0; i < config_size; i++)
return &config[i];
return NULL;
}
{
struct lxc_netdev *netdev;
if (!netdev) {
SYSERROR("failed to allocate memory");
return -1;
}
if (!list) {
SYSERROR("failed to allocate memory");
return -1;
}
else {
return -1;
}
return 0;
}
{
return 32 - IN_CLASSA_NSHIFT;
return 32 - IN_CLASSB_NSHIFT;
return 32 - IN_CLASSC_NSHIFT;
return 0;
}
{
struct lxc_netdev *netdev;
if (lxc_list_empty(network)) {
ERROR("network is not created for '%s' = '%s' option",
return NULL;
}
if (!netdev) {
ERROR("no network device defined for '%s' = '%s' option",
return NULL;
}
return netdev;
}
{
ERROR("interface name '%s' too long (>%d)\n",
return -1;
}
if (!*valuep) {
return -1;
}
return 0;
}
#ifndef MACVLAN_MODE_PRIVATE
# define MACVLAN_MODE_PRIVATE 1
#endif
#ifndef MACVLAN_MODE_VEPA
# define MACVLAN_MODE_VEPA 2
#endif
#ifndef MACVLAN_MODE_BRIDGE
# define MACVLAN_MODE_BRIDGE 4
#endif
{
struct mc_mode {
char *name;
int mode;
} m[] = {
{ "private", MACVLAN_MODE_PRIVATE },
{ "vepa", MACVLAN_MODE_VEPA },
{ "bridge", MACVLAN_MODE_BRIDGE },
};
int i;
for (i = 0; i < sizeof(m)/sizeof(m[0]); i++) {
continue;
return 0;
}
return -1;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
return -1;
}
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
return -1;
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
return -1;
}
return 0;
}
{
struct lxc_netdev *netdev;
struct lxc_inetdev *inetdev;
if (!netdev)
return -1;
if (!inetdev) {
SYSERROR("failed to allocate ipv4 address");
return -1;
}
if (!list) {
SYSERROR("failed to allocate memory");
return -1;
}
if (cursor) {
*cursor = '\0';
}
if (slash) {
*slash = '\0';
}
if (!addr) {
ERROR("no address specified");
return -1;
}
return -1;
}
return -1;
}
/* no prefix specified, determine it from the network class */
/* if no broadcast address, let compute one from the
* prefix and address
*/
if (!bcast) {
}
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
if (!gw) {
SYSERROR("failed to allocate ipv4 gateway address");
return -1;
}
if (!value) {
ERROR("no ipv4 gateway address specified");
return -1;
}
netdev->ipv4_gateway_auto = true;
} else {
return -1;
}
netdev->ipv4_gateway_auto = false;
}
return 0;
}
{
struct lxc_netdev *netdev;
struct lxc_inet6dev *inet6dev;
char *slash;
char *netmask;
if (!netdev)
return -1;
if (!inet6dev) {
SYSERROR("failed to allocate ipv6 address");
return -1;
}
if (!list) {
SYSERROR("failed to allocate memory");
return -1;
}
if (slash) {
*slash = '\0';
}
return -1;
}
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
if (!gw) {
SYSERROR("failed to allocate ipv6 gateway address");
return -1;
}
if (!value) {
ERROR("no ipv6 gateway address specified");
return -1;
}
netdev->ipv6_gateway_auto = true;
} else {
return -1;
}
netdev->ipv6_gateway_auto = false;
}
return 0;
}
{
struct lxc_netdev *netdev;
if (!netdev)
return -1;
if (!copy) {
return -1;
}
return 0;
}
return 0;
}
return -1;
}
{
if (!hooklist) {
return -1;
}
return 0;
}
{
char *path;
ERROR("seccomp already defined");
return -1;
}
if (!path) {
return -1;
}
return 0;
}
{
if (!copy) {
return -1;
}
return -1;
}
{
if (personality >= 0)
else
return 0;
}
{
return 0;
}
{
return 0;
}
{
char *path;
return 0;
if (!path) {
return -1;
}
return 0;
}
#if HAVE_APPARMOR
{
char *path;
return 0;
if (!path) {
return -1;
}
return 0;
}
#endif
{
char *subkey;
if (!subkey)
return -1;
return -1;
return -1;
if (!cglist)
goto out;
if (!cgelem)
goto out;
goto out;
return 0;
out:
if (cglist)
if (cgelem) {
}
return -1;
}
{
return -1;
}
return -1;
}
return 0;
}
{
char *fstab_token = "lxc.mount";
char *token = "lxc.mount.entry";
char *subkey;
char *mntelem;
if (!subkey) {
if (!subkey)
return -1;
}
return -1;
if (!mntlist)
return -1;
if (!mntelem)
return -1;
return 0;
}
{
int ret = -1;
return -1;
if (!dropcaps) {
return -1;
}
/* in case several capability drop is specified in a single line
* split these caps in a single element for the list */
for (;;) {
if (!token) {
ret = 0;
break;
}
if (!droplist) {
SYSERROR("failed to allocate drop list");
break;
}
break;
}
}
return ret;
}
{
char *path;
if (!path) {
return -1;
}
return 0;
}
{
}
{
return -1;
}
return -1;
}
return 0;
}
{
return -1;
}
return -1;
}
return 0;
}
{
return -1;
}
return -1;
}
return 0;
}
{
if (!utsname) {
SYSERROR("failed to allocate memory");
return -1;
}
ERROR("node name '%s' is too long",
return -1;
}
return 0;
}
{
char *dot;
char *key;
char *value;
int ret = 0;
if (lxc_is_line_empty(buffer))
return 0;
/* we have to dup the buffer otherwise, at the re-exec for
* reboot we modified the original string on the stack by
* replacing '=' by '\0' below
*/
if (!line) {
return -1;
}
/* martian option - ignoring it, the commented lines beginning by '#'
* fall in this case
*/
goto out;
ret = -1;
if (!dot) {
goto out;
}
*dot = '\0';
if (!config) {
goto out;
}
out:
return ret;
}
{
}
{
}
{
if (!dent)
return -1;
return 0;
}
{
int ret = 0;
if (ret)
break;
}
}
return ret;
}
signed long lxc_config_parse_arch(const char *arch)
{
struct per_name {
char *name;
unsigned long per;
} pername[4] = {
{ "x86", PER_LINUX32 },
{ "i686", PER_LINUX32 },
{ "x86_64", PER_LINUX },
{ "amd64", PER_LINUX },
};
int i;
for (i = 0; i < len; i++) {
}
return -1;
}