diff options
author | Ivana Varekova <varekova@redhat.com> | 2009-06-03 09:37:05 +0200 |
---|---|---|
committer | Dhaval Giani <dhaval@linux.vnet.ibm.com> | 2009-06-03 13:49:35 +0530 |
commit | eee101722ff1358bf539eeb36deda8ca266f4a7a (patch) | |
tree | 13ceeaac33c96b36854890255ee1309956435874 | |
parent | 54532f896e9639941d7c88b0cf0aa31c842eba58 (diff) | |
download | libcg-eee101722ff1358bf539eeb36deda8ca266f4a7a.tar.gz libcg-eee101722ff1358bf539eeb36deda8ca266f4a7a.tar.xz libcg-eee101722ff1358bf539eeb36deda8ca266f4a7a.zip |
This patch adds cgcreate tool
This patch adds cgcreate tool, which creates cgroups based on input
parameters - the syntax is:
cgcreate -t <tuid>:<tgid> -a <agid>:<auid> -g <list of
controllers>:<relative path to cgroup>
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 <varekova@redhat.com>
-rw-r--r-- | src/tools/Makefile.am | 4 | ||||
-rw-r--r-- | src/tools/cgcreate.c | 203 |
2 files changed, 206 insertions, 1 deletions
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index 93d09ac..73f9130 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 0000000..9920be3 --- /dev/null +++ b/src/tools/cgcreate.c @@ -0,0 +1,203 @@ +#include <libcgroup.h> +#include <libcgroup-internal.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pwd.h> +#include <sys/types.h> +#include <errno.h> + +#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 <tuid>:<tgid> -a <agid>:<auid> " + "-g <list of controllers>:<relative path to cgroup>\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; +} |