Add cgroup_cgxget() to libcgroup.so.  Create a new header
file, libcgroup/tools.h, to hold C APIs that are exported
from the tools folder.

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
---
 include/Makefile.am       |  4 +-
 include/libcgroup.h       |  1 +
 include/libcgroup/tools.h | 57 +++++++++++++++++++++++++
 src/Makefile.am           | 16 +++++--
 src/libcgroup.map         |  1 +
 src/tools/cgget.c         | 88 ++++++++++++++++++++++++++++++++-------
 6 files changed, 146 insertions(+), 21 deletions(-)
 create mode 100644 include/libcgroup/tools.h

diff --git a/include/Makefile.am b/include/Makefile.am
index 752a624ca125..44a9c0930126 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,2 +1,2 @@
-# Using 'nobase_', we what groups.h in /usr/include/libcgroup/ directory
-nobase_include_HEADERS = libcgroup.h libcgroup/error.h libcgroup/init.h 
libcgroup/groups.h libcgroup/tasks.h libcgroup/iterators.h libcgroup/config.h 
libcgroup/log.h
+# Using 'nobase_', we want groups.h in /usr/include/libcgroup/ directory
+nobase_include_HEADERS = libcgroup.h libcgroup/error.h libcgroup/init.h 
libcgroup/groups.h libcgroup/tasks.h libcgroup/iterators.h libcgroup/config.h 
libcgroup/log.h libcgroup/tools.h
diff --git a/include/libcgroup.h b/include/libcgroup.h
index 1c7d409a7ab1..17ab90eaca5b 100644
--- a/include/libcgroup.h
+++ b/include/libcgroup.h
@@ -25,6 +25,7 @@
 #include <libcgroup/tasks.h>
 #include <libcgroup/config.h>
 #include <libcgroup/log.h>
+#include <libcgroup/tools.h>
 
 #undef _LIBCGROUP_H_INSIDE
 
diff --git a/include/libcgroup/tools.h b/include/libcgroup/tools.h
new file mode 100644
index 000000000000..cc0918c14fa7
--- /dev/null
+++ b/include/libcgroup/tools.h
@@ -0,0 +1,57 @@
+/**
+ * Libcgroup tools header file
+ *
+ * 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>.
+ */
+#ifndef _LIBCGROUP_TOOLS_H
+#define _LIBCGROUP_TOOLS_H
+
+#ifndef _LIBCGROUP_H_INSIDE
+#error "Only <libcgroup.h> should be included directly."
+#endif
+
+#ifndef SWIG
+#include <features.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Read the setting-value pairs in the cgroup sysfs for cg.
+ * cgroup_cgxget() will perform the necessary conversions to match
+ * the "on-disk" format and then convert the data back to the
+ * requested version.  If successful, cg will be populated with
+ * the setting-value pairs.
+ *
+ * @param cg Input/Output cgroup. Must be initialized and freed by the caller
+ * @param version Cgroup version of cg
+ * @param ignore_unmappable Ignore failures due to settings that cannot be
+ *                          converted from one cgroup version to another
+ */
+int cgroup_cgxget(struct cgroup ** cg,
+                 enum cg_version_t version, bool ignore_unmappable);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* _LIBCGROUP_TOOLS_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index f7f07e4247f8..d7716aa80b19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,13 +11,23 @@ CLEANFILES = lex.c parse.c parse.h
 
 AM_CPPFLAGS = -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 abstraction-map.c abstraction-map.h abstraction-cpu.c 
abstraction-cpuset.c
+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 \
+                      abstraction-map.c abstraction-map.h \
+                      abstraction-cpu.c abstraction-cpuset.c \
+                      tools/cgget.c
 libcgroup_la_LIBADD = -lpthread $(CODE_COVERAGE_LIBS)
-libcgroup_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) -DSTATIC=static
+libcgroup_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) -DSTATIC=static -DLIBCG_LIB \
+                     -fPIC
 libcgroup_la_LDFLAGS = -Wl,--version-script,$(srcdir)/libcgroup.map \
        -version-number 
$(LIBRARY_VERSION_MAJOR):$(LIBRARY_VERSION_MINOR):$(LIBRARY_VERSION_RELEASE)
 
-libcgroupfortesting_la_SOURCES = $(libcgroup_la_SOURCES)
+libcgroupfortesting_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 \
+                      abstraction-map.c abstraction-map.h \
+                      abstraction-cpu.c abstraction-cpuset.c
 libcgroupfortesting_la_LIBADD = -lpthread $(CODE_COVERAGE_LIBS)
 libcgroupfortesting_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) -DSTATIC= -DUNIT_TEST
 libcgroupfortesting_la_LDFLAGS = 
-Wl,--version-script,$(top_srcdir)/tests/gunit/libcgroup_unittest.map \
diff --git a/src/libcgroup.map b/src/libcgroup.map
index d99a2ce73c04..fb161daeecf2 100644
--- a/src/libcgroup.map
+++ b/src/libcgroup.map
@@ -142,4 +142,5 @@ CGROUP_2.0 {
 
 CGROUP_3.0 {
        cgroup_convert_cgroup;
+       cgroup_cgxget;
 } CGROUP_2.0;
diff --git a/src/tools/cgget.c b/src/tools/cgget.c
index e407383d73a7..2aa5709e8dcd 100644
--- a/src/tools/cgget.c
+++ b/src/tools/cgget.c
@@ -11,7 +11,7 @@
 
 #include "tools-common.h"
 
-#ifdef CGXGET
+#if defined(CGXGET) || defined(LIBCG_LIB)
 #include "abstraction-common.h"
 #endif
 
@@ -20,13 +20,14 @@
 
 #define LL_MAX                         100
 
+#ifndef LIBCG_LIB
 static struct option const long_options[] =
 {
 #ifdef CGXGET
        {"v1", no_argument, NULL, '1'},
        {"v2", no_argument, NULL, '2'},
        {"ignore-unmappable", no_argument, NULL, 'i'},
-#endif
+#endif /* CGXGET */
        {"variable", required_argument, NULL, 'r'},
        {"help", no_argument, NULL, 'h'},
        {"all",  no_argument, NULL, 'a'},
@@ -54,7 +55,7 @@ static void usage(int status, const char *program_name)
               "v2 format\n");
        printf("  -i, --ignore-unmappable       Do not return an error for 
settings "
               "that cannot be converted\n");
-#endif
+#endif /* CGXGET */
        printf("  -a, --all                     Print info about all relevant "
               "controllers\n");
        printf("  -g <controllers>              Controller which info should "
@@ -409,7 +410,7 @@ static int parse_opts(int argc, char *argv[], struct cgroup 
**cg_list[],
 #else
 static int parse_opts(int argc, char *argv[], struct cgroup **cg_list[],
                      int * const cg_list_len, int * const mode)
-#endif
+#endif /* CGXGET */
 {
        bool do_not_fill_controller = false;
        bool fill_controller = false;
@@ -424,7 +425,7 @@ static int parse_opts(int argc, char *argv[], struct cgroup 
**cg_list[],
 #else
        while ((c = getopt_long(argc, argv, "r:hnvg:a", long_options, NULL))
                > 0) {
-#endif
+#endif /* CGXGET */
                switch (c) {
                case 'h':
                        usage(0, argv[0]);
@@ -475,7 +476,7 @@ static int parse_opts(int argc, char *argv[], struct cgroup 
**cg_list[],
                case 'i':
                        *ignore_unmappable = true;
                        break;
-#endif
+#endif /* CGXGET */
                default:
                        usage(1, argv[0]);
                        exit(1);
@@ -496,6 +497,7 @@ static int parse_opts(int argc, char *argv[], struct cgroup 
**cg_list[],
 err:
        return ret;
 }
+#endif /* !LIBCG_LIB */
 
 static int get_cv_value(struct control_value * const cv,
                        const char * const cg_name,
@@ -710,6 +712,7 @@ static int get_cgroup_values(struct cgroup * const cg)
        return ret;
 }
 
+#ifndef LIBCG_LIB
 static int get_values(struct cgroup *cg_list[], int cg_list_len)
 {
        int ret;
@@ -724,7 +727,8 @@ static int get_values(struct cgroup *cg_list[], int 
cg_list_len)
        return ret;
 }
 
-void print_control_values(const struct control_value * const cv, int mode)
+static void print_control_values(const struct control_value * const cv,
+                                int mode)
 {
        if (mode & MODE_SHOW_NAMES)
                printf("%s: ", cv->name);
@@ -735,7 +739,8 @@ void print_control_values(const struct control_value * 
const cv, int mode)
                printf("%s\n", cv->value);
 }
 
-void print_controller(const struct cgroup_controller * const cgc, int mode)
+static void print_controller(const struct cgroup_controller * const cgc,
+                            int mode)
 {
        int i;
 
@@ -768,9 +773,9 @@ static void print_cgroups(struct cgroup *cg_list[], int 
cg_list_len, int mode)
 }
 
 #ifdef CGXGET
-int convert_cgroups(struct cgroup **cg_list[], int cg_list_len,
-                   enum cg_version_t in_version,
-                   enum cg_version_t out_version)
+static int convert_cgroups(struct cgroup **cg_list[], int cg_list_len,
+                          enum cg_version_t in_version,
+                          enum cg_version_t out_version)
 {
        struct cgroup **cg_converted_list;
        int i = 0, j, ret = 0;
@@ -807,7 +812,7 @@ out:
 
        return ret;
 }
-#endif
+#endif /* CGXGET */
 
 int main(int argc, char *argv[])
 {
@@ -818,7 +823,7 @@ int main(int argc, char *argv[])
 #ifdef CGXGET
        enum cg_version_t version = CGROUP_UNK;
        bool ignore_unmappable = false;
-#endif
+#endif /* CGXGET */
 
        /* No parameter on input? */
        if (argc < 2) {
@@ -838,7 +843,7 @@ int main(int argc, char *argv[])
                         &ignore_unmappable);
 #else
        ret = parse_opts(argc, argv, &cg_list, &cg_list_len, &mode);
-#endif
+#endif /* CGXGET */
        if (ret)
                goto err;
 
@@ -851,7 +856,7 @@ int main(int argc, char *argv[])
                ret = 0;
        else if (ret)
                goto err;
-#endif
+#endif /* CGXGET */
 
        ret = get_values(cg_list, cg_list_len);
        if (ret)
@@ -861,7 +866,7 @@ int main(int argc, char *argv[])
        ret = convert_cgroups(&cg_list, cg_list_len, CGROUP_DISK, version);
        if (ret)
                goto err;
-#endif
+#endif /* CGXGET */
 
        print_cgroups(cg_list, cg_list_len, mode);
 
@@ -871,3 +876,54 @@ err:
 
        return ret;
 }
+#endif /* LIBCG_LIB */
+
+#ifdef LIBCG_LIB
+int cgroup_cgxget(struct cgroup **cg,
+                 enum cg_version_t version, bool ignore_unmappable)
+{
+       struct cgroup *disk_cg, *out_cg;
+       int ret;
+
+       if (!cg || !(*cg)) {
+               ret = ECGINVAL;
+               goto out;
+       }
+
+       disk_cg = cgroup_new_cgroup((*cg)->name);
+       if (!disk_cg) {
+               ret = ECGCONTROLLERCREATEFAILED;
+               goto out;
+       }
+
+       ret = cgroup_convert_cgroup(disk_cg, CGROUP_DISK, *cg, version);
+       if (ret == ECGNOVERSIONCONVERT && ignore_unmappable)
+               ret = 0;
+       else if (ret)
+               goto out;
+
+       ret = get_cgroup_values(disk_cg);
+       if (ret)
+               goto out;
+
+       out_cg = cgroup_new_cgroup((*cg)->name);
+       if (!out_cg) {
+               ret = ECGCONTROLLERCREATEFAILED;
+               goto out;
+       }
+
+       ret = cgroup_convert_cgroup(out_cg, version, disk_cg, CGROUP_DISK);
+       if (ret) {
+               cgroup_free(&out_cg);
+               goto out;
+       }
+
+       cgroup_free(cg);
+       *cg = out_cg;
+
+out:
+       if (disk_cg)
+               cgroup_free(&disk_cg);
+       return ret;
+}
+#endif /* LIBCG_LIB */
-- 
2.31.1



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to