Example #1
0
static int lxc_one_cgroup_attach(const char *name,
				 struct mntent *mntent, pid_t pid)
{
	FILE *f;
	char tasks[MAXPATHLEN], initcgroup[MAXPATHLEN];
	char *cgmnt = mntent->mnt_dir;
	int flags, ret = 0;
	int rc;

	flags = get_cgroup_flags(mntent);

	rc = snprintf(tasks, MAXPATHLEN, "%s%s%s/%s/tasks", cgmnt,
	         get_init_cgroup(NULL, mntent, initcgroup),
	         (flags & CGROUP_NS_CGROUP) ? "" : "/lxc",
	         name);
	if (rc < 0 || rc >= MAXPATHLEN) {
		ERROR("pathname too long");
		return -1;
	}

	f = fopen(tasks, "w");
	if (!f) {
		SYSERROR("failed to open '%s'", tasks);
		return -1;
	}

	if (fprintf(f, "%d", pid) <= 0) {
		SYSERROR("failed to write pid '%d' to '%s'", pid, tasks);
		ret = -1;
	}

	fclose(f);

	return ret;
}
Example #2
0
static int get_cgroup_mount(const char *subsystem, char *mnt)
{
	struct mntent *mntent;
	char initcgroup[MAXPATHLEN];
	FILE *file = NULL;
	int ret, flags, err = -1;

	file = setmntent(MTAB, "r");
	if (!file) {
		SYSERROR("failed to open %s", MTAB);
		return -1;
	}

	while ((mntent = getmntent(file))) {
		if (strcmp(mntent->mnt_type, "cgroup"))
			continue;

		if (subsystem) {
			if (!hasmntopt(mntent, subsystem))
				continue;
		}
		else {
			if (!mount_has_subsystem(mntent))
				continue;
		}

		flags = get_cgroup_flags(mntent);
		ret = snprintf(mnt, MAXPATHLEN, "%s%s%s", mntent->mnt_dir,
			       get_init_cgroup(subsystem, NULL, initcgroup),
		               (flags & CGROUP_NS_CGROUP) ? "" : "/lxc");
		if (ret < 0 || ret >= MAXPATHLEN)
			goto fail;

		DEBUG("using cgroup mounted at '%s'", mnt);
		err = 0;
		goto out;
	};

fail:
	DEBUG("Failed to find cgroup for %s\n",
	      subsystem ? subsystem : "(NULL)");
out:
	endmntent(file);
	return err;
}
Example #3
0
int lxc_one_cgroup_destroy(struct mntent *mntent, const char *name)
{
	char cgname[MAXPATHLEN], initcgroup[MAXPATHLEN];
	char *cgmnt = mntent->mnt_dir;
	int flags = get_cgroup_flags(mntent);
	int rc;

	rc = snprintf(cgname, MAXPATHLEN, "%s%s%s/%s", cgmnt,
		get_init_cgroup(NULL, mntent, initcgroup),
		(flags & CGROUP_NS_CGROUP) ? "" : "/lxc", name);
	if (rc < 0 || rc >= MAXPATHLEN) {
		ERROR("name too long");
		return -1;
	}
	DEBUG("destroying %s\n", cgname);
	if (recursive_rmdir(cgname)) {
		SYSERROR("failed to remove cgroup '%s'", cgname);
		return -1;
	}

	DEBUG("'%s' unlinked", cgname);

	return 0;
}
Example #4
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;
}
Example #5
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;
}