]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
This patch modifies libcg to use the new cgroup data structure.
authorBalbir Singh <balbir@linux.vnet.ibm.com>
Mon, 7 Apr 2008 13:27:39 +0000 (13:27 +0000)
committerBalbir Singh <balbir@linux.vnet.ibm.com>
Mon, 7 Apr 2008 13:27:39 +0000 (13:27 +0000)
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
The code is yet to be tested though

git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/branches/balbir@7 4f4bb910-9a46-0410-90c8-c897d4f1cd53

Makefile
api.c
libcg.h

index 686396e32ffc51f53b0eab2ffe06afe6b6c79e44..ec2142b2542cc359ccd8b21256e409f8e60c7c34 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ LDFLAGS= -L .
 all: cgconfig libcg.so
 
 cgconfig: libcg.so config.c y.tab.c lex.yy.c libcg.h file-ops.c
-       $(CXX) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c $(LDFLAGS) $(LIBS)
+       $(CC) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c $(LDFLAGS) $(LIBS)
 
 y.tab.c: parse.y lex.yy.c
        byacc -v -d parse.y
diff --git a/api.c b/api.c
index f842040ceca5d83729f80f576b983da65b408969..756a3315627cd93740fbeefc8a8d35e67e06d94f 100644 (file)
--- a/api.c
+++ b/api.c
@@ -75,21 +75,33 @@ static inline pid_t cg_gettid()
        return syscall(__NR_gettid);
 }
 
-/*
+static char* cg_build_path(char *name, char *path)
+{
+       strcpy(path, MOUNT_POINT);
+       strcat(path, name);
+       strcat(path, "/");
+       return path;
+}
+
+/** cg_attach_task_pid is used to assign tasks to a cgroup.
+ *  struct cgroup *cgroup: The cgroup to assign the thread to.
+ *  pid_t tid: The thread to be assigned to the cgroup.
+ *
+ *  returns 0 on success.
+ *  returns ECGROUPNOTOWNER if the caller does not have access to the cgroup.
+ *  returns ECGROUPNOTALLOWED for other causes of failure.
  */
-int cg_attach_task_pid(char *cgroup, pid_t tid)
+int cg_attach_task_pid(struct cgroup *cgroup, pid_t tid)
 {
        char path[FILENAME_MAX];
        FILE *tasks;
 
-       if (cgroup == NULL) {
-               cgroup = (char *) malloc(sizeof(char));
-               cgroup = "\0";
+       if (cgroup == NULL)
+               strcpy(path, MOUNT_POINT);
+       else {
+               cg_build_path(cgroup->name, path);
        }
 
-       strcpy(path, MOUNT_POINT);
-       strcat(path, "/");
-       strcat(path, cgroup);
        strcat(path, "/tasks");
 
        tasks = fopen(path, "w");
@@ -107,12 +119,12 @@ int cg_attach_task_pid(char *cgroup, pid_t tid)
 
 }
 
-/*
- * Used to attach the task to a control group.
+/** cg_attach_task is used to attach the current thread to a cgroup.
+ *  struct cgroup *cgroup: The cgroup to assign the current thread to.
  *
- * WARNING: Will change to use struct cgroup when it is implemented.
+ *  See cg_attach_task_pid for return values.
  */
-int cg_attach_task(char *cgroup)
+int cg_attach_task(struct cgroup *cgroup)
 {
        pid_t tid = cg_gettid();
        int error;
@@ -192,46 +204,37 @@ static int cg_set_control_value(char *path, char *val)
        return 0;
 }
 
-/*
- * WARNING: This API is not final. It WILL change format to use
- * struct cgroup. This API will then become internal and be called something
- * else.
+/** cg_modify_cgroup modifies the cgroup control files.
+ * struct cgroup *cgroup: The name will be the cgroup to be modified.
+ * The values will be the values to be modified, those not mentioned
+ * in the structure will not be modified.
  *
- * I am still not happy with how the data structure is looking at the moment,
- * plus there are a couple of additional details to be worked out. Please
- * do not rely on this API.
- *
- * Be prepared to change the implementation later once it shifts to
- * struct cgroup in the real alpha release.
- *
- * The final version is expected to be
- *
- * int modify_cgroup(struct cgroup *original, struct cgroup *final);
+ * The uids cannot be modified yet.
  *
- * where original is the cgroup which is to be modified and final is how it
- * should look.
+ * returns 0 on success.
  *
- * Also this version is still at one level since we do not have
- * multi-hierarchy support in kernel. The real alpha release should have this
- * issue sorted out as well.
  */
 
-int cg_modify_cgroup(char *cgroup, struct control_value *values[], int n)
+int cg_modify_cgroup(struct cgroup *cgroup)
 {
        char path[FILENAME_MAX], base[FILENAME_MAX];
        int i;
        int error;
 
-       strcpy(base, MOUNT_POINT);
-       strcat(base, "/");
-       strcat(base, cgroup);
-       strcat(base, "/");
-
-       for (i = 0; i < n; i++, strcpy(path, base)) {
-               strcat(path, values[i]->name);
-               error = cg_set_control_value(path, values[i]->value);
-               if (error)
-                       goto err;
+       cg_build_path(cgroup->name, base);
+
+       for (i = 0; i < CG_CONTROLLER_MAX && cgroup->controller[i];
+                                               i++, strcpy(path, base)) {
+               int j;
+               for(j = 0; j < CG_NV_MAX &&
+                       cgroup->controller[i]->values[j];
+                       j++, strcpy(path, base)) {
+                       strcat(path, cgroup->controller[i]->values[j]->name);
+                       error = cg_set_control_value(path,
+                               cgroup->controller[i]->values[j]->value);
+                       if (error)
+                               goto err;
+               }
        }
        return 0;
 err:
@@ -261,7 +264,7 @@ err:
  * multi-hierarchy support in kernel. The real alpha release should have this
  * issue sorted out as well.
  */
-int cg_create_cgroup(char *cgroup, struct control_value *values[], int n)
+int cg_create_cgroup(struct cgroup *cgroup)
 {
        char path[FILENAME_MAX], base[FILENAME_MAX];
        int i;
@@ -270,46 +273,37 @@ int cg_create_cgroup(char *cgroup, struct control_value *values[], int n)
        if (MOUNT_POINT == NULL)
                return ECGROUPNOTMOUNTED;
 
-       strcpy(path, MOUNT_POINT);
-       strcat(path, "/");
-       strcat(path, cgroup);
+       cg_build_path(cgroup->name, path);
 
        error = cg_create_control_group(path);
-       strcat(path, "/");
+
        strcpy(base, path);
 
-       for (i = 0; i < n; i++, strcpy(path, base)) {
-               strcat(path, values[i]->name);
-               error = cg_set_control_value(path, values[i]->value);
-               if (!error)
-                       return error;
+       for (i = 0; i < CG_CONTROLLER_MAX && cgroup->controller[i];
+                                               i++, strcpy(path, base)) {
+               int j;
+               for(j = 0; j < CG_NV_MAX && cgroup->controller[i]->values[j];
+                                               j++, strcpy(path, base)) {
+                       strcat(path, cgroup->controller[i]->values[j]->name);
+                       error = cg_set_control_value(path,
+                                       cgroup->controller[i]->values[j]->value);
+                       chown(path, cgroup->control_uid, cgroup->control_gid);
+                       if (!error)
+                               return error;
+               }
        }
+       strcpy(path, base);
+       strcat(path, "tasks");
+       chown(path, cgroup->tasks_uid, cgroup->tasks_gid);
        return error;
 }
 
-/*
- * WARNING: This API is not final. It WILL change format to use
- * struct cgroup. This API will then become internal and be called something
- * else.
- *
- * I am still not happy with how the data structure is looking at the moment,
- * plus there are a couple of additional details to be worked out. Please
- * do not rely on this API.
- *
- * Be prepared to change the implementation later once it shifts to
- * struct cgroup in the real alpha release.
- *
- * The final version is expected to be
+/** cg_delete cgroup deletes a control group.
+ *  struct cgroup *cgroup takes the group which is to be deleted.
  *
- * int delete_cgroup(struct cgroup *group);
- *
- * where group is the group to be deleted.
- *
- * Also this version is still at one level since we do not have
- * multi-hierarchy support in kernel. The real alpha release should have this
- * issue sorted out as well.
+ *  returns 0 on success.
  */
-int cg_delete_cgroup(char *cgroup)
+int cg_delete_cgroup(struct cgroup *cgroup)
 {
        FILE *delete_tasks, *base_tasks;
        int tids;
@@ -321,10 +315,8 @@ int cg_delete_cgroup(char *cgroup)
 
        base_tasks = fopen(path, "w");
 
-       strcpy(path, MOUNT_POINT);
-       strcat(path, "/");
-       strcat(path, cgroup);
-       strcat(path,"/tasks");
+       cg_build_path(cgroup->name, path);
+       strcat(path,"tasks");
 
        delete_tasks = fopen(path, "r");
 
@@ -333,9 +325,7 @@ int cg_delete_cgroup(char *cgroup)
                fprintf(base_tasks, "%d", tids);
        }
 
-       strcpy(path, MOUNT_POINT);
-       strcat(path, "/");
-       strcat(path, cgroup);
+       cg_build_path(cgroup->name, path);
 
        error = rmdir(path);
 
diff --git a/libcg.h b/libcg.h
index 91496cad6cfebaf5277cf344f6cb0a0e2b647260..b600a28697cb22d5a6f21949c8bdf0f5899e1f56 100644 (file)
--- a/libcg.h
+++ b/libcg.h
@@ -21,6 +21,7 @@
 __BEGIN_DECLS
 
 #include <grp.h>
+#include <linux/types.h>
 #include <stdio.h>
 #include <sys/stat.h>
 
@@ -139,17 +140,31 @@ int cg_unmount_controllers(void);
 int cg_load_config(const char *pathname);
 void cg_unload_current_config(void);
 
+#define CG_NV_MAX 100
+#define CG_CONTROLLER_MAX 100
 /* Functions and structures that can be used by the application*/
 struct control_value {
        char name[FILENAME_MAX];
        char *value;
 };
 
+struct cgroup{
+       char *name;
+       struct {
+               char *name;
+               struct control_value *values[CG_NV_MAX];
+       } *controller[CG_CONTROLLER_MAX];
+       uid_t tasks_uid;
+       gid_t tasks_gid;
+       uid_t control_uid;
+       gid_t control_gid;
+};
+
 int cg_init(void);
-int cg_attach_task(char *cgroup);
-int cg_modify_cgroup(char *cgroup, struct control_value *values[], int n);
-int cg_create_cgroup(char *cgroup, struct control_value *values[], int n);
-int cg_delete_cgroup(char *cgroup);
+int cg_attach_task(struct cgroup *cgroup);
+int cg_modify_cgroup(struct cgroup *cgroup);
+int cg_create_cgroup(struct cgroup *cgroup);
+int cg_delete_cgroup(struct cgroup *cgroup);
 
 __END_DECLS