SYNOPSIS:
cgsnapshot [-h] [-n] [controller] [...]
Generate the configuration file from the current hierarchie(s) of control groups
  -h, --help            Display this help
  -n, --no-errors       Omit the output
the output have the same format as cgconfig.conf file (the values are in commas)

EXAMPLE:
$ /home/varekova/bg/libcgroup/20100719/libcg/src/tools/cgsnapshot -n
# Configuration file generated by cgsnapshot
mount {
         cpuset = /cgroup/cpuset;
         cpu = /cgroup/devices;
         cpuacct = /cgroup/memoryd;
         memory = /cgroup/memory;
         devices = /cgroup/devices;
         freezer = /cgroup/freezer;
         net_cls = /cgroup/net_cls;
}

group daemons {
        perm {
                admin {
                        uid = root;
                        gid = root;
                }
                task {
                        uid = root;
                        gid = root;
                }
        }
        cpuset {
                cpuset.memory_spread_slab="0";
                cpuset.memory_spread_page="0";
                cpuset.memory_migrate="0";
                cpuset.sched_relax_domain_level="-1";
                cpuset.sched_load_balance="1";
                cpuset.mem_hardwall="0";
                cpuset.mem_exclusive="0";
                cpuset.cpu_exclusive="0";
        }
}



Signed-off-by: Ivana Hutarova Varekova <[email protected]>
---

 src/tools/Makefile.am  |    4 
 src/tools/cgsnapshot.c |  519 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 522 insertions(+), 1 deletions(-)
 create mode 100644 src/tools/cgsnapshot.c

diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index f755037..bebdc81 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -3,7 +3,7 @@ LDADD = $(top_builddir)/src/.libs/libcgroup.la
 
 if WITH_TOOLS
 
-bin_PROGRAMS = cgexec cgclassify cgcreate cgset cgget cgdelete lssubsys 
lscgroup
+bin_PROGRAMS = cgexec cgclassify cgcreate cgset cgget cgdelete lssubsys 
lscgroup cgsnapshot
 
 sbin_PROGRAMS = cgconfigparser cgclear
 
@@ -27,6 +27,8 @@ lssubsys_SOURCES = lssubsys.c
 
 lscgroup_SOURCES = tools-common.c lscgroup.c
 
+cgsnapshot_SOURCES = cgsnapshot.c
+
 install-exec-hook:
        chmod u+s $(DESTDIR)$(bindir)/cgexec
 
diff --git a/src/tools/cgsnapshot.c b/src/tools/cgsnapshot.c
new file mode 100644
index 0000000..6d27c31
--- /dev/null
+++ b/src/tools/cgsnapshot.c
@@ -0,0 +1,519 @@
+/* " Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * " Written by Ivana Hutarova Varekova <[email protected]>
+ *
+ * This program 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 program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <libcgroup.h>
+#include <libcgroup-internal.h>
+#include <pwd.h>
+#include <grp.h>
+
+enum flag{
+    FL_LIST = 1,
+    FL_NOERR = 2,  /* don't show the error messages */
+};
+
+typedef char cont_name_t[FILENAME_MAX];
+
+/*
+ * display the usage
+ */
+static void usage(int status, const char *program_name)
+{
+       if (status != 0) {
+               fprintf(stderr, "Wrong input parameters,"
+                       " try %s -h' for more information.\n",
+                       program_name);
+       } else {
+               fprintf(stdout, "Usage: %s [-h] [-n] [controller] [...]\n",
+                       program_name);
+               fprintf(stdout, "Generate the configuration file from "\
+                       "the given controllers of control groups\n");
+               fprintf(stdout, "  -h, --help           Display this help\n");
+               fprintf(stdout, "  -n, --no-errors      Omit the error "\
+                       "output\n");
+       }
+}
+
+/* display the variable name and its value */
+static int display_variable_data(struct cgroup_file_info info,
+       int prefix_len, char cont_old[FILENAME_MAX],
+       const char *program_name)
+{
+       char *end;
+       char path[FILENAME_MAX];
+       char cont[FILENAME_MAX];
+
+       struct cgroup *group = NULL;
+       struct cgroup_controller *group_controller = NULL;
+
+       char *value = NULL;
+
+       int ret;
+       char rel_path[FILENAME_MAX];
+       struct stat sb;
+
+       /* get the controller name
+          - it is the part before "." sign in variable name */
+       strncpy(cont, info.path, FILENAME_MAX);
+       cont[FILENAME_MAX-1] = '\0';
+       end = strchr(cont, '.');
+       end[0] = '\0';
+
+       /* get the relative path to the control group
+          - remove the mount poin prefix */
+       strncpy(path, info.full_path+prefix_len, FILENAME_MAX);
+       path[FILENAME_MAX-1] = '\0';
+
+       /* get the relative path to the control group
+          - remove the file name suffix*/
+       end = strrchr(path, '/');
+       if (end != NULL)
+               end[0] = '\0';
+
+       /* open the control group for the relevant path */
+       group = cgroup_new_cgroup(path);
+       if (group == NULL) {
+               fprintf(stderr, "%s: cannot create group '%s'\n", program_name,
+                       path);
+               return -1;
+       }
+
+       /* get the data for this control group */
+       ret = cgroup_get_cgroup(group);
+       if (ret != 0) {
+               fprintf(stderr, "%s: cannot read group '%s': %s\n",
+                       program_name, path, cgroup_strerror(ret));
+               goto err;
+       }
+
+       /* find the relevant controller */
+       group_controller = cgroup_get_controller(group, cont);
+       if (group_controller == NULL) {
+               fprintf(stderr, "%s: cannot find controller " \
+                       "'%s' in group '%s'\n", program_name,
+                       cont, path);
+               ret =  -1;
+               goto err;
+       }
+
+       ret = cgroup_get_value_string(group_controller, info.path, &value);
+
+       /* variable can not be read */
+       if (ret != 0) {
+               ret = 0;
+               goto err;
+       }
+
+       if (strcmp(cont_old, cont)) {
+               if (cont_old[0] != '\0')
+                       printf("\t}\n");
+               printf("\t%s { \n", cont);
+               strcpy(cont_old, cont);
+       }
+
+       /* if the variable is nonempty */
+       if (strlen(value) != 0) {
+               /* test whether the variable file is writable */
+               strncpy(rel_path, info.full_path, FILENAME_MAX);
+               rel_path[prefix_len] = '\0';
+               strncat(rel_path, info.path, FILENAME_MAX);
+               ret = stat(rel_path, &sb);
+
+               /*
+                * freezer.state is not in root group so ret != 0,
+                * but it should be listed
+                */
+               if ((ret == 0) && ((sb.st_mode & S_IWUSR) == 0)) {
+                       /* variable is not writable */
+                       /*
+                        * TODO - device variables
+                        * should be handle in some different way
+                        */
+                       goto err_val;
+               }
+
+               printf("\t\t%s=\"%s\";\n", info.path, value);
+       }
+
+       strcpy(cont_old, cont);
+
+err_val:
+       if (value)
+               free(value);
+err:
+       cgroup_free(&group);
+
+       return ret;
+}
+
+static int display_controller_data(char controller[CG_CONTROLLER_MAX],
+               const char *program_name)
+{
+       int ret;
+       void *handle;
+
+       struct cgroup_file_info info;
+       int lvl;
+
+       char cont_old[FILENAME_MAX];
+       int start = 0;
+       int triv = 1;
+
+       int prefix_len;
+       char rel_path[FILENAME_MAX];
+       char *end;
+       struct stat sb;
+       struct passwd *pw;
+       struct group *gr;
+
+       /* start to parse the structure for the first controller -
+          controller[0] attached to hierarchie */
+       ret = cgroup_walk_tree_begin(controller, "/", 0,
+               &handle, &info, &lvl);
+       if (ret != 0)
+               return ret;
+
+       prefix_len = strlen(info.full_path);
+       cont_old[0] = '\0';
+       /* go through all files and directories */
+       while ((ret = cgroup_walk_tree_next(0, &handle, &info, lvl)) == 0) {
+               /* subgroup of / starts here */
+               if (info.type != CGROUP_FILE_TYPE_FILE) {
+                       /* group output was finished */
+                       start = 0;
+               }
+               if ((info.depth > 1) && (info.type == CGROUP_FILE_TYPE_FILE)
+                  && (start == 0)) {
+                       /* close the previous group here, if there was some */
+                       if (triv == 1)
+                               triv = 0;
+                       else
+                               printf("\t}\n}\n");
+                       start = 1;
+
+                       strncpy(rel_path, &info.full_path[prefix_len],
+                               FILENAME_MAX);
+                       rel_path[FILENAME_MAX-1] = '\0';
+
+                       end = strrchr(rel_path, '/');
+                       if (end != NULL)
+                               end[0] = '\0';
+
+                       printf("group %s {\n", rel_path);
+                       cont_old[0] = '\0';
+
+                       /* set the permission tags */
+                       printf("\tperm {\n");
+
+                       /* admin permissions */
+                       strncpy(rel_path, info.full_path, FILENAME_MAX-1);
+                       rel_path[FILENAME_MAX-1] = '\0';
+                       end = strrchr(rel_path, '/');
+                       if (end != NULL)
+                               end[0] = '\0';
+
+                       /* get the directory statistic */
+                       ret = stat(rel_path, &sb);
+                       if (ret)
+                               goto err;
+
+                       /*
+                        * from the statistic find out the
+                        * user and group name
+                        */
+                       pw = getpwuid(sb.st_uid);
+                       if (pw == NULL) {
+                               ret = -1;
+                               goto err;
+                       }
+                       gr = getgrgid(sb.st_gid);
+
+                       if (gr == NULL) {
+                               ret = -1;
+                               goto err;
+                       }
+
+                       printf("\t\tadmin {\n"\
+                               "\t\t\tuid = %s;\n"\
+                               "\t\t\tgid = %s;\n"\
+                               "\t\t}\n", pw->pw_name, gr->gr_name);
+
+                       /* tasks permissions */
+                       strncat(rel_path, "/tasks", NAME_MAX);
+                       /* get tasks file statistic */
+                       ret = stat(rel_path, &sb);
+                       if (ret)
+                               goto err;
+
+                       /*
+                        * from the statistic find out the
+                        * user and group name
+                        */
+                       pw = getpwuid(sb.st_uid);
+                       if (pw == NULL) {
+                               ret = -1;
+                               goto err;
+                       }
+
+                       gr = getgrgid(sb.st_gid);
+                       if (gr == NULL) {
+                               ret = -1;
+                               goto err;
+                       }
+
+                       printf("\t\ttask {\n" \
+                               "\t\t\tuid = %s;\n"\
+                               "\t\t\tgid = %s;\n"\
+                               "\t\t}\n", pw->pw_name, gr->gr_name);
+                       printf("\t}\n");
+               }
+               /* no output for nonvariable files */
+               if ((info.type == CGROUP_FILE_TYPE_FILE) &&
+                       /* files for non-root control group */
+                       (info.depth > 1) &&
+                       /* not variable-name file */
+                       ((strchr(info.path, '.')) != NULL) &&
+                       /* not variable-name file */
+                       (strncmp(info.path, "cgroup.", 7) != 0) &&
+                       /* files which reports data */
+                       (strcmp(info.path, "memory.stat") != 0) &&
+                       (strcmp(info.path, "cpuacct.stat") != 0) &&
+                       /*
+                        * TODO this file have to be handled
+                        * in some special way
+                        */
+                       (strcmp(info.path, "cpuacct.usage") != 0)) {
+                       ret = display_variable_data(info,
+                               prefix_len, cont_old, program_name);
+               }
+
+       }
+
+
+err:
+       if (cont_old[0] != 0)
+               printf("\t}\n");
+
+       if (triv == 0)
+               printf("}\n");
+
+       cgroup_walk_tree_end(&handle);
+       if (ret == ECGEOF)
+               ret = 0;
+
+       return ret;
+
+}
+
+static int is_ctlr_on_list(char controllers[CG_CONTROLLER_MAX][FILENAME_MAX],
+                       cont_name_t wanted_conts[FILENAME_MAX])
+{
+       int i = 0;
+       int j = 0;
+
+       while (controllers[i][0] != '\0') {
+               while (wanted_conts[j][0] != '\0') {
+                       if (strcmp(controllers[i], wanted_conts[j]) == 0)
+                               return 1;
+                       j++;
+               }
+               j = 0;
+               i++;
+       }
+
+       return 0;
+}
+
+
+/* print data about input cont_name controller */
+static int parse_controllers(cont_name_t cont_names[CG_CONTROLLER_MAX],
+       int flags, const char *program_name)
+{
+       int ret = 0;
+       void *handle;
+       char path[FILENAME_MAX];
+       struct cgroup_mount_point controller;
+
+       char controllers[CG_CONTROLLER_MAX][FILENAME_MAX];
+       int max = 0;
+
+       path[0] = '\0';
+
+       ret = cgroup_get_controller_begin(&handle, &controller);
+
+       /* go through the list of controllers/mount point pairs */
+       while (ret == 0) {
+               if (strcmp(path, controller.path) == 0) {
+                       /* if it is still the same mount point */
+                       if (max < CG_CONTROLLER_MAX) {
+                               strncpy(controllers[max],
+                                       controller.name, FILENAME_MAX);
+                               (controllers[max])[FILENAME_MAX-1] = '\0';
+                               max++;
+                       }
+               } else {
+
+                       /* we got new mount point, print it if needed */
+                       if ((!(flags & FL_LIST) ||
+                               (is_ctlr_on_list(controllers, cont_names)))
+                               && (max != 0)) {
+                               (controllers[max])[0] = '\0';
+                               ret = display_controller_data(
+                                       controllers[0], program_name);
+                       }
+
+                       strncpy(controllers[0], controller.name, FILENAME_MAX);
+                       (controllers[0])[FILENAME_MAX-1] = '\0';
+
+                       strncpy(path, controller.path, FILENAME_MAX);
+                       path[FILENAME_MAX-1] = '\0';
+                       max = 1;
+               }
+
+               /* the actual controller should not be printed */
+               ret = cgroup_get_controller_next(&handle, &controller);
+       }
+
+       if (max != 0)
+               ret = display_controller_data(
+                       controllers[0], program_name);
+
+       cgroup_get_controller_end(&handle);
+       if (ret != ECGEOF)
+               return ret;
+       return 0;
+}
+
+/* print data about input mount points */
+/* TODO only wanted ones */
+static int parse_mountpoints(cont_name_t cont_names[CG_CONTROLLER_MAX],
+       int flags, const char *program_name)
+{
+       int ret;
+       void *handle;
+       struct controller_data info;
+       char *mount_point;
+
+       /* start mount section */
+       printf("mount {\n");
+
+       /* go through the controller list */
+       ret = cgroup_get_all_controller_begin(&handle, &info);
+       while (ret != ECGEOF) {
+
+               /* the controller attached to some hierarchy */
+               if  (info.hierarchy != 0) {
+                       ret = cgroup_get_subsys_mount_point(info.name,
+                               &mount_point);
+                       if (ret != 0) {
+                               /* the controller is not mounted */
+                               if ((flags &  FL_NOERR) == 0) {
+                                       fprintf(stderr,
+                                               "%s hierarchy not mounted\n",
+                                               info.name);
+                               }
+                       } else
+                               printf("\t%s = %s;\n", info.name, mount_point);
+               }
+
+               /* next controller */
+               ret = cgroup_get_all_controller_next(&handle, &info);
+       }
+       if (ret != ECGEOF) {
+               if ((flags &  FL_NOERR) == 0) {
+                       fprintf(stderr,
+                               "error: in get next controller %s\n",
+                               cgroup_strerror(ret));
+                       return ret;
+               }
+       }
+
+       ret = cgroup_get_all_controller_end(&handle);
+
+       /* finish mount section*/
+       printf("}\n\n");
+       return ret;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret = 0;
+       int c;
+
+       int flags = 0;
+
+       int i;
+       int c_number = 0;
+       cont_name_t wanted_cont[CG_CONTROLLER_MAX];
+
+       static struct option options[] = {
+               {"help", 0, 0, 'h'},
+               {"no-error" , 0, 0, 'n'},
+               {0, 0, 0, 0}
+       };
+
+       for (i = 0; i < CG_CONTROLLER_MAX; i++)
+               wanted_cont[i][0] = '\0';
+
+       /* parse arguments */
+       while ((c = getopt_long(argc, argv, "nh", options, NULL)) > 0) {
+               switch (c) {
+               case 'h':
+                       usage(0, argv[0]);
+                       return 0;
+               case 'n':
+                       flags |= FL_NOERR;
+                       break;
+               default:
+                       usage(1, argv[0]);
+                       return -1;
+               }
+       }
+
+       /* read the list of controllers */
+       while (optind < argc) {
+               flags |= FL_LIST;
+               strncpy(wanted_cont[c_number], argv[optind], FILENAME_MAX);
+               (wanted_cont[c_number])[FILENAME_MAX-1] = '\0';
+               c_number++;
+               optind++;
+               if (optind == CG_CONTROLLER_MAX-1) {
+                       fprintf(stderr, "too many parameters\n");
+                       break;
+               }
+       }
+
+       /* print the header */
+       printf("# Configuration file generated by cgsnapshot\n");
+
+       /* initialize libcgroup */
+       ret = cgroup_init();
+
+       if (ret) {
+               /* empty configuration file */
+               return ret;
+       }
+
+       /* print mount points section */
+       ret = parse_mountpoints(wanted_cont, flags, argv[0]);
+
+       /* print hierarchies section */
+       ret = parse_controllers(wanted_cont, flags, argv[0]);
+       return ret;
+}


------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share
of $1 Million in cash or HP Products. Visit us here for more details:
http://p.sf.net/sfu/dev2dev-palm
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to