Add a function - cgroup_convert_cgroup() - that can convert from one cgroup version to another. This function will be the building block for the libcgroup abstraction layer.
Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com> --- src/abstraction-common.c | 103 +++++++++++++++++++++++++++++++++++++++ src/abstraction-common.h | 17 +++++++ src/libcgroup-internal.h | 1 + src/libcgroup.map | 4 ++ 4 files changed, 125 insertions(+) diff --git a/src/abstraction-common.c b/src/abstraction-common.c index df5fa1b3a452..e0e3984006b7 100644 --- a/src/abstraction-common.c +++ b/src/abstraction-common.c @@ -29,6 +29,7 @@ #include <unistd.h> #include "abstraction-common.h" +#include "abstraction-map.h" int cgroup_strtol(const char * const in_str, int base, long int * const out_value) @@ -108,3 +109,105 @@ out: return ret; } + +static int convert_setting(struct cgroup_controller * const out_cgc, + const struct control_value * const in_ctrl_val) +{ + const struct cgroup_abstraction_map *convert_tbl; + int tbl_sz = 0; + int ret = ECGINVAL; + int i; + + switch (out_cgc->version) { + case CGROUP_V1: + convert_tbl = cgroup_v2_to_v1_map; + tbl_sz = cgroup_v2_to_v1_map_sz; + break; + case CGROUP_V2: + convert_tbl = cgroup_v1_to_v2_map; + tbl_sz = cgroup_v1_to_v2_map_sz; + break; + default: + ret = ECGFAIL; + goto out; + } + + for (i = 0; i < tbl_sz; i++) { + if (strcmp(convert_tbl[i].in_setting, in_ctrl_val->name) == 0) { + ret = convert_tbl[i].cgroup_convert(out_cgc, + in_ctrl_val->value, + convert_tbl[i].out_setting, + convert_tbl[i].in_dflt, + convert_tbl[i].out_dflt); + if (ret) + goto out; + } + } + +out: + return ret; +} + +static int convert_controller(struct cgroup_controller * const out_cgc, + const struct cgroup_controller * const in_cgc) +{ + int ret; + int i; + + + if (in_cgc->version == out_cgc->version) { + ret = cgroup_copy_controller_values(out_cgc, in_cgc); + /* regardless of success/failure, there's nothing more to do */ + goto out; + } + + for (i = 0; i < in_cgc->index; i++) { + ret = convert_setting(out_cgc, in_cgc->values[i]); + if (ret) + goto out; + } + +out: + return ret; +} + +int cgroup_convert_cgroup(struct cgroup * const out_cgroup, + enum cg_version_t out_version, + const struct cgroup * const in_cgroup, + enum cg_version_t in_version) +{ + struct cgroup_controller *cgc; + int ret = 0; + int i; + + for (i = 0; i < in_cgroup->index; i++) { + cgc = cgroup_add_controller(out_cgroup, + in_cgroup->controller[i]->name); + if (cgc == NULL) { + ret = ECGFAIL; + goto out; + } + + /* the user has overridden the version */ + if (in_version == CGROUP_V1 || in_version == CGROUP_V2) { + in_cgroup->controller[i]->version = in_version; + } + + cgc->version = out_version; + + if (cgc->version == CGROUP_UNK || + cgc->version == CGROUP_DISK) { + ret = cgroup_get_controller_version(cgc->name, + &cgc->version); + if (ret) + goto out; + } + + ret = convert_controller(cgc, in_cgroup->controller[i]); + if (ret) + goto out; + } + +out: + return ret; +} diff --git a/src/abstraction-common.h b/src/abstraction-common.h index 02f7b9ff9541..69a28538e091 100644 --- a/src/abstraction-common.h +++ b/src/abstraction-common.h @@ -57,6 +57,23 @@ int cgroup_convert_int(struct cgroup_controller * const dst_cgc, const char * const out_setting, void *in_dflt, void *out_dflt); +/* + * Convert from one cgroup version to another version + * + * @param out_cgroup Destination cgroup + * @param out_version Destination cgroup version + * @param in_cgroup Source cgroup + * @param in_version Source cgroup version, only used if set to v1 or v2 + * + * @return 0 on success + * ECGFAIL conversion failed + * ECGCONTROLLERNOTEQUAL incorrect controller version provided + */ +int cgroup_convert_cgroup(struct cgroup * const out_cgroup, + enum cg_version_t out_version, + const struct cgroup * const in_cgroup, + enum cg_version_t in_version); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index 34c5be703920..6d9de03a00bc 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -89,6 +89,7 @@ enum cg_version_t { CGROUP_UNK = 0, CGROUP_V1, CGROUP_V2, + CGROUP_DISK = 0xFF, }; struct control_value { diff --git a/src/libcgroup.map b/src/libcgroup.map index 68098cd3accb..d99a2ce73c04 100644 --- a/src/libcgroup.map +++ b/src/libcgroup.map @@ -139,3 +139,7 @@ CGROUP_2.0 { cg_mount_table_lock; cgroup_get_controller_version; } CGROUP_0.42; + +CGROUP_3.0 { + cgroup_convert_cgroup; +} CGROUP_2.0; -- 2.25.1 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel