diff options
author | Jan Safranek <jsafrane@redhat.com> | 2009-03-13 15:16:19 +0100 |
---|---|---|
committer | Jan Safranek <jsafrane@redhat.com> | 2009-03-26 09:34:18 +0100 |
commit | f8e05fc8c129a13fed256b03a23537ef94c77152 (patch) | |
tree | c64ea7d9f7daeefd307feec1bcb90ea5e3e6d600 /config.c | |
parent | 04bb98f8bd9751dd8a514b0e3a6c4862ceabeae9 (diff) | |
download | libcg-f8e05fc8c129a13fed256b03a23537ef94c77152.tar.gz libcg-f8e05fc8c129a13fed256b03a23537ef94c77152.tar.xz libcg-f8e05fc8c129a13fed256b03a23537ef94c77152.zip |
Distribute files to various subdirectories
Signed-off-by: Jan Safranek <jsafrane@redhat.com>
Diffstat (limited to 'config.c')
-rw-r--r-- | config.c | 496 |
1 files changed, 0 insertions, 496 deletions
diff --git a/config.c b/config.c deleted file mode 100644 index b188985..0000000 --- a/config.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Copyright IBM Corporation. 2007 - * - * Authors: Balbir Singh <balbir@linux.vnet.ibm.com> - * Dhaval Giani <dhaval@linux.vnet.ibm.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2.1 of the GNU Lesser General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * TODOs: - * 1. Implement our own hashing scheme - * 2. Add namespace support - * 3. Add support for parsing cgroup filesystem and creating a - * config out of it. - * - * Code initiated and designed by Balbir Singh. All faults are most likely - * his mistake. - * - * Cleanup and changes to use the "official" structures and functions made - * by Dhaval Giani. All faults will still be Balbir's mistake :) - */ - -#include <assert.h> -#include <dirent.h> -#include <errno.h> -#include <grp.h> -#include <libcgroup.h> -#include <libcgroup-internal.h> -#include <limits.h> -#include <pwd.h> -#include <pthread.h> -#include <search.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/types.h> - -#define MAX_CGROUPS 1024 - -extern FILE *yyin; -extern int yyparse(void); - -/* - * The basic global data structures. - * - * config_mount_table -> Where what controller is mounted - * table_index -> Where in the table are we. - * config_table_lock -> Serializing access to config_mount_table. - * cgroup_table -> Which cgroups have to be created. - * cgroup_table_index -> Where in the cgroup_table we are. - */ -static struct cg_mount_table_s config_mount_table[CG_CONTROLLER_MAX]; -static int config_table_index; -static pthread_rwlock_t config_table_lock = PTHREAD_RWLOCK_INITIALIZER; -static struct cgroup config_cgroup_table[MAX_CGROUPS]; -int cgroup_table_index; - -/* - * Needed for the type while mounting cgroupfs. - */ -static const char cgroup_filesystem[] = "cgroup"; - -/* - * NOTE: All these functions return 1 on success - * and not 0 as is the library convention - */ - -/* - * This call just sets the name of the cgroup. It will - * always be called in the end, because the parser will - * work bottom up. - */ -int cgroup_config_insert_cgroup(char *cg_name) -{ - struct cgroup *config_cgroup = - &config_cgroup_table[cgroup_table_index]; - - strncpy(config_cgroup->name, cg_name, FILENAME_MAX); - /* - * Since this will be the last part to be parsed. - */ - cgroup_table_index++; - free(cg_name); - return 1; -} - -/* - * This function sets the various controller's control - * files. It will always append values for cgroup_table_index - * entry in the cgroup_table. The index is incremented in - * cgroup_config_insert_cgroup - */ -int cgroup_config_parse_controller_options(char *controller, char *name_value) -{ - char *buffer = NULL; - char *name, *value; - struct cgroup_controller *cgc; - int error; - struct cgroup *config_cgroup = - &config_cgroup_table[cgroup_table_index]; - char *nm_pairs, *nv_buf; - - cgroup_dbg("Adding controller %s, value %s\n", controller, name_value); - cgc = cgroup_add_controller(config_cgroup, controller); - - if (!cgc) - goto parse_error; - - /* - * Did we just specify the controller to create the correct - * set of directories, without setting any values? - */ - if (!name_value) - goto done; - - nm_pairs = strtok_r(name_value, ":", &nv_buf); - cgroup_dbg("[1] name value pair being processed is %s\n", nm_pairs); - - name = strtok_r(nm_pairs, " ", &buffer); - - if (!name) - goto parse_error; - - value = strtok_r(NULL, " ", &buffer); - - if (!value) - goto parse_error; - - cgroup_dbg("name is %s, value is %s\n", name, value); - error = cgroup_add_value_string(cgc, name, value); - - if (error) - goto parse_error; - - while ((nm_pairs = strtok_r(NULL, ":", &nv_buf))) { - cgroup_dbg("[2] name value pair being processed is %s\n", - nm_pairs); - name = strtok_r(nm_pairs, " ", &buffer); - - if (!name) - goto parse_error; - - value = strtok_r(NULL, " ", &buffer); - - if (!value) - goto parse_error; - - cgroup_dbg("name is %s, value is %s\n", name, value); - error = cgroup_add_value_string(cgc, name, value); - - if (error) - goto parse_error; - } - -done: - free(controller); - free(name_value); - return 1; - -parse_error: - free(controller); - free(name_value); - cgroup_delete_cgroup(config_cgroup, 1); - cgroup_table_index--; - return 0; -} - -/* - * Sets the tasks file's uid and gid - */ -int cgroup_config_group_task_perm(char *perm_type, char *value) -{ - struct passwd *pw, *pw_buffer; - struct group *group, *group_buffer; - int error; - long val = atoi(value); - char buffer[CGROUP_BUFFER_LEN]; - struct cgroup *config_cgroup = - &config_cgroup_table[cgroup_table_index]; - - if (!strcmp(perm_type, "uid")) { - if (!val) { - pw = (struct passwd *) malloc(sizeof(struct passwd)); - - if (!pw) - goto group_task_error; - - error = getpwnam_r(value, pw, buffer, CGROUP_BUFFER_LEN, - &pw_buffer); - if (pw_buffer == NULL) { - free(pw); - goto group_task_error; - } - - val = pw->pw_uid; - free(pw); - } - config_cgroup->tasks_uid = val; - } - - if (!strcmp(perm_type, "gid")) { - if (!val) { - group = (struct group *) malloc(sizeof(struct group)); - - if (!group) - goto group_task_error; - - error = getgrnam_r(value, group, buffer, - CGROUP_BUFFER_LEN, &group_buffer); - - if (group_buffer == NULL) { - free(group); - goto group_task_error; - } - - val = group->gr_gid; - free(group); - } - config_cgroup->tasks_gid = val; - } - - free(perm_type); - free(value); - return 1; - -group_task_error: - free(perm_type); - free(value); - cgroup_delete_cgroup(config_cgroup, 1); - cgroup_table_index--; - return 0; -} - -/* - * Set the control file's uid/gid - */ -int cgroup_config_group_admin_perm(char *perm_type, char *value) -{ - struct passwd *pw, *pw_buffer; - struct group *group, *group_buffer; - int error; - struct cgroup *config_cgroup = - &config_cgroup_table[cgroup_table_index]; - long val = atoi(value); - char buffer[CGROUP_BUFFER_LEN]; - - if (!strcmp(perm_type, "uid")) { - if (!val) { - pw = (struct passwd *) malloc(sizeof(struct passwd)); - - if (!pw) - goto admin_error; - - error = getpwnam_r(value, pw, buffer, CGROUP_BUFFER_LEN, - &pw_buffer); - if (pw_buffer == NULL) { - free(pw); - goto admin_error; - } - - val = pw->pw_uid; - free(pw); - } - config_cgroup->control_uid = val; - } - - if (!strcmp(perm_type, "gid")) { - if (!val) { - group = (struct group *) malloc(sizeof(struct group)); - - if (!group) - goto admin_error; - - error = getgrnam_r(value, group, buffer, - CGROUP_BUFFER_LEN, &group_buffer); - - if (group_buffer == NULL) { - free(group); - goto admin_error; - } - - val = group->gr_gid; - free(group); - } - config_cgroup->control_gid = val; - } - - free(perm_type); - free(value); - return 1; - -admin_error: - free(perm_type); - free(value); - cgroup_delete_cgroup(config_cgroup, 1); - cgroup_table_index--; - return 0; -} - -/* - * The moment we have found the controller's information - * insert it into the config_mount_table. - */ -int cgroup_config_insert_into_mount_table(char *name, char *mount_point) -{ - int i; - - if (config_table_index >= CG_CONTROLLER_MAX) - return 0; - - pthread_rwlock_wrlock(&config_table_lock); - - /* - * Merge controller names with the same mount point - */ - for (i = 0; i < config_table_index; i++) { - if (strcmp(config_mount_table[i].path, mount_point) == 0) { - char *cname = config_mount_table[i].name; - strncat(cname, ",", FILENAME_MAX - strlen(cname) - 1); - strncat(cname, name, - FILENAME_MAX - strlen(cname) - 1); - goto done; - } - } - - strcpy(config_mount_table[config_table_index].name, name); - strcpy(config_mount_table[config_table_index].path, mount_point); - config_table_index++; -done: - pthread_rwlock_unlock(&config_table_lock); - free(name); - free(mount_point); - return 1; -} - -/* - * Cleanup all the data from the config_mount_table - */ -void cgroup_config_cleanup_mount_table(void) -{ - memset(&config_mount_table, 0, - sizeof(struct cg_mount_table_s) * CG_CONTROLLER_MAX); -} - -/* - * Start mounting the mount table. - */ -int cgroup_config_mount_fs() -{ - int ret; - struct stat buff; - int i; - - for (i = 0; i < config_table_index; i++) { - struct cg_mount_table_s *curr = &(config_mount_table[i]); - - ret = stat(curr->path, &buff); - - if (ret < 0 && errno != ENOENT) { - last_errno = errno; - return ECGOTHER; - } - - if (errno == ENOENT) { - ret = mkdir(curr->path, - S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (ret < 0) { - last_errno = errno; - return ECGOTHER; - } - } else if (!S_ISDIR(buff.st_mode)) { - errno = ENOTDIR; - last_errno = errno; - return ECGOTHER; - } - - ret = mount(cgroup_filesystem, curr->path, cgroup_filesystem, - 0, curr->name); - - if (ret < 0) - return ECGMOUNTFAIL; - } - return 0; -} - -/* - * Actually create the groups once the parsing has been finished. - */ -int cgroup_config_create_groups() -{ - int error = 0; - int i; - - for (i = 0; i < cgroup_table_index; i++) { - struct cgroup *cgroup = &config_cgroup_table[i]; - error = cgroup_create_cgroup(cgroup, 0); - cgroup_dbg("creating group %s, error %d\n", cgroup->name, - error); - if (error) - return error; - } - return error; -} - -/* - * Destroy the cgroups - */ -int cgroup_config_destroy_groups(void) -{ - int error = 0; - int i; - - for (i = 0; i < cgroup_table_index; i++) { - struct cgroup *cgroup = &config_cgroup_table[i]; - error = cgroup_delete_cgroup(cgroup, 0); - if (error) - return error; - } - return error; -} - -/* - * Unmount the controllers - */ -int cgroup_config_unmount_controllers(void) -{ - int i; - int error; - - for (i = 0; i < config_table_index; i++) { - /* - * We ignore failures and ensure that all mounted - * containers are unmounted - */ - error = umount(config_mount_table[i].path); - if (error < 0) - cgroup_dbg("Unmount failed\n"); - error = rmdir(config_mount_table[i].path); - if (error < 0) - cgroup_dbg("rmdir failed\n"); - } - - return 0; -} - -/* - * The main function which does all the setup of the data structures - * and finally creates the cgroups - */ -int cgroup_config_load_config(const char *pathname) -{ - int error; - yyin = fopen(pathname, "r"); - - if (!yyin) { - cgroup_dbg("Failed to open file %s\n", pathname); - last_errno = errno; - return ECGOTHER; - } - - if (yyparse() != 0) { - cgroup_dbg("Failed to parse file %s\n", pathname); - return ECGROUPPARSEFAIL; - } - - error = cgroup_config_mount_fs(); - if (error) - goto err_mnt; - - error = cgroup_init(); - if (error) - goto err_mnt; - - error = cgroup_config_create_groups(); - cgroup_dbg("creating all cgroups now, error=%d\n", error); - if (error) - goto err_grp; - - fclose(yyin); - return 0; -err_grp: - cgroup_config_destroy_groups(); -err_mnt: - cgroup_config_unmount_controllers(); - fclose(yyin); - return error; -} |