Add a new libcgroup tool - cgxget. cgxget is based upon cgget,
but it supports converting from cgroup version to another.
For example, a request like the following will work on a system
running the cgroup v1 cpu controller or the cgroup v2 cpu controller.
$ cgxget -2 cpu.weight MyCgroup
The return value to the user will match the cgroup version requested.
If the user requests a v1 setting, the return value will be a cgroup
v1 setting. And the same holds true for v2.
Signed-off-by: Tom Hromatka <[email protected]>
---
src/tools/Makefile.am | 8 ++-
src/tools/cgget.c | 115 ++++++++++++++++++++++++++++++++++++++----
2 files changed, 111 insertions(+), 12 deletions(-)
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index fd792853a27e..9b5380bc301a 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -5,8 +5,8 @@ LDADD = $(top_builddir)/src/.libs/libcgroup.la -lpthread
if WITH_TOOLS
-bin_PROGRAMS = cgexec cgclassify cgcreate cgset cgget cgdelete lssubsys\
- lscgroup cgsnapshot
+bin_PROGRAMS = cgexec cgclassify cgcreate cgset cgget cgxget cgdelete \
+ lssubsys lscgroup cgsnapshot
sbin_PROGRAMS = cgconfigparser cgclear
@@ -30,6 +30,10 @@ cgget_SOURCES = cgget.c tools-common.c tools-common.h
cgget_LIBS = $(CODE_COVERAGE_LIBS)
cgget_CFLAGS = $(CODE_COVERAGE_CFLAGS)
+cgxget_SOURCES = cgget.c tools-common.c tools-common.h
+cgxget_LIBS = $(CODE_COVERAGE_LIBS)
+cgxget_CFLAGS = $(CODE_COVERAGE_CFLAGS) -DCGXGET
+
cgconfigparser_SOURCES = cgconfig.c tools-common.c tools-common.h
cgconfigparser_LIBS = $(CODE_COVERAGE_LIBS)
cgconfigparser_CFLAGS = $(CODE_COVERAGE_CFLAGS)
diff --git a/src/tools/cgget.c b/src/tools/cgget.c
index 08c2286ca098..3359f551f6ad 100644
--- a/src/tools/cgget.c
+++ b/src/tools/cgget.c
@@ -11,6 +11,10 @@
#include "tools-common.h"
+#ifdef CGXGET
+#include "abstraction-common.h"
+#endif
+
#define MODE_SHOW_HEADERS 1
#define MODE_SHOW_NAMES 2
@@ -18,6 +22,10 @@
static struct option const long_options[] =
{
+#ifdef CGXGET
+ {"v1", no_argument, NULL, '1'},
+ {"v2", no_argument, NULL, '2'},
+#endif
{"variable", required_argument, NULL, 'r'},
{"help", no_argument, NULL, 'h'},
{"all", no_argument, NULL, 'a'},
@@ -38,17 +46,23 @@ static void usage(int status, const char *program_name)
" or: %s [-nv] [-r <name>] -g <controllers>:<path> ...\n",
program_name, program_name);
printf("Print parameter(s) of given group(s).\n");
- printf(" -a, --all Print info about all relevant "\
- "controllers\n");
- printf(" -g <controllers> Controller which info should "\
- "be displayed\n");
- printf(" -g <controllers>:<path> Control group which info "\
- "should be displayed\n");
+#ifdef CGXGET
+ printf(" -1, --v1 Provided parameters are in "
+ "v1 format\n");
+ printf(" -2, --v2 Provided parameters are in "
+ "v2 format\n");
+#endif
+ printf(" -a, --all Print info about all relevant "
+ "controllers\n");
+ printf(" -g <controllers> Controller which info should "
+ "be displayed\n");
+ printf(" -g <controllers>:<path> Control group which info "
+ "should be displayed\n");
printf(" -h, --help Display this help\n");
printf(" -n Do not print headers\n");
printf(" -r, --variable <name> Define parameter to display\n");
- printf(" -v, --values-only Print only values, not "\
- "parameter names\n");
+ printf(" -v, --values-only Print only values, not "
+ "parameter names\n");
}
static int get_controller_from_name(const char * const name,
@@ -163,7 +177,9 @@ static int parse_r_flag(struct cgroup **cg_list[], int *
const cg_list_len,
if (!cgc) {
cgc = cgroup_add_controller(cg, cntl_value_controller);
if (!cgc) {
- ret = ECGCONTROLLERCREATEFAILED;
+ fprintf(stderr, "cgget: cannot find controller '%s'\n",
+ cntl_value_controller);
+ ret = ECGOTHER;
goto out;
}
}
@@ -366,9 +382,14 @@ static int parse_opt_args(int argc, char *argv[], struct
cgroup **cg_list[],
out:
return ret;
}
-
+#ifdef CGXGET
+static int parse_opts(int argc, char *argv[], struct cgroup **cg_list[],
+ int * const cg_list_len, int * const mode,
+ enum cg_version_t * const version)
+#else
static int parse_opts(int argc, char *argv[], struct cgroup **cg_list[],
int * const cg_list_len, int * const mode)
+#endif
{
bool do_not_fill_controller = false;
bool fill_controller = false;
@@ -377,8 +398,13 @@ static int parse_opts(int argc, char *argv[], struct
cgroup **cg_list[],
int c;
/* Parse arguments. */
+#ifdef CGXGET
+ while ((c = getopt_long(argc, argv, "r:hnvg:a12", long_options, NULL))
+ > 0) {
+#else
while ((c = getopt_long(argc, argv, "r:hnvg:a", long_options, NULL))
> 0) {
+#endif
switch (c) {
case 'h':
usage(0, argv[0]);
@@ -419,6 +445,14 @@ static int parse_opts(int argc, char *argv[], struct
cgroup **cg_list[],
if (ret)
goto err;
break;
+#ifdef CGXGET
+ case '1':
+ *version = CGROUP_V1;
+ break;
+ case '2':
+ *version = CGROUP_V2;
+ break;
+#endif
default:
usage(1, argv[0]);
exit(1);
@@ -709,12 +743,57 @@ 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)
+{
+ struct cgroup **cg_converted_list;
+ int i = 0, j, ret = 0;
+
+ cg_converted_list = malloc(cg_list_len * sizeof(struct cgroup *));
+ if (cg_converted_list == NULL)
+ goto out;
+
+ for (i = 0; i < cg_list_len; i++) {
+ cg_converted_list[i] = cgroup_new_cgroup((*cg_list)[i]->name);
+ if (cg_converted_list[i] == NULL) {
+ ret = ECGCONTROLLERCREATEFAILED;
+ goto out;
+ }
+
+ ret = cgroup_convert_cgroup(cg_converted_list[i],
+ out_version, (*cg_list)[i], in_version);
+ if (ret)
+ goto out;
+ }
+
+out:
+ if (ret) {
+ /* the conversion failed */
+ for (j = 0; j < i; j++)
+ cgroup_free(&(cg_converted_list[i]));
+ } else {
+ /* the conversion succeeded. free the old list */
+ for (i = 0; i < cg_list_len; i++)
+ cgroup_free(cg_list[i]);
+
+ *cg_list = cg_converted_list;
+ }
+
+ return ret;
+}
+#endif
+
int main(int argc, char *argv[])
{
struct cgroup **cg_list = NULL;
int cg_list_len = 0;
int ret = 0, i;
int mode = MODE_SHOW_NAMES | MODE_SHOW_HEADERS;
+#ifdef CGXGET
+ enum cg_version_t version = CGROUP_UNK;
+#endif
/* No parameter on input? */
if (argc < 2) {
@@ -729,14 +808,30 @@ int main(int argc, char *argv[])
goto err;
}
+#ifdef CGXGET
+ ret = parse_opts(argc, argv, &cg_list, &cg_list_len, &mode, &version);
+#else
ret = parse_opts(argc, argv, &cg_list, &cg_list_len, &mode);
+#endif
+ if (ret)
+ goto err;
+
+#ifdef CGXGET
+ ret = convert_cgroups(&cg_list, cg_list_len, version, CGROUP_DISK);
if (ret)
goto err;
+#endif
ret = get_values(cg_list, cg_list_len);
if (ret)
goto err;
+#ifdef CGXGET
+ ret = convert_cgroups(&cg_list, cg_list_len, CGROUP_DISK, version);
+ if (ret)
+ goto err;
+#endif
+
print_cgroups(cg_list, cg_list_len, mode);
err:
--
2.26.2
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel