summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvana Varekova <varekova@redhat.com>2009-06-03 09:37:05 +0200
committerDhaval Giani <dhaval@linux.vnet.ibm.com>2009-06-03 13:49:35 +0530
commiteee101722ff1358bf539eeb36deda8ca266f4a7a (patch)
tree13ceeaac33c96b36854890255ee1309956435874
parent54532f896e9639941d7c88b0cf0aa31c842eba58 (diff)
downloadlibcg-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.am4
-rw-r--r--src/tools/cgcreate.c203
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;
+}