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 \
lxc-kill \
lxc-freeze \
lxc-info \
+ lxc-cgroup \
lxc-unfreeze \
- lxc-priority \
lxc-checkpoint \
lxc-restart \
lxc-version
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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
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;
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;
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:
#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"
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
* 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;
}
#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
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;
}
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;
}
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];
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;
}
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))
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;
};
/*
- * 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;
};
/*
char *rootfs;
char *fstab;
struct utsname *utsname;
- struct lxc_cgroup *cgroup;
+ struct lxc_list cgroup;
struct lxc_list networks;
};
#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
#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);
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;
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;
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;
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;
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;
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;
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;
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);
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);
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;
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)
conf->rootfs = NULL;
conf->fstab = NULL;
conf->utsname = NULL;
- conf->cgroup = NULL;
+ lxc_list_init(&conf->cgroup);
lxc_list_init(&conf->networks);
return 0;
}
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,