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. If the user requests a v2 setting, the return value will be a cgroup v2 setting. Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com> --- 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 dc8ec9d4b6dd..bb00520be48b 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -5,8 +5,8 @@ LDADD = $(top_builddir)/src/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 @@ -36,6 +36,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 e9e29fd2350e..147af683fef7 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; } } @@ -382,9 +398,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; @@ -393,8 +414,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]); @@ -435,6 +461,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); @@ -726,12 +760,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) { @@ -746,14 +825,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.25.1 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel