From: Tom Hromatka Date: Wed, 9 Feb 2022 19:27:43 +0000 (-0700) Subject: api.c: Refactor cgroup_create_cgroup() X-Git-Tag: v3.0~206^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07ebb0b9400155fe28aa1a0224199ae316073e15;p=thirdparty%2Flibcgroup.git api.c: Refactor cgroup_create_cgroup() Non-functional change to refactor cgroup_create_cgroup(). Move the contents of this "for" loop to its own function: for (k = 0; k < cgroup->index; k++) This will be used as a building block for the next commit to allow the creation of cgroups with no controllers attached. Signed-off-by: Tom Hromatka Reviewed-by: Kamalesh Babulal --- diff --git a/src/api.c b/src/api.c index e9fbe420..c13e27c7 100644 --- a/src/api.c +++ b/src/api.c @@ -2417,34 +2417,15 @@ err: return error; } -/** cgroup_create_cgroup creates a new control group. - * struct cgroup *cgroup: The control group to be created - * - * returns 0 on success. We recommend calling cg_delete_cgroup - * if this routine fails. That should do the cleanup operation. - * If ECGCANTSETVALUE is returned, the group was created successfully - * but not all controller parameters were successfully set. - */ -int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) +static int _cgroup_create_cgroup(const struct cgroup * const cgroup, + const struct cgroup_controller * const controller, + int ignore_ownership) { enum cg_version_t version; char *fts_path[2]; char *base = NULL; char *path = NULL; - int i, k; - int error = 0; - int retval = 0; - - if (!cgroup_initialized) - return ECGROUPNOTINITIALIZED; - - if (!cgroup) - return ECGROUPNOTALLOWED; - - for (i = 0; i < cgroup->index; i++) { - if (!cgroup_test_subsys_mounted(cgroup->controller[i]->name)) - return ECGROUPSUBSYSNOTMOUNTED; - } + int error; fts_path[0] = (char *)malloc(FILENAME_MAX); if (!fts_path[0]) { @@ -2454,81 +2435,69 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) fts_path[1] = NULL; path = fts_path[0]; - /* - * XX: One important test to be done is to check, if you have multiple - * subsystems mounted at one point, all of them *have* be on the cgroup - * data structure. If not, we fail. - */ - for (k = 0; k < cgroup->index; k++) { - if (!cg_build_path(cgroup->name, path, - cgroup->controller[k]->name)) - continue; - - error = cgroup_get_controller_version( - cgroup->controller[k]->name, &version); - if (error) - goto err; - - if (version == CGROUP_V2) { - char *parent, *dname; + if (!cg_build_path(cgroup->name, path, controller->name)) + goto err; - parent = strdup(path); - if (!parent) { - error = ECGOTHER; - goto err; - } + error = cgroup_get_controller_version(controller->name, &version); + if (error) + goto err; - dname = dirname(parent); + if (version == CGROUP_V2) { + char *parent, *dname; - error = cgroupv2_subtree_control_recursive(dname, - cgroup->controller[k]->name, true); - free(parent); - if (error) - goto err; + parent = strdup(path); + if (!parent) { + error = ECGOTHER; + goto err; } - error = cg_create_control_group(path); + dname = dirname(parent); + + error = cgroupv2_subtree_control_recursive(dname, + controller->name, true); + free(parent); if (error) goto err; + } - base = strdup(path); + error = cg_create_control_group(path); + if (error) + goto err; - if (!base) { - last_errno = errno; - error = ECGOTHER; - goto err; - } + base = strdup(path); - if (!ignore_ownership) { - cgroup_dbg("Changing ownership of %s\n", fts_path[0]); - error = cg_chown_recursive(fts_path, - cgroup->control_uid, cgroup->control_gid); - if (!error) - error = cg_chmod_recursive_controller(fts_path[0], - cgroup->control_dperm, - cgroup->control_dperm != NO_PERMS, - cgroup->control_fperm, - cgroup->control_fperm != NO_PERMS, - 1, cgroup_ignored_tasks_files); - } + if (!base) { + last_errno = errno; + error = ECGOTHER; + goto err; + } - if (error) - goto err; + if (!ignore_ownership) { + cgroup_dbg("Changing ownership of %s\n", fts_path[0]); + error = cg_chown_recursive(fts_path, + cgroup->control_uid, cgroup->control_gid); + if (!error) + error = cg_chmod_recursive_controller(fts_path[0], + cgroup->control_dperm, + cgroup->control_dperm != NO_PERMS, + cgroup->control_fperm, + cgroup->control_fperm != NO_PERMS, + 1, cgroup_ignored_tasks_files); + } - error = cgroup_set_values_recursive(base, - cgroup->controller[k], false); + if (error) + goto err; + + error = cgroup_set_values_recursive(base, controller, false); + if (error) + goto err; + + if (!ignore_ownership && version == CGROUP_V1) { + error = cgroup_chown_chmod_tasks(base, + cgroup->tasks_uid, cgroup->tasks_gid, + cgroup->task_fperm); if (error) goto err; - - if (!ignore_ownership && version == CGROUP_V1) { - error = cgroup_chown_chmod_tasks(base, - cgroup->tasks_uid, cgroup->tasks_gid, - cgroup->task_fperm); - if (error) - goto err; - } - free(base); - base = NULL; } err: @@ -2536,11 +2505,48 @@ err: free(path); if (base) free(base); - if (retval && !error) - error = retval; return error; } +/** cgroup_create_cgroup creates a new control group. + * struct cgroup *cgroup: The control group to be created + * + * returns 0 on success. We recommend calling cg_delete_cgroup + * if this routine fails. That should do the cleanup operation. + * If ECGCANTSETVALUE is returned, the group was created successfully + * but not all controller parameters were successfully set. + */ +int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) +{ + int error = 0; + int i; + + if (!cgroup_initialized) + return ECGROUPNOTINITIALIZED; + + if (!cgroup) + return ECGROUPNOTALLOWED; + + for (i = 0; i < cgroup->index; i++) { + if (!cgroup_test_subsys_mounted(cgroup->controller[i]->name)) + return ECGROUPSUBSYSNOTMOUNTED; + } + + /* + * XX: One important test to be done is to check, if you have multiple + * subsystems mounted at one point, all of them *have* be on the cgroup + * data structure. If not, we fail. + */ + for (i = 0; i < cgroup->index; i++) { + error = _cgroup_create_cgroup(cgroup, cgroup->controller[i], + ignore_ownership); + if (error) + return error; + } + + return 0; +} + /** * Obtain the calculated parent name of specified cgroup; no validation * of the existence of the child or parent group is performed.