/* * cgroup_path_get: Calculate the full path for a particular subsystem, plus * a passed-in (to be appended) relative cgpath for a container. * @path: a char** into which a pointer to the answer is copied * @subsystem: subsystem of interest (i.e. freezer). * @cgpath: a container's (relative) cgroup path, i.e. "/lxc/c1". * * Returns 0 on success, -1 on error. * * The answer is written in a static char[MAXPATHLEN] in this function and * should not be freed. */ extern int cgroup_path_get(char **path, const char *subsystem, const char *cgpath) { static char buf[MAXPATHLEN]; static char retbuf[MAXPATHLEN]; int rc; /* lxc_cgroup_set passes a state object for the subsystem, * so trim it to just the subsystem part */ if (subsystem) { rc = snprintf(retbuf, MAXPATHLEN, "%s", subsystem); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("subsystem name too long"); return -1; } char *s = index(retbuf, '.'); if (s) *s = '\0'; DEBUG("%s: called for subsys %s name %s\n", __func__, retbuf, cgpath); } if (get_cgroup_mount(subsystem ? retbuf : NULL, buf)) { ERROR("cgroup is not mounted"); return -1; } rc = snprintf(retbuf, MAXPATHLEN, "%s/%s", buf, cgpath); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("name too long"); return -1; } DEBUG("%s: returning %s for subsystem %s", __func__, retbuf, subsystem); *path = retbuf; return 0; }
/* * lxc_cgroup_path_get: put into *path the pathname for * %subsystem and cgroup %name. If %subsystem is NULL, then * the first mounted cgroup will be used (for nr_tasks) */ int lxc_cgroup_path_get(char **path, const char *subsystem, const char *name) { static char buf[MAXPATHLEN]; static char retbuf[MAXPATHLEN]; /* what lxc_cgroup_set calls subsystem is actually the filename, i.e. 'devices.allow'. So for our purposee we trim it */ if (subsystem) { snprintf(retbuf, MAXPATHLEN, "%s", subsystem); char *s = index(retbuf, '.'); if (s) *s = '\0'; DEBUG("%s: called for subsys %s name %s\n", __func__, retbuf, name); } if (get_cgroup_mount(subsystem ? retbuf : NULL, buf)) { ERROR("cgroup is not mounted"); return -1; } snprintf(retbuf, MAXPATHLEN, "%s/%s", buf, name); DEBUG("%s: returning %s for subsystem %s", __func__, retbuf, subsystem); *path = retbuf; return 0; }
int lxc_cgroup_path_get(char **path, const char *name) { char cgroup[MAXPATHLEN]; *path = &nsgroup_path[0]; /* * report nsgroup_path string if already set */ if (**path != 0) return 0; if (get_cgroup_mount(MTAB, cgroup)) { ERROR("cgroup is not mounted"); return -1; } snprintf(nsgroup_path, MAXPATHLEN, "%s/%s", cgroup, name); return 0; }
int lxc_cgroup_destroy(const char *name) { char cgmnt[MAXPATHLEN]; char cgname[MAXPATHLEN]; if (get_cgroup_mount(MTAB, cgmnt)) { ERROR("cgroup is not mounted"); return -1; } snprintf(cgname, MAXPATHLEN, "%s/%s", cgmnt, name); if (rmdir(cgname)) { SYSERROR("failed to remove cgroup '%s'", cgname); return -1; } DEBUG("'%s' unlinked", cgname); return 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; }
int lxc_ns_is_mounted(void) { static char buf[MAXPATHLEN]; return (get_cgroup_mount("ns", buf) == 0); }