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

Reply via email to