int lxc_attach_proc_to_cgroups(pid_t pid, struct lxc_proc_context_info *ctx) { int i, ret; if (!ctx) { ERROR("No valid context supplied when asked to attach " "process to cgroups."); return -1; } for (i = 0; i < ctx->cgroups_count; i++) { char *path; /* the kernel should return paths that start with '/' */ if (ctx->cgroups[i].cgroup[0] != '/') { ERROR("For cgroup subsystem(s) %s the path '%s' does " "not start with a '/'", ctx->cgroups[i].subsystems, ctx->cgroups[i].cgroup); return -1; } /* lxc_cgroup_path_get can process multiple subsystems */ ret = lxc_cgroup_path_get(&path, ctx->cgroups[i].subsystems, &ctx->cgroups[i].cgroup[1]); if (ret) return -1; ret = lxc_cgroup_attach(path, pid); if (ret) return -1; } return 0; }
int lxc_cgroup_get(const char *name, const char *subsystem, char *value, size_t len) { int fd, ret = -1; char *nsgroup; char path[MAXPATHLEN]; ret = lxc_cgroup_path_get(&nsgroup, name); if (ret) return -1; snprintf(path, MAXPATHLEN, "%s/%s", nsgroup, subsystem); fd = open(path, O_RDONLY); if (fd < 0) { ERROR("open %s : %s", path, strerror(errno)); return -1; } ret = read(fd, value, len); if (ret < 0) ERROR("read %s : %s", path, strerror(errno)); close(fd); return ret; }
int lxc_cgroup_nrtasks(const char *name) { char *nsgroup; char path[MAXPATHLEN]; int pid, ret, count = 0; FILE *file; ret = lxc_cgroup_path_get(&nsgroup, name); if (ret) return -1; snprintf(path, MAXPATHLEN, "%s/tasks", nsgroup); file = fopen(path, "r"); if (!file) { SYSERROR("fopen '%s' failed", path); return -1; } while (fscanf(file, "%d", &pid) != EOF) count++; fclose(file); return count; }
static int freezer_state(const char *name) { char *nsgroup; char freezer[MAXPATHLEN]; char status[MAXPATHLEN]; FILE *file; int err; err = lxc_cgroup_path_get(&nsgroup, "freezer", name); if (err) return -1; err = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); if (err < 0 || err >= MAXPATHLEN) return -1; file = fopen(freezer, "r"); if (!file) return -1; err = fscanf(file, "%s", status); fclose(file); if (err == EOF) { SYSERROR("failed to read %s", freezer); return -1; } return lxc_str2state(status); }
int lxc_cgroup_set(const char *name, const char *subsystem, const char *value) { int fd, ret; char *nsgroup; char path[MAXPATHLEN]; ret = lxc_cgroup_path_get(&nsgroup, name); if (ret) return -1; snprintf(path, MAXPATHLEN, "%s/%s", nsgroup, subsystem); fd = open(path, O_WRONLY); if (fd < 0) { ERROR("open %s : %s", path, strerror(errno)); return -1; } ret = write(fd, value, strlen(value)); if (ret < 0) { ERROR("write %s : %s", path, strerror(errno)); goto out; } ret = 0; out: close(fd); return ret; }
int lxc_cgroup_nrtasks(const char *name) { char *dpath; char path[MAXPATHLEN]; int pid, ret, count = 0; FILE *file; int rc; ret = lxc_cgroup_path_get(&dpath, NULL, name); if (ret) return -1; rc = snprintf(path, MAXPATHLEN, "%s/tasks", dpath); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } file = fopen(path, "r"); if (!file) { SYSERROR("fopen '%s' failed", path); return -1; } while (fscanf(file, "%d", &pid) != EOF) count++; fclose(file); return count; }
int lxc_cgroup_get(const char *name, const char *filename, char *value, size_t len) { int fd, ret = -1; char *dirpath; char path[MAXPATHLEN]; int rc; ret = lxc_cgroup_path_get(&dirpath, filename, name); if (ret) return -1; rc = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } fd = open(path, O_RDONLY); if (fd < 0) { ERROR("open %s : %s", path, strerror(errno)); return -1; } ret = read(fd, value, len); if (ret < 0) ERROR("read %s : %s", path, strerror(errno)); close(fd); return ret; }
int lxc_cgroup_set(const char *name, const char *filename, const char *value) { int fd, ret; char *dirpath; char path[MAXPATHLEN]; int rc; ret = lxc_cgroup_path_get(&dirpath, filename, name); if (ret) return -1; rc = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } fd = open(path, O_WRONLY); if (fd < 0) { ERROR("open %s : %s", path, strerror(errno)); return -1; } ret = write(fd, value, strlen(value)); if (ret < 0) { ERROR("write %s : %s", path, strerror(errno)); goto out; } ret = 0; out: close(fd); return ret; }
int lxc_cgroup_set(const char *name, const char *filename, const char *value, const char *lxcpath) { int ret; char *dirpath; char path[MAXPATHLEN]; ret = lxc_cgroup_path_get(&dirpath, filename, name, lxcpath); if (ret) return -1; ret = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); if (ret < 0 || ret >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } return do_cgroup_set(path, value); }
/* * Get value of a cgroup setting for a container. * * @name: name of the container * @filename: the cgroup file to read (i.e. 'freezer.state') * @value: a preallocated char* into which to copy the answer * @len: the length of pre-allocated @value * @lxcpath: the lxcpath in which the container is running (i.e. * /var/lib/lxc) * * Returns < 0 on error, or the number of bytes read. * * If you pass in NULL value or 0 len, then you are asking for the size of the * file. * * Note that we can't get the file size quickly through stat or lseek. * Therefore if you pass in len > 0 but less than the file size, your only * indication will be that the return value will be equal to the passed-in ret. * We will not return the actual full file size. */ int lxc_cgroup_get(const char *name, const char *filename, char *value, size_t len, const char *lxcpath) { int fd, ret = -1; char *dirpath; char path[MAXPATHLEN]; int rc; ret = lxc_cgroup_path_get(&dirpath, filename, name, lxcpath); if (ret) return -1; rc = snprintf(path, MAXPATHLEN, "%s/%s", dirpath, filename); if (rc < 0 || rc >= MAXPATHLEN) { ERROR("pathname too long"); return -1; } fd = open(path, O_RDONLY); if (fd < 0) { ERROR("open %s : %s", path, strerror(errno)); return -1; } if (!len || !value) { char buf[100]; int count = 0; while ((ret = read(fd, buf, 100)) > 0) count += ret; if (ret >= 0) ret = count; } else { memset(value, 0, len); ret = read(fd, value, len); } if (ret < 0) ERROR("read %s : %s", path, strerror(errno)); close(fd); return ret; }