static bool cgm_setup_limits(void *hdata, struct lxc_list *cgroup_settings, bool do_devices) { struct cgm_data *d = hdata; struct lxc_list *iterator, *sorted_cgroup_settings, *next; struct lxc_cgroup *cg; bool ret = false; if (lxc_list_empty(cgroup_settings)) return true; if (!d || !d->cgroup_path) return false; if (!cgm_dbus_connect()) { ERROR("Error connecting to cgroup manager"); return false; } sorted_cgroup_settings = sort_cgroup_settings(cgroup_settings); if (!sorted_cgroup_settings) { return false; } lxc_list_for_each(iterator, sorted_cgroup_settings) { char controller[100], *p; cg = iterator->elem; if (do_devices != !strncmp("devices", cg->subsystem, 7)) continue; if (strlen(cg->subsystem) > 100) // i smell a rat goto out; strcpy(controller, cg->subsystem); p = strchr(controller, '.'); if (p) *p = '\0'; if (cgmanager_set_value_sync(NULL, cgroup_manager, controller, d->cgroup_path, cg->subsystem, cg->value) != 0) { NihError *nerr; nerr = nih_error_get(); if (do_devices) { WARN("call to cgmanager_set_value_sync failed: %s", nerr->message); nih_free(nerr); WARN("Error setting cgroup %s:%s limit type %s", controller, d->cgroup_path, cg->subsystem); continue; } ERROR("call to cgmanager_set_value_sync failed: %s", nerr->message); nih_free(nerr); ERROR("Error setting cgroup %s:%s limit type %s", controller, d->cgroup_path, cg->subsystem); goto out; } DEBUG("cgroup '%s' set to '%s'", cg->subsystem, cg->value); }
static bool cgm_unfreeze_fromhandler(struct lxc_handler *handler) { char *cgroup_path = handler->cgroup_info->data; if (cgmanager_set_value_sync(NULL, cgroup_manager, "freezer", cgroup_path, "freezer.state", "THAWED") != 0) { NihError *nerr; nerr = nih_error_get(); ERROR("call to cgmanager_set_value_sync failed: %s", nerr->message); nih_free(nerr); ERROR("Error unfreezing %s", cgroup_path); return false; } return true; }
static int cgm_do_set(const char *controller, const char *file, const char *cgroup, const char *value) { int ret; ret = cgmanager_set_value_sync(NULL, cgroup_manager, controller, cgroup, file, value); if (ret != 0) { NihError *nerr; nerr = nih_error_get(); ERROR("call to cgmanager_remove_sync failed: %s", nerr->message); nih_free(nerr); ERROR("Error setting cgroup %s limit %s", file, cgroup); } return ret; }
bool cgm_set_value(const char *controller, const char *cgroup, const char *file, const char *value) { if (!cgm_dbus_connect()) { return false; } if ( cgmanager_set_value_sync(NULL, cgroup_manager, controller, cgroup, file, value) != 0 ) { NihError *nerr; nerr = nih_error_get(); fprintf(stderr, "call to set_value (%s:%s, %s, %s) failed: %s\n", controller, cgroup, file, value, nerr->message); nih_free(nerr); cgm_dbus_disconnect(); return false; } cgm_dbus_disconnect(); return true; }
/* unfreeze is called by the command api after killing a container. */ static bool cgm_unfreeze(void *hdata) { struct cgm_data *d = hdata; bool ret = true; if (!d || !d->cgroup_path) return false; if (!cgm_dbus_connect()) { ERROR("Error connecting to cgroup manager"); return false; } if (cgmanager_set_value_sync(NULL, cgroup_manager, "freezer", d->cgroup_path, "freezer.state", "THAWED") != 0) { NihError *nerr; nerr = nih_error_get(); ERROR("call to cgmanager_set_value_sync failed: %s", nerr->message); nih_free(nerr); ERROR("Error unfreezing %s", d->cgroup_path); ret = false; } cgm_dbus_disconnect(); return ret; }
static void do_cgm_set(const char *name, const char *lxcpath, const char *filename, const char *value, int outp) { char *controller, *key, *cgroup = NULL; int retval = 0; // value we are sending to the parent over outp int ret; char *cglast; controller = alloca(strlen(filename)+1); strcpy(controller, filename); key = strchr(controller, '.'); if (!key) { ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); exit(1); } *key = '\0'; if (!cgm_dbus_connect()) { ERROR("Error connecting to cgroup manager"); ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); exit(1); } cgroup = try_get_abs_cgroup(name, lxcpath, controller); if (!cgroup) { cgm_dbus_disconnect(); ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); exit(1); } cglast = strrchr(cgroup, '/'); if (!cglast) { cgm_dbus_disconnect(); free_abs_cgroup(cgroup); ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); exit(1); } *cglast = '\0'; if (!lxc_cgmanager_enter(getpid(), controller, cgroup, abs_cgroup_supported())) { ERROR("Failed to enter container cgroup %s:%s", controller, cgroup); ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); cgm_dbus_disconnect(); free_abs_cgroup(cgroup); exit(1); } if (cgmanager_set_value_sync(NULL, cgroup_manager, controller, cglast+1, filename, value) != 0) { NihError *nerr; nerr = nih_error_get(); ERROR("Error setting cgroup value %s for %s:%s", filename, controller, cgroup); ERROR("call to cgmanager_set_value_sync failed: %s", nerr->message); nih_free(nerr); free_abs_cgroup(cgroup); cgm_dbus_disconnect(); ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) WARN("Failed to warn cgm_set of error; parent may hang"); exit(1); } free_abs_cgroup(cgroup); cgm_dbus_disconnect(); /* tell parent that we are done */ retval = 1; ret = write(outp, &retval, sizeof(retval)); if (ret != sizeof(retval)) { exit(1); } exit(0); }