Commit 576f946d by dlezcano

Add cgroup support, the configuration file should be specified with the format:

lxc.cgroup.xxx = yyy where xxx is a cgroup subsystem (eg. cpu.shares) and the yyy is the value to be set.
parent 893c6f54
......@@ -25,7 +25,7 @@ liblxc_la_SOURCES = \
checkpoint.c \
restart.c \
version.c \
lxc_cgroup.c lxc_cgroup.h \
cgroup.c cgroup.h \
lxc.h \
lxc_utils.h \
lxc_lock.c lxc_lock.h \
......@@ -57,8 +57,8 @@ bin_PROGRAMS = \
lxc-kill \
lxc-freeze \
lxc-info \
lxc-cgroup \
lxc-unfreeze \
lxc-priority \
lxc-checkpoint \
lxc-restart \
lxc-version
......@@ -99,8 +99,8 @@ lxc_freeze_LDADD = liblxc.la
lxc_unfreeze_SOURCES = lxc_unfreeze.c
lxc_unfreeze_LDADD = liblxc.la
lxc_priority_SOURCES = lxc_priority.c
lxc_priority_LDADD = liblxc.la
lxc_cgroup_SOURCES = lxc_cgroup.c
lxc_cgroup_LDADD = liblxc.la
lxc_checkpoint_SOURCES = lxc_checkpoint.c
lxc_checkpoint_LDADD = liblxc.la
......
/*
* 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/lxc.h>
#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_type, "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[MAXPATHLEN];
char nsgroup[MAXPATHLEN];
char cgroup[MAXPATHLEN];
int ret;
if (get_cgroup_mount(MTAB, cgroup)) {
lxc_log_info("cgroup is not mounted");
return -1;
}
snprintf(lxc, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
snprintf(nsgroup, MAXPATHLEN, "%s/%d", cgroup, pid);
unlink(lxc);
ret = symlink(nsgroup, lxc);
if (ret)
lxc_log_syserror("failed to create symlink %s->%s",
nsgroup, lxc);
return ret;
}
int lxc_unlink_nsgroup(const char *name)
{
char nsgroup[MAXPATHLEN];
snprintf(nsgroup, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
return unlink(nsgroup);
}
int lxc_cgroup_copy(const char *name, const char *subsystem)
{
char destination[MAXPATHLEN];
char source[MAXPATHLEN];
char buffer[1024];
int nbbytes, fd_source, fd_destination, ret = -1;
snprintf(source, MAXPATHLEN, LXCPATH "/%s/cgroup/%s", name, subsystem);
if (access(source, F_OK))
return 0;
fd_source = open(source, O_RDONLY);
if (fd_source < 0) {
lxc_log_syserror("failed to open '%s'", source);
return -1;
}
snprintf(destination, MAXPATHLEN, LXCPATH "/%s/nsgroup/%s", name, subsystem);
fd_destination = open(destination, O_WRONLY);
if (fd_destination < 0) {
lxc_log_syserror("failed to open '%s'", destination);
goto out;
}
nbbytes = read(fd_source, buffer, sizeof(buffer));
if (nbbytes < 0) {
lxc_log_syserror("failed to read '%s'", source);
goto out;
}
if (write(fd_destination, buffer, nbbytes) < 0) {
lxc_log_syserror("failed to write to '%s'", destination);
goto out;
}
ret = 0;
out:
close(fd_source);
close(fd_destination);
return ret;
}
int lxc_cgroup_set(const char *name, const char *subsystem, const char *value)
{
int fd, ret = -1;;
char path[MAXPATHLEN];
snprintf(path, MAXPATHLEN, LXCPATH "/%s/nsgroup/%s", name, subsystem);
fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
if (write(fd, value, strlen(value)) < 0)
goto out;
ret = 0;
out:
close(fd);
return ret;
}
int lxc_cgroup_get(const char *name, const char *subsystem,
char *value, size_t len)
{
int fd, ret = -1;;
char path[MAXPATHLEN];
snprintf(path, MAXPATHLEN, LXCPATH "/%s/nsgroup/%s", name, subsystem);
fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
if (read(fd, value, len) < 0)
goto out;
ret = 0;
out:
close(fd);
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 _cgroup_h
#define _cgroup_h
#define MAXPRIOLEN 24
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);
int lxc_cgroup_copy(const char *name, const char *subsystem);
#endif
......@@ -172,6 +172,9 @@ int lxc_execute(const char *name, int argc, char *argv[],
goto err_pipe_read;
}
if (lxc_link_nsgroup(name, pid))
lxc_log_warning("cgroupfs not found: cgroup disabled");
if (clone_flags & CLONE_NEWNET && conf_create_network(name, pid)) {
lxc_log_error("failed to create the configured network");
goto err_create_network;
......@@ -213,9 +216,6 @@ int lxc_execute(const char *name, int argc, char *argv[],
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", lxc_state2str(RUNNING));
goto err_state_failed;
......@@ -254,7 +254,8 @@ err_state_failed:
err_child_failed:
err_pipe_read2:
err_pipe_write:
conf_destroy_network(name);
if (clone_flags & CLONE_NEWNET)
conf_destroy_network(name);
err_create_network:
err_pipe_read:
err_open:
......
......@@ -38,9 +38,9 @@ extern "C" {
#include <lxc/lxc_conf.h>
#include <lxc/lxc_log.h>
#include <lxc/lxc_lock.h>
#include <lxc/lxc_cgroup.h>
#include <lxc/lxc_namespace.h>
#include <lxc/lxc_utils.h>
#include <lxc/cgroup.h>
#include <lxc/monitor.h>
#define LXCPATH "/var/lxc"
......@@ -179,76 +179,26 @@ extern lxc_state_t lxc_state(const char *name);
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
* Set a specified value for a specified subsystem. The specified
* subsystem must be fully specified, eg. "cpu.shares"
* @name : the name of the container
* @subsystem : the subsystem
* @value : the value to be set
* Returns 0 on success, < 0 otherwise
*/
extern int lxc_cgroup_set_priority(const char *name, int priority);
extern int lxc_cgroup_set(const char *name, const char *subsystem, const char *value);
/*
* Retrieve the priority of the container
* @name : the name of the container
* @priority : a pointer to an int where the priority will be stored
* Get a specified value for a specified subsystem. The specified
* subsystem must be fully specified, eg. "cpu.shares"
* @name : the name of the container
* @subsystem : the subsystem
* @value : the value to be set
* @len : the len of the value variable
* 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);
extern int lxc_cgroup_get(const char *name, const char *subsystem,
char *value, size_t len);
/*
* Checkpoint a container previously frozen
......
......@@ -20,168 +20,11 @@
* 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 <stdio.h>
#include <lxc/lxc.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_type, "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[MAXPATHLEN];
char nsgroup[MAXPATHLEN];
char cgroup[MAXPATHLEN];
int ret;
if (get_cgroup_mount(MTAB, cgroup)) {
lxc_log_info("cgroup is not mounted");
return -1;
}
snprintf(lxc, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
snprintf(nsgroup, MAXPATHLEN, "%s/%d", cgroup, pid);
unlink(lxc);
ret = symlink(nsgroup, lxc);
if (ret)
lxc_log_syserror("failed to create symlink %s->%s",
nsgroup, lxc);
return ret;
}
int lxc_unlink_nsgroup(const char *name)
{
char nsgroup[MAXPATHLEN];
snprintf(nsgroup, MAXPATHLEN, LXCPATH "/%s/nsgroup", name);
return unlink(nsgroup);
}
int lxc_cgroup_set_priority(const char *name, int priority)
{
int fd;
char path[MAXPATHLEN], *prio = NULL;
snprintf(path, MAXPATHLEN,
LXCPATH "/%s/nsgroup/cpu.shares", name);
fd = open(path, O_WRONLY);
if (fd < 0) {
lxc_log_syserror("failed to open '%s'", path);
return -1;
}
if (!asprintf(&prio, "%d", priority)) {
lxc_log_syserror("not enough memory");
goto out;
}
if (write(fd, prio, strlen(prio) + 1) < 0) {
lxc_log_syserror("failed to write to '%s'", path);
close(fd);
goto out;
}
lxc_monitor_send_priority(name, priority);
close(fd);
out:
free(prio);
return 0;
}
int lxc_cgroup_get_priority(const char *name, int *priority)
{
int fd, ret = -1;
char path[MAXPATHLEN], prio[MAXPRIOLEN];
snprintf(path, MAXPATHLEN, LXCPATH "/%s/nsgroup/cpu.shares", name);
fd = open(path, O_RDONLY);
if (fd < 0) {
lxc_log_syserror("failed to open '%s'", path);
return -1;
}
if (read(fd, prio, MAXPRIOLEN) < 0) {
lxc_log_syserror("failed to read from '%s'", path);
goto out;
}
*priority = atoi(prio);
ret = 0;
out:
close(fd);
return ret;
}
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)
int main(int argc, char *argv[])
{
return 0;
}
......@@ -23,8 +23,60 @@
#ifndef _cgroup_h
#define _cgroup_h
#define MAXPRIOLEN 24
#define CGROUP_CPU_SHARES "cpu.shares"
#define CGROUP_CPUACCT_USAGE "cpuacct.usage"
#define CGROUP_CPUSET_CPUS "cpuset.cpus"
#define CGROUP_CPUSET_CPU_EXCLUSIVE "cpuset.cpu_exclusive"
#define CGROUP_CPUSET_SCHED_LOAD_BALANCE "cpuset.sched_load_balance"
#define CGROUP_CPUSET_SCHED_RELAX_DOMAIN_LEVEL "cpuset.sched_relax_domain_level"
#define CGROUP_MEMORY_LIMIT_IN_BYTES "memory.limit_in_bytes"
struct lxc_cgroup_memory_info {
unsigned long cache;
unsigned long rss;
unsigned long page_in;
unsigned long page_out;
unsigned long active;
unsigned long inactive;
unsigned long failcnt;
unsigned long force_empty;
unsigned long limit_in_bytes;
unsigned long max_usage_in_bytes;
unsigned long usage_in_bytes;
};
struct lxc_cgroup_cpuacct_info {
unsigned long usage;
};
struct lxc_cgroup_cpu_info {
unsigned long rt_period_us;
unsigned long rt_runtimer_us;
unsigned long shares;
};
struct lxc_cgroup_cpuset_info {
int mem_exclusive;
int mem_hardball;
int memory_migrate;
int memory_pressure;
int memory_pressure_enabled;
int memory_spread_page;
int memory_spread_slab;
};
struct lxc_cgroup_info {
struct lxc_cgroup_memory_info memory;
struct lxc_cgroup_cpuacct_info cpuacct;
struct lxc_cgroup_cpu_info cpu;
struct lxc_cgroup_cpuset_info cpuset;
};
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);
int lxc_cgroup_copy(const char *name, const char *subsystem);
#endif
......@@ -394,8 +394,28 @@ out:
return err;
}
static int configure_cgroup(const char *name, struct lxc_cgroup *cgroup)
static int configure_cgroup(const char *name, struct lxc_list *cgroup)
{
char path[MAXPATHLEN];
struct lxc_list *iterator;
struct lxc_cgroup *cg;
int ret = -1;
if (lxc_list_empty(cgroup))
return 0;
snprintf(path, MAXPATHLEN, LXCPATH "/%s/cgroup", name);
if (mkdir(path, 0755)) {
lxc_log_syserror("failed to create '%s' directory", path);
return -1;
}
lxc_list_for_each(iterator, cgroup) {
cg = iterator->elem;
write_info(path, cg->subsystem, cg->value);
}
return 0;
}
......@@ -536,12 +556,20 @@ static int unconfigure_network(const char *name)
return 0;
}
static int unconfigure_cgroup_cb(const char *name, const char *dirname,
const char *file, void *data)
{
return delete_info(dirname, file);
}
static int unconfigure_cgroup(const char *name)
{
char path[MAXPATHLEN];
char dirname[MAXPATHLEN];
snprintf(path, MAXPATHLEN, LXCPATH "/%s", name);
delete_info(path, "nsgroup");
lxc_unlink_nsgroup(name);
snprintf(dirname, MAXPATHLEN, LXCPATH "/%s/cgroup", name);
dir_for_each(name, dirname, unconfigure_cgroup_cb, NULL);
rmdir(dirname);
return 0;
}
......@@ -622,6 +650,21 @@ static int setup_rootfs(const char *name)
return 0;
}
static int setup_cgroup_cb(const char *name, const char *dirname,
const char *file, void *data)
{
if (lxc_cgroup_copy(name, file))
lxc_log_warning("failed to setup '%s'");
return 0;
}
static int setup_cgroup(const char *name)
{
char dirname[MAXPATHLEN];
snprintf(dirname, MAXPATHLEN, LXCPATH "/%s/cgroup", name);
return dir_for_each(name, dirname, setup_cgroup_cb, NULL);
}
static int setup_mount(const char *name)
{
char path[MAXPATHLEN];
......@@ -900,13 +943,13 @@ int lxc_configure(const char *name, struct lxc_conf *conf)
return -1;
}
if (configure_network(name, &conf->networks)) {
lxc_log_error("failed to configure the network");
if (configure_cgroup(name, &conf->cgroup)) {
lxc_log_error("failed to configure the control group");
return -1;
}
if (conf->cgroup && configure_cgroup(name, conf->cgroup)) {
lxc_log_error("failed to configure the control group");
if (configure_network(name, &conf->networks)) {
lxc_log_error("failed to configure the network");
return -1;
}
......@@ -931,7 +974,7 @@ int lxc_unconfigure(const char *name)
if (conf_has_network(name) && unconfigure_network(name))
lxc_log_error("failed to cleanup the network");
if (unconfigure_cgroup(name))
if (conf_has_cgroup(name) && unconfigure_cgroup(name))
lxc_log_error("failed to cleanup cgroup");
if (conf_has_rootfs(name) && unconfigure_rootfs(name))
......@@ -1252,6 +1295,11 @@ int lxc_setup(const char *name)
return -1;
}
if (conf_has_cgroup(name) && setup_cgroup(name)) {
lxc_log_error("failed to setup the cgroups for '%s'", name);
return -1;
}
if (conf_has_rootfs(name) && setup_rootfs(name)) {
lxc_log_error("failed to set rootfs for '%s'", name);
return -1;
......
......@@ -97,10 +97,14 @@ struct lxc_network {
};
/*
* Defines a structure to configure the control data and path
* Defines a generic struct to configure the control group.
* It is up to the programmer to specify the right subsystem.
* @subsystem : the targetted subsystem
* @value : the value to set
*/
struct lxc_cgroup {
;
char *subsystem;
char *value;
};
/*
......@@ -114,7 +118,7 @@ struct lxc_conf {
char *rootfs;
char *fstab;
struct utsname *utsname;
struct lxc_cgroup *cgroup;
struct lxc_list cgroup;
struct lxc_list networks;
};
......@@ -143,5 +147,6 @@ extern int conf_has(const char *name, const char *info);
#define conf_has_rootfs(__name) conf_has(__name, "rootfs")
#define conf_has_utsname(__name) conf_has(__name, "utsname")
#define conf_has_network(__name) conf_has(__name, "network")
#define conf_has_cgroup(__name) conf_has(__name, "cgroup")
#endif
......@@ -35,39 +35,38 @@
#include <lxc/lxc.h>
typedef int (*file_cb)(char* buffer, void *data);
typedef int (*config_cb)(char *value, struct lxc_conf *lxc_conf);
static int config_mount(char *, struct lxc_conf *);
static int config_rootfs(char *, struct lxc_conf *);
static int config_utsname(char *, struct lxc_conf *);
static int config_network_type(char *, struct lxc_conf *);
static int config_network_flags(char *, struct lxc_conf *);
static int config_network_link(char *, struct lxc_conf *);
static int config_network_name(char *, struct lxc_conf *);
static int config_network_hwaddr(char *, struct lxc_conf *);
static int config_network_ipv4(char *, struct lxc_conf *);
static int config_network_ipv6(char *, struct lxc_conf *);
typedef int (*config_cb)(const char *, char *, struct lxc_conf *);
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_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_hwaddr(const char *, char *, struct lxc_conf *);
static int config_network_ipv4(const char *, char *, struct lxc_conf *);
static int config_network_ipv6(const char *, char *, struct lxc_conf *);
struct config {
char *name;
int type;
config_cb cb;
};
enum { MOUNT, ROOTFS, UTSNAME, NETTYPE, NETFLAGS, NETLINK,
NETNAME, NETHWADDR, NETIPV4, NETIPV6 };
struct config config[] = {
{ "lxc.mount", MOUNT, config_mount },
{ "lxc.rootfs", ROOTFS, config_rootfs },
{ "lxc.utsname", UTSNAME, config_utsname },
{ "lxc.network.type", NETTYPE, config_network_type },
{ "lxc.network.flags", NETFLAGS, config_network_flags },
{ "lxc.network.link", NETLINK, config_network_link },
{ "lxc.network.name", NETNAME, config_network_name },
{ "lxc.network.hwaddr", NETHWADDR, config_network_hwaddr },
{ "lxc.network.ipv4", NETIPV4, config_network_ipv4 },
{ "lxc.network.ipv6", NETIPV6, config_network_ipv6 },
static struct config config[] = {
{ "lxc.cgroup", config_cgroup },
{ "lxc.mount", config_mount },
{ "lxc.rootfs", config_rootfs },
{ "lxc.utsname", config_utsname },
{ "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.hwaddr", config_network_hwaddr },
{ "lxc.network.ipv4", config_network_ipv4 },
{ "lxc.network.ipv6", config_network_ipv6 },
};
static const size_t config_size = sizeof(config)/sizeof(struct config);
......@@ -122,7 +121,7 @@ static int char_right_gc(char *buffer, size_t len)
return 0;
}
static int config_network_type(char *value, struct lxc_conf *lxc_conf)
static int config_network_type(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -185,7 +184,7 @@ static int config_network_type(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_flags(char *value, struct lxc_conf *lxc_conf)
static int config_network_flags(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -207,7 +206,7 @@ static int config_network_flags(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_link(char *value, struct lxc_conf *lxc_conf)
static int config_network_link(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -234,7 +233,7 @@ static int config_network_link(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_name(char *value, struct lxc_conf *lxc_conf)
static int config_network_name(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -261,7 +260,7 @@ static int config_network_name(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf)
static int config_network_hwaddr(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -283,7 +282,7 @@ static int config_network_hwaddr(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf)
static int config_network_ipv4(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -362,7 +361,7 @@ static int config_network_ipv4(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf)
static int config_network_ipv6(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct lxc_list *networks = &lxc_conf->networks;
struct lxc_network *network;
......@@ -418,7 +417,46 @@ static int config_network_ipv6(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_mount(char *value, struct lxc_conf *lxc_conf)
static int config_cgroup(const char *key, char *value, struct lxc_conf *lxc_conf)
{
char *token = "lxc.cgroup.";
char *subkey;
struct lxc_list *cglist;
struct lxc_cgroup *cgelem;
subkey = strstr(key, token);
if (!subkey)
return -1;
if (!strlen(subkey))
return -1;
if (strlen(subkey) == strlen(token))
return -1;
subkey += strlen(token);
cglist = malloc(sizeof(*cglist));
if (!cglist)
return -1;
cgelem = malloc(sizeof(*cgelem));
if (!cgelem) {
free(cglist);
return -1;
}
cgelem->subsystem = strdup(subkey);
cgelem->value = strdup(value);
cglist->elem = cgelem;
lxc_list_add(&lxc_conf->cgroup, cglist);
return 0;
}
static int config_mount(const char *key, char *value, struct lxc_conf *lxc_conf)
{
if (strlen(value) >= MAXPATHLEN) {
lxc_log_error("%s path is too long", value);
......@@ -434,7 +472,7 @@ static int config_mount(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_rootfs(char *value, struct lxc_conf *lxc_conf)
static int config_rootfs(const char *key, char *value, struct lxc_conf *lxc_conf)
{
if (strlen(value) >= MAXPATHLEN) {
lxc_log_error("%s path is too long", value);
......@@ -450,7 +488,7 @@ static int config_rootfs(char *value, struct lxc_conf *lxc_conf)
return 0;
}
static int config_utsname(char *value, struct lxc_conf *lxc_conf)
static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_conf)
{
struct utsname *utsname;
......@@ -507,7 +545,7 @@ static int parse_line(char *buffer, void *data)
return -1;
}
return config->cb(value, data);
return config->cb(key, value, data);
}
static int file_for_each_line(const char *file, file_cb callback, void *data)
......@@ -542,7 +580,7 @@ int lxc_config_init(struct lxc_conf *conf)
conf->rootfs = NULL;
conf->fstab = NULL;
conf->utsname = NULL;
conf->cgroup = NULL;
lxc_list_init(&conf->cgroup);
lxc_list_init(&conf->networks);
return 0;
}
......@@ -123,13 +123,6 @@ static void lxc_monitor_send(const char *name, struct lxc_msg *msg)
close(fd);
}
void lxc_monitor_send_priority(const char *name, int priority)
{
struct lxc_msg msg = { .type = lxc_msg_priority,
.value = priority };
lxc_monitor_send(name, &msg);
}
void lxc_monitor_send_state(const char *name, lxc_state_t state)
{
struct lxc_msg msg = { .type = lxc_msg_state,
......
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