Add the building blocks to convert a cpu controller from one cgroup version to another.
Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com> --- src/Makefile.am | 2 +- src/abstraction-common.c | 7 ++- src/abstraction-common.h | 13 +++++ src/ctrl-cpu.c | 117 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/ctrl-cpu.c diff --git a/src/Makefile.am b/src/Makefile.am index b2e8f02f0146..de52df417df5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,7 +15,7 @@ CLEANFILES = lex.c parse.c parse.h INCLUDES = -I$(top_srcdir)/include lib_LTLIBRARIES = libcgroup.la libcgroupfortesting.la -libcgroup_la_SOURCES = parse.h parse.y lex.l api.c config.c libcgroup-internal.h libcgroup.map wrapper.c log.c abstraction-common.c abstraction-common.h +libcgroup_la_SOURCES = parse.h parse.y lex.l api.c config.c libcgroup-internal.h libcgroup.map wrapper.c log.c abstraction-common.c abstraction-common.h ctrl-cpu.c libcgroup_la_LIBADD = -lpthread $(CODE_COVERAGE_LIBS) libcgroup_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) -DSTATIC=static libcgroup_la_LDFLAGS = -Wl,--version-script,$(srcdir)/libcgroup.map \ diff --git a/src/abstraction-common.c b/src/abstraction-common.c index f69c8af28a4b..cbb4fc993c8e 100644 --- a/src/abstraction-common.c +++ b/src/abstraction-common.c @@ -83,7 +83,12 @@ int cgroup_convert_cgroup(struct cgroup * const out_cgroup, cgc->version = out_version; - /* Controller conversions will go here */ + if (strcmp(in_cgroup->controller[i]->name, "cpu") == 0) { + ret = cgroup_convert_cpu(cgc, + in_cgroup->controller[i]); + if (ret) + goto out; + } } out: diff --git a/src/abstraction-common.h b/src/abstraction-common.h index 9a4e4d09fd77..054c4bea61b1 100644 --- a/src/abstraction-common.h +++ b/src/abstraction-common.h @@ -56,6 +56,19 @@ int cgroup_convert_cgroup(struct cgroup * const out_cgroup, const struct cgroup * const in_cgroup, enum cg_version_t in_version); +/** + * Convert from one cpu controller version to another version + * + * @param out_cgc Destination controller + * @param in_cgc Source controller + * + * @return 0 on success + * ECGFAIL conversion failed + * ECGCONTROLLERNOTEQUAL incorrect controller version provided + */ +int cgroup_convert_cpu(struct cgroup_controller * const out_cgc, + const struct cgroup_controller * const in_cgc); + __END_DECLS #endif /* __ABSTRACTION_COMMON */ diff --git a/src/ctrl-cpu.c b/src/ctrl-cpu.c new file mode 100644 index 000000000000..2fab490c7b21 --- /dev/null +++ b/src/ctrl-cpu.c @@ -0,0 +1,117 @@ +/** + * Libcgroup cpu controller abstraction layer + * + * Copyright (c) 2021 Oracle and/or its affiliates. + * Author: Tom Hromatka <tom.hroma...@oracle.com> + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see <http://www.gnu.org/licenses>. + */ +#include <libcgroup.h> +#include <libcgroup-internal.h> + +#include <errno.h> +#include <limits.h> +#include <stdlib.h> +#include <string.h> + +#include "abstraction-common.h" + +static int v1_to_v2(struct cgroup_controller * const out_cgc, + const struct cgroup_controller * const in_cgc) +{ + int i, ret = 0; + + if (in_cgc->version != CGROUP_V1) { + cgroup_err("Invalid cgroup version"); + return ECGCONTROLLERNOTEQUAL; + } + + /* At this time, I believe cpu cgroup v1 settings have a one-to-one + * mapping to cpu cgroup v2 settings. If/When this no longer becomes + * the case, we can make this function smarter. + */ + for (i = 0; i < in_cgc->index; i++) { + /* todo - add conversions here */ + } + + if (out_cgc->index == 0) + /* no settings/values were successfully converted */ + ret = ECGFAIL; + +out: + return ret; +} + +static int v2_to_v1(struct cgroup_controller * const out_cgc, + const struct cgroup_controller * const in_cgc) +{ + int i, ret = 0; + + if (in_cgc->version != CGROUP_V2) { + cgroup_err("Invalid cgroup version"); + return ECGCONTROLLERNOTEQUAL; + } + + /* At this time, I believe cpu cgroup v1 settings have a one-to-one + * mapping to cpu cgroup v2 settings. If/When this no longer becomes + * the case, we can make this function smarter. + */ + for (i = 0; i < in_cgc->index; i++) { + /* todo - add conversions here */ + } + + if (out_cgc->index == 0) + /* no settings/values were successfully converted */ + ret = ECGFAIL; + +out: + return ret; +} + +int cgroup_convert_cpu(struct cgroup_controller * const out_cgc, + const struct cgroup_controller * const in_cgc) +{ + int ret; + + if (out_cgc->version == CGROUP_UNK || + out_cgc->version == CGROUP_DISK) + { + ret = cgroup_get_controller_version(out_cgc->name, + &out_cgc->version); + if (ret) + goto out; + } + + 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; + } + + switch (out_cgc->version) { + case CGROUP_V1: + ret = v2_to_v1(out_cgc, in_cgc); + break; + case CGROUP_V2: + ret = v1_to_v2(out_cgc, in_cgc); + break; + default: + ret = ECGFAIL; + break; + } + +out: + return ret; +} -- 2.26.2 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel