/* * TODO: this should be re-written to use the get_config_item("lxc.id_map") * cmd api instead of getting the idmap from c->lxc_conf. The reason is * that the id_maps may be different if the container was started with a * -f or -s argument. * The reason I'm punting on that is because we'll need to parse the * idmap results. */ static bool cgm_attach(const char *name, const char *lxcpath, pid_t pid) { bool pass = false; char *cgroup = NULL; struct lxc_container *c; c = lxc_container_new(name, lxcpath); if (!c) { ERROR("Could not load container %s:%s", lxcpath, name); return false; } if (!collect_subsytems()) { ERROR("Error collecting cgroup subsystems"); goto out; } // cgm_create makes sure that we have the same cgroup name for all // subsystems, so since this is a slow command over the cmd socket, // just get the cgroup name for the first one. cgroup = lxc_cmd_get_cgroup_path(name, lxcpath, subsystems[0]); if (!cgroup) { ERROR("Failed to get cgroup for controller %s", subsystems[0]); goto out; } if (!(pass = do_cgm_enter(pid, cgroup))) ERROR("Failed to enter group %s", cgroup); out: free(cgroup); lxc_container_put(c); return pass; }
int cgm_get(const char *filename, char *value, size_t len, const char *name, const char *lxcpath) { char *result, *controller, *key, *cgroup; size_t newlen; controller = alloca(strlen(filename)+1); strcpy(controller, filename); key = strchr(controller, '.'); if (!key) return -1; *key = '\0'; /* use the command interface to look for the cgroup */ cgroup = lxc_cmd_get_cgroup_path(name, lxcpath, controller); if (!cgroup) return -1; if (cgmanager_get_value_sync(NULL, cgroup_manager, controller, cgroup, filename, &result) != 0) { /* * must consume the nih error * However don't print out an error as the key may simply not exist * on the host */ NihError *nerr; nerr = nih_error_get(); nih_free(nerr); free(cgroup); return -1; } free(cgroup); newlen = strlen(result); if (!value) { // user queries the size nih_free(result); return newlen+1; } strncpy(value, result, len); if (newlen >= len) { value[len-1] = '\0'; newlen = len-1; } else if (newlen+1 < len) { // cgmanager doesn't add eol to last entry value[newlen++] = '\n'; value[newlen] = '\0'; } nih_free(result); return newlen; }
static char *try_get_abs_cgroup(const char *name, const char *lxcpath, const char *controller) { char *cgroup = NULL; if (abs_cgroup_supported()) { /* get the container init pid and ask for its abs cgroup */ pid_t pid = lxc_cmd_get_init_pid(name, lxcpath); if (pid < 0) return NULL; if (cgmanager_get_pid_cgroup_abs_sync(NULL, cgroup_manager, controller, pid, &cgroup) != 0) { cgroup = NULL; NihError *nerr; nerr = nih_error_get(); nih_free(nerr); } return cgroup; } /* use the command interface to look for the cgroup */ return lxc_cmd_get_cgroup_path(name, lxcpath, controller); }
int cgm_set(const char *filename, const char *value, const char *name, const char *lxcpath) { char *controller, *key, *cgroup; int ret; controller = alloca(strlen(filename)+1); strcpy(controller, filename); key = strchr(controller, '.'); if (!key) return -1; *key = '\0'; /* use the command interface to look for the cgroup */ cgroup = lxc_cmd_get_cgroup_path(name, lxcpath, controller); if (!cgroup) { ERROR("Failed to get cgroup for controller %s for %s:%s", controller, lxcpath, name); return -1; } ret = cgm_do_set(controller, filename, cgroup, value); free(cgroup); return ret; }
/* * test_running_container: test cgroup functions against a running container * * @group : name of the container group or NULL for default "lxc" * @name : name of the container */ static int test_running_container(const char *lxcpath, const char *group, const char *name) { int ret = -1; struct lxc_container *c = NULL; char *cgrelpath; char relpath[PATH_MAX+1]; char value[NAME_MAX], value_save[NAME_MAX]; sprintf(relpath, "%s/%s", group ? group : "lxc", name); if ((c = lxc_container_new(name, lxcpath)) == NULL) { TSTERR("container %s couldn't instantiate", name); goto err1; } if (!c->is_defined(c)) { TSTERR("container %s does not exist", name); goto err2; } cgrelpath = lxc_cmd_get_cgroup_path(c->name, c->config_path, "freezer"); if (!cgrelpath) { TSTERR("lxc_cmd_get_cgroup_path returned NULL"); goto err2; } if (!strstr(cgrelpath, relpath)) { TSTERR("lxc_cmd_get_cgroup_path %s not in %s", relpath, cgrelpath); goto err3; } /* test get/set value using memory.soft_limit_in_bytes file */ ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value), c->name, c->config_path); if (ret < 0) { TSTERR("lxc_cgroup_get failed"); goto err3; } strcpy(value_save, value); ret = lxc_cgroup_set("memory.soft_limit_in_bytes", "512M", c->name, c->config_path); if (ret < 0) { TSTERR("lxc_cgroup_set failed %d %d", ret, errno); goto err3; } ret = lxc_cgroup_get("memory.soft_limit_in_bytes", value, sizeof(value), c->name, c->config_path); if (ret < 0) { TSTERR("lxc_cgroup_get failed"); goto err3; } if (strcmp(value, "536870912\n")) { TSTERR("lxc_cgroup_set_bypath failed to set value >%s<", value); goto err3; } /* restore original value */ ret = lxc_cgroup_set("memory.soft_limit_in_bytes", value_save, c->name, c->config_path); if (ret < 0) { TSTERR("lxc_cgroup_set failed"); goto err3; } ret = 0; err3: free(cgrelpath); err2: lxc_container_put(c); err1: return ret; }