Ejemplo n.º 1
0
int lxc_cgroup_create(const char *name, pid_t pid)
{
	char cgmnt[MAXPATHLEN];
	char cgname[MAXPATHLEN];
	char clonechild[MAXPATHLEN];
	int flags;

	if (get_cgroup_mount(MTAB, cgmnt)) {
		ERROR("cgroup is not mounted");
		return -1;
	}

	snprintf(cgname, MAXPATHLEN, "%s/%s", cgmnt, name);

	/*
	 * There is a previous cgroup, assume it is empty,
	 * otherwise that fails
	 */
	if (!access(cgname, F_OK) && rmdir(cgname)) {
		SYSERROR("failed to remove previous cgroup '%s'", cgname);
		return -1;
	}

	if (get_cgroup_flags(MTAB, &flags)) {
		SYSERROR("failed to get cgroup flags");
		return -1;
	}

	/* We have the deprecated ns_cgroup subsystem */
	if (flags & CGROUP_NS_CGROUP) {
		WARN("using deprecated ns_cgroup");
		return cgroup_rename_nsgroup(cgmnt, cgname, pid);
	}

	snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children", cgmnt);

	/* we check if the kernel has clone_children, at this point if there
	 * no clone_children neither ns_cgroup, that means the cgroup is mounted
	 * without the ns_cgroup and it has not the compatibility flag
	 */
	if (access(clonechild, F_OK)) {
		ERROR("no ns_cgroup option specified");
		return -1;
	}

	/* we enable the clone_children flag of the cgroup */
	if (cgroup_enable_clone_children(clonechild)) {
		SYSERROR("failed to enable 'clone_children flag");
		return -1;
	}

	/* Let's create the cgroup */
	if (mkdir(cgname, 0700)) {
		SYSERROR("failed to create '%s' directory", cgname);
		return -1;
	}

	/* Let's add the pid to the 'tasks' file */
	if (cgroup_attach(cgname, pid)) {
		SYSERROR("failed to attach pid '%d' to '%s'", pid, cgname);
		rmdir(cgname);
		return -1;
	}

	return 0;
}
Ejemplo n.º 2
0
/*
 * create a cgroup for the container in a particular subsystem.
 */
static int lxc_one_cgroup_create(const char *name,
				 struct mntent *mntent, pid_t pid)
{
	char cginit[MAXPATHLEN], cgname[MAXPATHLEN], cgparent[MAXPATHLEN];
	char clonechild[MAXPATHLEN];
	char initcgroup[MAXPATHLEN];
	int flags, ret;

	/* cgparent is the parent dir, e.g., /sys/fs/cgroup/<cgroup>/<init-cgroup>/lxc */
	/* (remember get_init_cgroup() returns a path starting with '/') */
	/* cgname is the full name, e.g., /sys/fs/cgroup/<cgroup>/<init-cgroup>/lxc/name */
	ret = snprintf(cginit, MAXPATHLEN, "%s%s", mntent->mnt_dir,
		get_init_cgroup(NULL, mntent, initcgroup));
	if (ret < 0 || ret >= MAXPATHLEN) {
		SYSERROR("Failed creating pathname for init's cgroup (%d)\n", ret);
		return -1;
	}

	flags = get_cgroup_flags(mntent);

	ret = snprintf(cgparent, MAXPATHLEN, "%s%s", cginit,
		       (flags & CGROUP_NS_CGROUP) ? "" : "/lxc");
	if (ret < 0 || ret >= MAXPATHLEN) {
		SYSERROR("Failed creating pathname for cgroup parent (%d)\n", ret);
		return -1;
	}
	ret = snprintf(cgname, MAXPATHLEN, "%s/%s", cgparent, name);
	if (ret < 0 || ret >= MAXPATHLEN) {
		SYSERROR("Failed creating pathname for cgroup (%d)\n", ret);
		return -1;
	}

	/* Do we have the deprecated ns_cgroup subsystem? */
	if (flags & CGROUP_NS_CGROUP) {
		WARN("using deprecated ns_cgroup");
		return cgroup_rename_nsgroup(cginit, name, pid);
	}

	ret = snprintf(clonechild, MAXPATHLEN, "%s/cgroup.clone_children",
		       cginit);
	if (ret < 0 || ret >= MAXPATHLEN) {
		SYSERROR("Failed creating pathname for clone_children (%d)\n", ret);
		return -1;
	}

	/* we check if the kernel has clone_children, at this point if there
	 * no clone_children neither ns_cgroup, that means the cgroup is mounted
	 * without the ns_cgroup and it has not the compatibility flag
	 */
	if (access(clonechild, F_OK)) {
		ERROR("no ns_cgroup option specified");
		return -1;
	}

	/* enable the clone_children flag of the cgroup */
	if (cgroup_enable_clone_children(clonechild)) {
		SYSERROR("failed to enable 'clone_children flag");
		return -1;
	}

	/* if cgparent does not exist, create it */
	if (access(cgparent, F_OK) && mkdir(cgparent, 0755)) {
		SYSERROR("failed to create '%s' directory", cgparent);
		return -1;
	}

	/*
	 * There is a previous cgroup.  Try to delete it.  If that fails
	 * (i.e. it is not empty) try to move it out of the way.
	 */
	if (!access(cgname, F_OK) && rmdir(cgname)) {
		if (try_to_move_cgname(cgparent, cgname)) {
			SYSERROR("failed to remove previous cgroup '%s'", cgname);
			return -1;
		}
	}

	/* Let's create the cgroup */
	if (mkdir(cgname, 0755)) {
		SYSERROR("failed to create '%s' directory", cgname);
		return -1;
	}

	INFO("created cgroup '%s'", cgname);

	return 0;
}