diff options
author | Dhaval Giani <dhaval@linux.vnet.ibm.com> | 2008-08-06 17:47:41 +0000 |
---|---|---|
committer | Dhaval Giani <dhaval@linux.vnet.ibm.com> | 2008-08-06 17:47:41 +0000 |
commit | 1d408fb14ebad88d254f58f733ad6b0ffe4adaf6 (patch) | |
tree | 372b1d2c30d3af9a1bc0199cdd21737cbe702221 /api.c | |
parent | be7f8e221816cbfd0b69f7593f962133dab2fecf (diff) | |
download | libcg-1d408fb14ebad88d254f58f733ad6b0ffe4adaf6.tar.gz libcg-1d408fb14ebad88d254f58f733ad6b0ffe4adaf6.tar.xz libcg-1d408fb14ebad88d254f58f733ad6b0ffe4adaf6.zip |
libcgroup: Add new API to get cgroup data structure from filesystem
New API to get the cgroup datastructure from the mounted filesystem.
It accepts the cgroup datastructure with the name of the cgroup
which has to populated across various mountpoints.
TODO:
More testing.
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
Cc: Dan Smith <danms@us.ibm.com>
Cc: Paul Menage <menage@google.com>
git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@117 4f4bb910-9a46-0410-90c8-c897d4f1cd53
Diffstat (limited to 'api.c')
-rw-r--r-- | api.c | 153 |
1 files changed, 153 insertions, 0 deletions
@@ -22,6 +22,7 @@ * his mistake. */ +#include <dirent.h> #include <errno.h> #include <libcgroup.h> #include <libcgroup-internal.h> @@ -661,3 +662,155 @@ base_open_err: } return error; } + +/* + * This function should really have more checks, but this version + * will assume that the callers have taken care of everything. + * Including the locking. + */ +static char *cg_rd_ctrl_file(char *subsys, char *cgroup, char *file) +{ + char *value; + char path[FILENAME_MAX]; + FILE *ctrl_file; + + if (!cg_build_path_locked(cgroup, path, subsys)) + return NULL; + + strcat(path, file); + ctrl_file = fopen(path, "r"); + if (!ctrl_file) + return NULL; + + fscanf(ctrl_file, "%as", &value); + + fclose(ctrl_file); + + return value; +} + +/* + * Call this function with required locks taken. + */ +static int cgroup_fill_cgc(struct dirent *ctrl_dir, struct cgroup *cgroup, + struct cgroup_controller *cgc, int index) +{ + char *ctrl_name; + char *ctrl_file; + char *ctrl_value; + char *d_name; + char *buffer; + int error = 0; + + d_name = strdup(ctrl_dir->d_name); + + ctrl_name = strtok_r(d_name, ".", &buffer); + + if (!ctrl_name) { + error = ECGFAIL; + goto fill_error; + } + + ctrl_file = strtok_r(NULL, ".", &buffer); + + if (!ctrl_file) { + error = ECGFAIL; + goto fill_error; + } + + if (strcmp(ctrl_name, cg_mount_table[index].name) == 0) { + ctrl_value = cg_rd_ctrl_file(cg_mount_table[index].name, + cgroup->name, d_name); + if (!ctrl_value) { + error = ECGFAIL; + goto fill_error; + } + + if (cgroup_add_value_string(cgc, ctrl_dir->d_name, + ctrl_value)) { + error = ECGFAIL; + goto fill_error; + } + } +fill_error: + free(ctrl_value); + free(d_name); + return error; +} + +/* + * cgroup_get_cgroup returns the cgroup data from the filesystem. + * struct cgroup has the name of the group to be populated + * + * return succesfully filled cgroup data structure on success. + */ +struct cgroup *cgroup_get_cgroup(struct cgroup *cgroup) +{ + int i; + char path[FILENAME_MAX]; + DIR *dir; + struct dirent *ctrl_dir; + + if (!cgroup_initialized) { + /* ECGROUPNOTINITIALIZED */ + return NULL; + } + + if (!cgroup) { + /* ECGROUPNOTALLOWED */ + return NULL; + } + + pthread_rwlock_rdlock(&cg_mount_table_lock); + for (i = 0; i < CG_CONTROLLER_MAX && + cg_mount_table[i].name[0] != '\0'; i++) { + /* + * cgc will not leak, since it has to be freed using + * cgroup_free_cgroup + */ + struct cgroup_controller *cgc; + if (!cg_build_path_locked(NULL, path, + cg_mount_table[i].name)) + continue; + + strncat(path, cgroup->name, sizeof(path)); + + if (access(path, F_OK)) + continue; + + if (!cg_build_path_locked(cgroup->name, path, + cg_mount_table[i].name)) { + /* + * This fails when the cgroup does not exist + * for that controller. + */ + continue; + } + + cgc = cgroup_add_controller(cgroup, + cg_mount_table[i].name); + if (!cgc) + goto unlock_error; + + dir = opendir(path); + if (!dir) { + /* error = ECGROUPSTRUCTERROR; */ + goto unlock_error; + } + while ((ctrl_dir = readdir(dir)) != NULL) { + if (cgroup_fill_cgc(ctrl_dir, cgroup, cgc, i)) { + closedir(dir); + goto unlock_error; + } + + } + closedir(dir); + } + pthread_rwlock_unlock(&cg_mount_table_lock); + return cgroup; + +unlock_error: + pthread_rwlock_unlock(&cg_mount_table_lock); + cgroup = NULL; + return NULL; +} |