From: Ivana Varekova Date: Wed, 3 Jun 2009 07:37:05 +0000 (+0200) Subject: This patch adds cgcreate tool X-Git-Tag: v0.34~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eee101722ff1358bf539eeb36deda8ca266f4a7a;p=thirdparty%2Flibcgroup.git This patch adds cgcreate tool This patch adds cgcreate tool, which creates cgroups based on input parameters - the syntax is: cgcreate -t : -a : -g : where: -a enables user to define admin gid and uid (implicit values are the same values which are in the parent directory) -t enables user to define task gid and uid (implicit values are the same values which are in parent directory) -g sets pairs list of controllers-relative path to cgroup ------------------------------------------------- EXAMPLES: * ../../libtool --mode=execute ./cgcreate -a :varekova -g cpuacct:first * ll /mnt/cgroups/cpuacct | grep first drwxrwxr-x 2 root varekova 0 2009-06-03 09:14 first * ll /mnt/cgroups/cpuacct/first/* -rwxrwxr-x 1 root varekova 0 2009-06-03 09:14 /mnt/cgroups/cpuacct/first/cpuacct.usage -rwxrwxr-x 1 root varekova 0 2009-06-03 09:14 /mnt/cgroups/cpuacct/first/notify_on_release -rwxrwxr-x 1 root varekova 0 2009-06-03 09:14 /mnt/cgroups/cpuacct/first/tasks * ../../libtool --mode=execute ./cgcreate -a varekova:root -t varekova:varekova -g cpuacct:second * ll /mnt/cgroups/cpuacct/ | grep second drwxrwxr-x 2 varekova root 0 2009-06-03 09:13 second * ll /mnt/cgroups/cpuacct/second total 0 -rwxrwxr-x 1 varekova root 0 2009-06-03 09:13 cpuacct.usage -rwxrwxr-x 1 varekova root 0 2009-06-03 09:13 notify_on_release -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:13 tasks * ../../libtool --mode=execute ./cgcreate -a varekova:varekova -g cpuacct:third -g cpuacct:fourth * ll /mnt/cgroups/cpuacct | grep h drwxrwxr-x 2 varekova varekova 0 2009-06-03 09:18 fourth drwxrwxr-x 2 varekova varekova 0 2009-06-03 09:18 third * ll /mnt/cgroups/cpuacct/*h* /mnt/cgroups/cpuacct/fourth: total 0 -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 cpuacct.usage -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 notify_on_release -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 tasks /mnt/cgroups/cpuacct/third: total 0 -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 cpuacct.usage -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 notify_on_release -rwxrwxr-x 1 varekova varekova 0 2009-06-03 09:18 tasks Signed-off-by: Ivana Varekova --- diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 93d09ac5..73f91300 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -3,7 +3,7 @@ LDADD = $(top_srcdir)/src/.libs/libcgroup.la if WITH_TOOLS -bin_PROGRAMS = cgexec cgclassify +bin_PROGRAMS = cgexec cgclassify cgcreate sbin_PROGRAMS = cgconfigparser @@ -11,6 +11,8 @@ cgexec_SOURCES = cgexec.c tools-common.c tools-common.h cgclassify_SOURCES = cgclassify.c tools-common.c tools-common.h +cgcreate_SOURCES = cgcreate.c tools-common.c tools-common.h + cgconfigparser_SOURCES = cgconfig.c endif diff --git a/src/tools/cgcreate.c b/src/tools/cgcreate.c new file mode 100644 index 00000000..9920be39 --- /dev/null +++ b/src/tools/cgcreate.c @@ -0,0 +1,203 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "tools-common.h" + +int main(int argc, char *argv[]) +{ + int ret = 0; + int i, j; + char c; + + /* Structure to get GID from group name */ + struct group *grp = NULL; + char *grp_string = NULL; + + /* Structure to get UID from user name */ + struct passwd *pwd = NULL; + char *pwd_string = NULL; + + uid_t tuid = CGRULE_INVALID, auid = CGRULE_INVALID; + gid_t tgid = CGRULE_INVALID, agid = CGRULE_INVALID; + + struct cgroup_group_spec *cgroup_list[CG_HIER_MAX]; + struct cgroup *cgroup; + struct cgroup_controller *cgc; + + /* no parametr on input */ + if (argc < 2) { + fprintf(stderr, "Usage is %s " + "-t : -a : " + "-g :\n", + argv[0]); + return -1; + } + + memset(cgroup_list, 0, sizeof(cgroup_list)); + /* parse arguments */ + while ((c = getopt(argc, argv, "a:t:g:")) > 0) { + switch (c) { + case 'a': + /* set admin uid/gid */ + if (optarg[0] == ':') + grp_string = strtok(optarg, ":"); + else { + pwd_string = strtok(optarg, ":"); + if (pwd_string != NULL) + grp_string = strtok(NULL, ":"); + } + + if (pwd_string != NULL) { + pwd = getpwnam(pwd_string); + if (pwd != NULL) { + auid = pwd->pw_uid; + } else { + fprintf(stderr, "%s: " + "can't find uid of user %s.\n", + argv[0], pwd_string); + return -1; + } + } + if (grp_string != NULL) { + grp = getgrnam(grp_string); + if (grp != NULL) + agid = grp->gr_gid; + else { + fprintf(stderr, "%s: " + "can't find gid of group %s.\n", + argv[0], grp_string); + return -1; + } + } + + break; + case 't': + /* set task uid/gid */ + if (optarg[0] == ':') + grp_string = strtok(optarg, ":"); + else { + pwd_string = strtok(optarg, ":"); + if (pwd_string != NULL) + grp_string = strtok(NULL, ":"); + } + + if (pwd_string != NULL) { + pwd = getpwnam(pwd_string); + if (pwd != NULL) { + tuid = pwd->pw_uid; + } else { + fprintf(stderr, "%s: " + "can't find uid of user %s.\n", + argv[0], pwd_string); + return -1; + } + } + if (grp_string != NULL) { + grp = getgrnam(grp_string); + if (grp != NULL) + tgid = grp->gr_gid; + else { + fprintf(stderr, "%s: " + "can't find gid of group %s.\n", + argv[0], grp_string); + return -1; + } + } + break; + case 'g': + if (parse_cgroup_spec(cgroup_list, optarg)) { + fprintf(stderr, "%s: " + "cgroup controller and path" + "parsing failed (%s)\n", + argv[0], argv[optind]); + return -1; + } + break; + default: + fprintf(stderr, "%s: " + "invalid command line option\n", + argv[0]); + return -1; + break; + } + } + + /* no cgroup name */ + if (argv[optind]) { + fprintf(stderr, "%s: " + "wrong arguments (%s)\n", + argv[0], argv[optind]); + ret = -1; + goto err; + } + + /* initialize libcg */ + ret = cgroup_init(); + if (ret) { + fprintf(stderr, "%s: " + "libcgroup initialization failed: %s\n", + argv[0], cgroup_strerror(ret)); + goto err; + } + + /* for each new cgroup */ + for (i = 0; i < CG_HIER_MAX; i++) { + if (!cgroup_list[i]) + break; + + /* create the new cgroup structure */ + cgroup = cgroup_new_cgroup(cgroup_list[i]->path); + if (!cgroup) { + ret = ECGFAIL; + fprintf(stderr, "%s: can't add new cgroup: %s\n", + argv[0], cgroup_strerror(ret)); + goto err; + } + + /* set uid and gid for the new cgroup based on input options */ + ret = cgroup_set_uid_gid(cgroup, tuid, tgid, auid, agid); + if (ret) + goto err; + + /* add controllers to the new cgroup */ + j = 0; + while (cgroup_list[i]->controllers[j]) { + cgc = cgroup_add_controller(cgroup, + cgroup_list[i]->controllers[j]); + if (!cgc) { + ret = ECGINVAL; + fprintf(stderr, "%s: " + "controller %s can't be add\n", + argv[0], + cgroup_list[i]->controllers[j]); + cgroup_free(&cgroup); + goto err; + } + j++; + } + + /* all variables set so create cgroup */ + ret = cgroup_create_cgroup(cgroup, 0); + if (ret) { + fprintf(stderr, "%s: " + "can't create cgroup %s: %s\n", + argv[0], cgroup->name, cgroup_strerror(ret)); + cgroup_free(&cgroup); + goto err; + } + cgroup_free(&cgroup); + } +err: + for (i = 0; i < CG_HIER_MAX; i++) { + if (cgroup_list[i]) + cgroup_free_group_spec(cgroup_list[i]); + } + return ret; +}