On 05/25/2011 03:22 PM, Ivana Hutarova Varekova wrote: > Most of the tools use <controllers>:<path> together with -g option, > this patch adds this version of usage of -g option to cgget tool > Older have the possibility to use -g in form -g <controller> <path>. > > CHANGELOG: > * use GR_* constants instread of magic numbers > * free all alocated data (names, cgroup_list, controllers) > > -------------- > old version: > $ cgget -h > Usage: cgget [-nv] [-r<name>] [-g<controller>] [-a] ...<path> ... > > new version: > $ ./cgget -h > Usage: cgget [-nv] [-r<name>] [-g<controller>] [-a] <path> ... > or: cgget [-nv] [-r<name>] -g<controller>:<path> ... > > Signed-off-by: Ivana Hutarova Varekova <varek...@redhat.com> Acked-By: Jan Safranek <jsafr...@redhat.com>
> --- > > src/tools/cgget.c | 287 > ++++++++++++++++++++++++++++++----------------------- > 1 files changed, 165 insertions(+), 122 deletions(-) > > diff --git a/src/tools/cgget.c b/src/tools/cgget.c > index 87cdc8e..5e2d7d0 100644 > --- a/src/tools/cgget.c > +++ b/src/tools/cgget.c > @@ -24,6 +24,12 @@ static struct option const long_options[] = > {NULL, 0, NULL, 0} > }; > > +enum group{ > + GR_NOTSET = 0, /* 0 .. path not specified -g<g> or -a not used */ > + GR_GROUP, /* 1 .. path not specified -g<g> or -a used */ > + GR_LIST /* 2 .. path specified using -g<g>:<p> */ > +}; > + > > static void usage(int status, const char *program_name) > { > @@ -32,12 +38,15 @@ static void usage(int status, const char *program_name) > " try %s -h' for more information.\n", > program_name); > else { > - printf("Usage: %s [-nv] [-r<name>] [-g<controller>] [-a] ... "\ > - "<path> ...\n", program_name); > + fprintf(stdout, "Usage: %s [-nv] [-r<name>] "\ > + "[-g<controller>] [-a] <path> ...\n", program_name); > + fprintf(stdout, " or: %s [-nv] [-r<name>] "\ > + "-g<controller>:<path> ...\n", program_name); > } > } > > -static int display_one_record(char *name, struct cgroup_controller > *group_controller, > +static int display_record(char *name, > + struct cgroup_controller *group_controller, > const char *group_name, const char *program_name, int mode) > { > int ret = 0; > @@ -54,58 +63,52 @@ static int display_one_record(char *name, struct > cgroup_controller *group_contro > > if (ret == ECGEOF) { > printf("\n"); > - ret = 0; > goto read_end; > } > > - if (ret != 0) { > - fprintf(stderr, "variable file read failed %d\n", ret); > - return ret; > - } > + if (ret != 0) > + goto end; > > printf("%s", line); > - if (line[strlen(line)-1] == '\n') { > - /* if the value continue on the net row, > - * indent the next row > - */ > + if (line[strlen(line)-1] == '\n') > + /* if value continue on the next row. indent it */ > ind = 1; > - } > + > > /* read iteratively the whole value */ > while ((ret = cgroup_read_value_next(&handle, line, LL_MAX)) == 0) { > - if (ind == 1) { > + if (ind == 1) > printf("\t"); > - ind = 0; > - } > - > printf("%s", line); > + ind = 0; > > - if (line[strlen(line)-1] == '\n') { > - /* if the value continue on the net row, > - * indent the next row > - */ > + /* if value continue on the next row. indent it */ > + if (line[strlen(line)-1] == '\n') > ind = 1; > - } > } > > +read_end: > + cgroup_read_value_end(&handle); > if (ret == ECGEOF) > ret = 0; > -read_end: > > - cgroup_read_value_end(&handle); > +end: > + if (ret != 0) > + fprintf(stderr, "variable file read failed %s\n", > + cgroup_strerror(ret)); > return ret; > } > > > > -static int display_name_values(char **names, int count, const char* > group_name, > +static int display_name_values(char **names, const char* group_name, > const char *program_name, int mode) > { > int i; > struct cgroup_controller *group_controller = NULL; > struct cgroup *group = NULL; > int ret = 0; > - char *controller = NULL, *parameter = NULL; > + char *controller = NULL, *dot; > > group = cgroup_new_cgroup(group_name); > if (group == NULL) { > @@ -120,7 +123,8 @@ static int display_name_values(char **names, int count, > const char* group_name, > goto err; > } > > - for (i = 0; i < count; i++) { > + i = 0; > + while (names[i] != NULL) { > /* Parse the controller out of 'controller.parameter'. */ > free(controller); > controller = strdup(names[i]); > @@ -129,15 +133,14 @@ static int display_name_values(char **names, int count, > const char* group_name, > ret = -1; > goto err; > } > - parameter = strchr(controller, '.'); > - if (parameter == NULL) { > + dot = strchr(controller, '.'); > + if (dot == NULL) { > fprintf(stderr, "%s: error parsing parameter name\n" \ > " '%s'", program_name, names[i]); > ret = -1; > goto err; > } > - *parameter = '\0'; > - parameter++; > + *dot = '\0'; > > /* Find appropriate controller. */ > group_controller = cgroup_get_controller(group, controller); > @@ -150,10 +153,11 @@ static int display_name_values(char **names, int count, > const char* group_name, > } > > /* Finally read the parameter value.*/ > - ret = display_one_record(names[i], group_controller, > + ret = display_record(names[i], group_controller, > group_name, program_name, mode); > if (ret != 0) > goto err; > + i++; > } > err: > if (controller) > @@ -163,8 +167,8 @@ err: > return ret; > } > > -static int display_controller_values(char **controllers, int count, > - const char *group_name, const char *program_name, int mode) > +static int display_controller_values(char **controllers, const char > *group_name, > + const char *program_name, int mode) > { > struct cgroup *group = NULL; > struct cgroup_controller *group_controller = NULL; > @@ -190,8 +194,8 @@ static int display_controller_values(char **controllers, > int count, > } > > /* for all wanted controllers */ > - for (j = 0; j < count; j++) { > - > + j = 0; > + while (controllers[j] != NULL) { > /* read the controller group data */ > group_controller = cgroup_get_controller(group, controllers[j]); > if (group_controller == NULL) { > @@ -208,7 +212,7 @@ static int display_controller_values(char **controllers, > int count, > for (i = 0; i < name_count; i++) { > name = cgroup_get_value_name(group_controller, i); > if (name != NULL) { > - ret = display_one_record(name, group_controller, > + ret = display_record(name, group_controller, > group_name, program_name, mode); > if (ret) { > result = ret; > @@ -216,6 +220,7 @@ static int display_controller_values(char **controllers, > int count, > } > } > } > + j = j+1; > } > > err: > @@ -224,62 +229,67 @@ err: > > } > > -static int display_all_controllers(const char *group_name, > - const char *program_name, int mode) > +static int display_values(char **controllers, int max, const char > *group_name, > + char **names, int mode, const char *program_name) > { > - void *handle; > - int ret; > - struct cgroup_mount_point controller; > - char *name; > - int succ = 0; > + int ret, result = 0; > > - ret = cgroup_get_controller_begin(&handle, &controller); > + /* display the directory if needed */ > + if (mode & MODE_SHOW_HEADERS) > + printf("%s:\n", group_name); > > - /* go through the list of controllers/mount point pairs */ > - while (ret == 0) { > - name = controller.name; > - succ |= display_controller_values(&name, 1, > - group_name, program_name, mode); > - ret = cgroup_get_controller_next(&handle, &controller); > + /* display all wanted variables */ > + if (names[0] != NULL) { > + ret = display_name_values(names, group_name, program_name, > + mode); > + if (ret) > + result = ret; > + } > + > + /* display all wanted controllers */ > + if (controllers[0] != NULL) { > + ret = display_controller_values(controllers, group_name, > + program_name, mode); > + if (ret) > + result = ret; > } > > - cgroup_get_controller_end(&handle); > - return succ; > + /* separate each group with empty line. */ > + if (mode & MODE_SHOW_HEADERS) > + printf("\n"); > + > + return result; > } > > -static int add_record_to_buffer(int *p_number, > - int *p_max, char ***p_records, char *new_rec) > +void add_record_to_buffer(char **buffer, char *record, int capacity) > { > + int i; > > - if (*p_number >= *p_max) { > - *p_max += CG_NV_MAX; > - *p_records = (char **) realloc(*p_records, > - *p_max * sizeof(char *)); > - if (!(*p_records)) { > - fprintf(stderr, "not enough memory\n"); > - return -1; > - } > + /* find first free entry inside the cgroup data array */ > + for (i = 0; i < capacity; i++) { > + if (!buffer[i]) > + break; > } > > - (*p_records)[*p_number] = new_rec; > - (*p_number)++; > - > - return 0; > + if (i < capacity) > + buffer[i] = strdup(record); > } > > + > int main(int argc, char *argv[]) > { > int ret = 0; > int result = 0; > int c, i; > + int group_needed = GR_NOTSET; > > - char **names = NULL; > - int n_number = 0; > - int n_max = 0; > + int capacity = argc + CG_CONTROLLER_MAX; /* maximal number of records */ > + struct cgroup_group_spec **cgroup_list; /* list of all groups */ > + char **names; /* list of wanted variable names */ > + char **controllers; /* list of wanted controllers*/ > > - char **controllers = NULL; > - int c_number = 0; > - int c_max = 0; > + void *handle; > + struct cgroup_mount_point controller; > > int mode = MODE_SHOW_NAMES | MODE_SHOW_HEADERS; > > @@ -289,6 +299,17 @@ int main(int argc, char *argv[]) > return 1; > } > > + names = (char **)calloc(capacity+1, sizeof(char *)); > + controllers = (char **)calloc(capacity+1, sizeof(char *)); > + cgroup_list = (struct cgroup_group_spec **)calloc(capacity, > + sizeof(struct cgroup_group_spec *)); > + if ((names == NULL) || (controllers == NULL) || > + (cgroup_list == NULL)) { > + fprintf(stderr, "%s: out of memory\n", argv[0]); > + ret = -1; > + goto err; > + } > + > /* Parse arguments. */ > while ((c = getopt_long(argc, argv, "r:hnvg:a", long_options, NULL)) > > 0) { > @@ -311,23 +332,49 @@ int main(int argc, char *argv[]) > > case 'r': > /* Add name to buffer. */ > - ret = add_record_to_buffer( > - &n_number, &n_max, &names, optarg); > + add_record_to_buffer(names, optarg, capacity); > if (ret) { > result = ret; > goto err; > } > break; > case 'g': > - /* for each controller add all variables to list */ > - ret = add_record_to_buffer(&c_number, > - &c_max, &controllers, optarg); > - if (ret) { > - result = ret; > - goto err; > + if (strchr(optarg, ':') == NULL) { > + /* -g <group> */ > + if (group_needed == GR_LIST) { > + usage(1, argv[0]); > + result = -1; > + goto err; > + } > + group_needed = GR_GROUP; > + add_record_to_buffer(controllers, optarg, > + capacity); > + } else { > + /* -g <group>:<path> */ > + if (group_needed == GR_GROUP) { > + usage(1, argv[0]); > + result = -1; > + goto err; > + } > + group_needed = GR_LIST; > + ret = parse_cgroup_spec(cgroup_list, optarg, > + capacity); > + if (ret) { > + fprintf(stderr, "%s: cgroup controller/" > + "path parsing failed (%s)\n", > + argv[0], argv[optind]); > + ret = -1; > + goto err; > + } > } > break; > case 'a': > + if (group_needed == GR_LIST) { > + usage(1, argv[0]); > + result = -1; > + goto err; > + } > + group_needed = GR_GROUP; > /* go through cgroups for all possible controllers */ > mode |= MODE_SHOW_ALL_CONTROLLERS; > break; > @@ -335,23 +382,17 @@ int main(int argc, char *argv[]) > usage(1, argv[0]); > result = -1; > goto err; > - break; > } > } > > - if (!argv[optind]) { > - fprintf(stderr, "%s: no cgroup specified\n", argv[0]); > + if (((group_needed == GR_LIST) && (argv[optind])) || > + ((group_needed != GR_LIST) && (!argv[optind]))) { > + /* mixed -g <controller>:<path> and <path> or path not set */ > + usage(1, argv[0]); > result = -1; > goto err; > } > > - /* > - * if no controller or variable is set > - * then show values of all possible variables > - */ > - if ((c_number == 0) && (n_number == 0)) > - mode |= MODE_SHOW_ALL_CONTROLLERS; > - > /* Initialize libcgroup. */ > ret = cgroup_init(); > if (ret) { > @@ -361,44 +402,46 @@ int main(int argc, char *argv[]) > goto err; > } > > - if (!argv[optind]) { > - fprintf(stderr, "%s: no cgroup specified\n", argv[0]); > - result = -1; > - goto err; > + if ((mode & MODE_SHOW_ALL_CONTROLLERS) || > + ((controllers[0] == NULL) && (names[0] == NULL) > + && (cgroup_list[0] == NULL))) { > + /* show info about all controllers */ > + ret = cgroup_get_controller_begin(&handle, &controller); > + /* go through list of controllers, add them to the list */ > + while (ret == 0) { > + add_record_to_buffer(controllers, controller.name, > + capacity); > + ret = cgroup_get_controller_next(&handle, &controller); > + } > + cgroup_get_controller_end(&handle); > + } > + > + /* Parse control groups set by -g<c>:<p> pairs */ > + for (i = 0; i < capacity; i++) { > + if (!cgroup_list[i]) > + break; > + ret |= display_values(cgroup_list[i]->controllers, capacity, > + cgroup_list[i]->path, names, mode, argv[0]); > } > > /* Parse control groups and print them .*/ > for (i = optind; i < argc; i++) { > - > - /* display the directory if needed */ > - if (mode & MODE_SHOW_HEADERS) > - printf("%s:\n", argv[i]); > - > - ret = display_name_values(names, > - n_number, argv[i], argv[0], mode); > - if (ret) > - result = ret; > - > - ret = display_controller_values(controllers, c_number, argv[i], > - argv[0], mode - (mode & MODE_SHOW_ALL_CONTROLLERS)); > - if (ret) { > - result = ret; > - goto err; > - } > - > - if (mode & MODE_SHOW_ALL_CONTROLLERS) { > - ret = display_all_controllers(argv[i], argv[0], mode); > - /* remember the error but continue showing the rest */ > - if (ret) > - result = ret; > - } > - > - /* Separate each group with empty line. */ > - if (mode & MODE_SHOW_HEADERS && i != argc-1) > - printf("\n"); > + ret |= display_values(controllers, capacity, > + argv[i], names, mode, argv[0]); > } > > err: > + for (i = 0; i < capacity; i++) { > + if (cgroup_list[i]) > + cgroup_free_group_spec(cgroup_list[i]); > + if (controllers[i]) > + free(controllers[i]); > + if (names[i]) > + free(names[i]); > + } > free(names); > + free(cgroup_list); > + free(controllers); > + > return result; > } > > > ------------------------------------------------------------------------------ > vRanger cuts backup time in half-while increasing security. > With the market-leading solution for virtual backup and recovery, > you get blazing-fast, flexible, and affordable data protection. > Download your free trial now. > http://p.sf.net/sfu/quest-d2dcopy1 > _______________________________________________ > Libcg-devel mailing list > Libcg-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/libcg-devel ------------------------------------------------------------------------------ vRanger cuts backup time in half-while increasing security. With the market-leading solution for virtual backup and recovery, you get blazing-fast, flexible, and affordable data protection. Download your free trial now. http://p.sf.net/sfu/quest-d2dcopy1 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel