Commit 47ee660e by Stéphane Graber

Merge pull request #875 from hallyn/cgfsng

cgfsng: next generation filesystem-backed cgroup implementation
parents 554cd166 43647298
......@@ -89,6 +89,7 @@ liblxc_so_SOURCES = \
error.h error.c \
parse.c parse.h \
cgfs.c \
cgfsng.c \
cgroup.c cgroup.h \
lxc.h \
initutils.c initutils.h \
......
......@@ -141,7 +141,6 @@ static int do_cgroup_set(const char *cgroup_path, const char *sub_filename, cons
static bool cgroup_devices_has_allow_or_deny(struct cgfs_data *d, char *v, bool for_allow);
static int do_setup_cgroup_limits(struct cgfs_data *d, struct lxc_list *cgroup_settings, bool do_devices);
static int cgroup_recursive_task_count(const char *cgroup_path);
static int count_lines(const char *fn);
static int handle_cgroup_settings(struct cgroup_mount_point *mp, char *cgroup_path);
static bool init_cpuset_if_needed(struct cgroup_mount_point *mp, const char *path);
......@@ -2116,7 +2115,7 @@ static int cgroup_recursive_task_count(const char *cgroup_path)
if (r >= 0)
n += r;
} else if (!strcmp(dent->d_name, "tasks")) {
r = count_lines(sub_path);
r = lxc_count_file_lines(sub_path);
if (r >= 0)
n += r;
}
......@@ -2128,25 +2127,6 @@ static int cgroup_recursive_task_count(const char *cgroup_path)
return n;
}
static int count_lines(const char *fn)
{
FILE *f;
char *line = NULL;
size_t sz = 0;
int n = 0;
f = fopen_cloexec(fn, "r");
if (!f)
return -1;
while (getline(&line, &sz, f) != -1) {
n++;
}
free(line);
fclose(f);
return n;
}
static int handle_cgroup_settings(struct cgroup_mount_point *mp,
char *cgroup_path)
{
......@@ -2420,7 +2400,7 @@ static const char *cgfs_canonical_path(void *hdata)
return path;
}
static bool cgfs_escape(void)
static bool cgfs_escape(void *hdata)
{
struct cgroup_meta_data *md;
int i;
......
......@@ -299,7 +299,7 @@ static bool lxc_cgmanager_create(const char *controller, const char *cgroup_path
* be in "/lxc/c1" rather than "/user/..../c1"
* called internally with connection already open
*/
static bool cgm_escape(void)
static bool cgm_escape(void *hdata)
{
bool ret = true, cgm_needs_disconnect = false;
pid_t me = getpid();
......@@ -1436,7 +1436,7 @@ struct cgroup_ops *cgm_ops_init(void)
cgm_all_controllers_same = false;
// if root, try to escape to root cgroup
if (geteuid() == 0 && !cgm_escape()) {
if (geteuid() == 0 && !cgm_escape(NULL)) {
free_subsystems();
return NULL;
}
......
......@@ -34,6 +34,7 @@ lxc_log_define(lxc_cgroup, lxc);
static struct cgroup_ops *ops = NULL;
extern struct cgroup_ops *cgfs_ops_init(void);
extern struct cgroup_ops *cgfsng_ops_init(void);
extern struct cgroup_ops *cgm_ops_init(void);
__attribute__((constructor))
......@@ -45,8 +46,10 @@ void cgroup_ops_init(void)
}
DEBUG("cgroup_init");
ops = cgfsng_ops_init();
#if HAVE_CGMANAGER
ops = cgm_ops_init();
if (!ops)
ops = cgm_ops_init();
#endif
if (!ops)
ops = cgfs_ops_init();
......@@ -109,10 +112,10 @@ const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem
return NULL;
}
bool cgroup_escape(void)
bool cgroup_escape(struct lxc_handler *handler)
{
if (ops)
return ops->escape();
return ops->escape(handler->cgroup_data);
return false;
}
......
......@@ -35,6 +35,7 @@ struct lxc_list;
typedef enum {
CGFS,
CGMANAGER,
CGFSNG,
} cgroup_driver_t;
struct cgroup_ops {
......@@ -47,7 +48,7 @@ struct cgroup_ops {
bool (*create_legacy)(void *hdata, pid_t pid);
const char *(*get_cgroup)(void *hdata, const char *subsystem);
const char *(*canonical_path)(void *hdata);
bool (*escape)(void);
bool (*escape)(void *hdata);
int (*set)(const char *filename, const char *value, const char *name, const char *lxcpath);
int (*get)(const char *filename, char *value, size_t len, const char *name, const char *lxcpath);
bool (*unfreeze)(void *hdata);
......@@ -72,7 +73,7 @@ extern void cgroup_cleanup(struct lxc_handler *handler);
extern bool cgroup_create_legacy(struct lxc_handler *handler);
extern int cgroup_nrtasks(struct lxc_handler *handler);
extern const char *cgroup_get_cgroup(struct lxc_handler *handler, const char *subsystem);
extern bool cgroup_escape(void);
extern bool cgroup_escape(struct lxc_handler *handler);
/*
* Currently, this call only makes sense for privileged containers.
......
......@@ -47,7 +47,7 @@
lxc_log_define(lxc_criu, lxc);
void exec_criu(struct criu_opts *opts)
void exec_criu(struct lxc_handler *handler, struct criu_opts *opts)
{
char **argv, log[PATH_MAX];
int static_args = 22, argc = 0, i, ret;
......@@ -63,7 +63,7 @@ void exec_criu(struct criu_opts *opts)
* /actual/ root cgroup so that lxcfs thinks criu has enough rights to
* see all cgroups.
*/
if (!cgroup_escape()) {
if (!cgroup_escape(handler)) {
ERROR("failed to escape cgroups");
return;
}
......@@ -517,7 +517,7 @@ void do_restore(struct lxc_container *c, int pipe, char *directory, bool verbose
os.cgroup_path = cgroup_canonical_path(handler);
/* exec_criu() returning is an error */
exec_criu(&os);
exec_criu(handler, &os);
umount(rootfs->mount);
rmdir(rootfs->mount);
goto out_fini_handler;
......@@ -624,6 +624,16 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
if (pid == 0) {
struct criu_opts os;
struct lxc_handler *handler;
handler = lxc_init(c->name, c->lxc_conf, c->config_path);
if (!handler)
exit(1);
if (!cgroup_init(handler)) {
ERROR("failed initing cgroups");
exit(1);
}
os.action = mode;
os.directory = directory;
......@@ -633,7 +643,7 @@ static bool do_dump(struct lxc_container *c, char *mode, char *directory,
os.predump_dir = predump_dir;
/* exec_criu() returning is an error */
exec_criu(&os);
exec_criu(handler, &os);
exit(1);
} else {
int status;
......
......@@ -58,7 +58,7 @@ struct criu_opts {
const char *cgroup_path;
};
void exec_criu(struct criu_opts *opts);
void exec_criu(struct lxc_handler *handler, struct criu_opts *opts);
/* Check and make sure the container has a configuration that we know CRIU can
* dump. */
......
......@@ -1771,3 +1771,25 @@ err:
close(fd);
return ret;
}
/*
* Return the number of lines in file @fn, or -1 on error
*/
int lxc_count_file_lines(const char *fn)
{
FILE *f;
char *line = NULL;
size_t sz = 0;
int n = 0;
f = fopen_cloexec(fn, "r");
if (!f)
return -1;
while (getline(&line, &sz, f) != -1) {
n++;
}
free(line);
fclose(f);
return n;
}
......@@ -284,4 +284,5 @@ int safe_mount(const char *src, const char *dest, const char *fstype,
unsigned long flags, const void *data, const char *rootfs);
int mount_proc_if_needed(const char *rootfs);
int null_stdfds(void);
int lxc_count_file_lines(const char *fn);
#endif /* __LXC_UTILS_H */
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