From: Balbir Singh Date: Mon, 29 Sep 2008 12:26:50 +0000 (+0000) Subject: Configuration rewrite to use the main cgroups API and several bug fixes X-Git-Tag: v0.34~217 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d1ab753ba5d0d641b52cb90e00ce2eabfae476f4;p=thirdparty%2Flibcgroup.git Configuration rewrite to use the main cgroups API and several bug fixes and configuration enhancements. Primarliy Initiated by Dhaval Giani Please see svn log of all branches/balbir-config-cleanup Signed-off-by: Balbir Singh Signed-off-by: Dhaval Giani git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@201 4f4bb910-9a46-0410-90c8-c897d4f1cd53 --- diff --git a/Makefile b/Makefile index 380dde75..c92d48f4 100644 --- a/Makefile +++ b/Makefile @@ -31,9 +31,8 @@ VERSION=1 all: libcgroup.so cgconfigparser cgexec cgclassify cgrulesengd -cgconfigparser: libcgroup.so config.c y.tab.c lex.yy.c libcgroup.h file-ops.c - $(CC) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c \ - $(LDFLAGS) $(LIBS) +cgconfigparser: libcgroup.so cgconfig.c libcgroup.h + $(CC) $(CFLAGS) -Wall -o $@ cgconfig.c $(LDFLAGS) $(LIBS) cgexec: libcgroup.so cgexec.c libcgroup.h $(CC) $(CFLAGS) -Wall -o $@ cgexec.c $(LDFLAGS) $(LIBS) @@ -51,9 +50,9 @@ y.tab.c: parse.y lex.yy.c lex.yy.c: lex.l $(LEX) lex.l -libcgroup.so: api.c libcgroup.h wrapper.c +libcgroup.so: api.c libcgroup.h wrapper.c config.c lex.yy.c y.tab.c $(CC) $(CFLAGS) -shared -fPIC -Wl,--soname,$@.$(VERSION) -o $@ api.c \ - wrapper.c + wrapper.c lex.yy.c y.tab.c config.c ln -sf $@ $@.$(VERSION) test: diff --git a/Makefile.in b/Makefile.in index aa68f4ea..74601cce 100644 --- a/Makefile.in +++ b/Makefile.in @@ -31,9 +31,8 @@ VERSION=1 all: libcgroup.so cgconfigparser cgexec cgclassify cgrulesengd -cgconfigparser: libcgroup.so config.c y.tab.c lex.yy.c libcgroup.h file-ops.c - $(CC) $(CFLAGS) -o $@ y.tab.c lex.yy.c config.c file-ops.c \ - $(LDFLAGS) $(LIBS) +cgconfigparser: libcgroup.so cgconfig.c libcgroup.h + $(CC) $(CFLAGS) -Wall -o $@ cgconfig.c $(LDFLAGS) $(LIBS) cgexec: libcgroup.so cgexec.c libcgroup.h $(CC) $(CFLAGS) -Wall -o $@ cgexec.c $(LDFLAGS) $(LIBS) @@ -51,9 +50,9 @@ y.tab.c: parse.y lex.yy.c lex.yy.c: lex.l $(LEX) lex.l -libcgroup.so: api.c libcgroup.h wrapper.c +libcgroup.so: api.c libcgroup.h wrapper.c config.c lex.yy.c y.tab.c $(CC) $(CFLAGS) -shared -fPIC -Wl,--soname,$@.$(VERSION) -o $@ api.c \ - wrapper.c + wrapper.c lex.yy.c y.tab.c config.c ln -sf $@ $@.$(VERSION) test: diff --git a/api.c b/api.c index 2cd1a373..ff2a30a2 100644 --- a/api.c +++ b/api.c @@ -658,7 +658,7 @@ static char *cg_build_path_locked(char *name, char *path, char *type) return NULL; } -static char *cg_build_path(char *name, char *path, char *type) +char *cg_build_path(char *name, char *path, char *type) { pthread_rwlock_rdlock(&cg_mount_table_lock); path = cg_build_path_locked(name, path, type); @@ -790,6 +790,76 @@ int cgroup_attach_task(struct cgroup *cgroup) return error; } +/** + * cg_mkdir_p, emulate the mkdir -p command (recursively creating paths) + * @path: path to create + */ +static int cg_mkdir_p(const char *path) +{ + char *real_path, *wd; + int i = 0, j = 0; + char pos, *str; + int ret = 0; + char cwd[FILENAME_MAX], *buf; + + buf = getcwd(cwd, FILENAME_MAX); + if (!buf) + return ECGOTHER; + + real_path = strdup(path); + if (!real_path) + return ECGOTHER; + + do { + while (real_path[j] != '\0' && real_path[j] != '/') + j++; + while (real_path[j] != '\0' && real_path[j] == '/') + j++; + if (i == j) + continue; + pos = real_path[j]; + real_path[j] = '\0'; /* Temporarily overwrite "/" */ + str = &real_path[i]; + ret = mkdir(str, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + wd = strdup(str); + if (!wd) { + ret = ECGOTHER; + break; + } + real_path[j] = pos; + if (ret) { + switch (errno) { + case EEXIST: + ret = 0; /* Not fatal really */ + break; + case EPERM: + ret = ECGROUPNOTOWNER; + free(wd); + goto done; + default: + ret = ECGROUPNOTALLOWED; + free(wd); + goto done; + } + } + i = j; + ret = chdir(wd); + if (ret) { + printf("could not chdir to child directory (%s)\n", wd); + break; + } + free(wd); + } while (real_path[i]); + + ret = chdir(buf); + if (ret) + printf("could not go back to old directory (%s)\n", cwd); + +done: + free(real_path); + return ret; +} + /* * create_control_group() * This is the basic function used to create the control group. This function @@ -801,21 +871,7 @@ static int cg_create_control_group(char *path) int error; if (!cg_test_mounted_fs()) return ECGROUPNOTMOUNTED; - error = mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (error) { - switch(errno) { - case EEXIST: - /* - * If the directory already exists, it really should - * not be an error - */ - return 0; - case EPERM: - return ECGROUPNOTOWNER; - default: - return ECGROUPNOTALLOWED; - } - } + error = cg_mkdir_p(path); return error; } @@ -1065,7 +1121,7 @@ int cgroup_create_cgroup(struct cgroup *cgroup, int ignore_ownership) strcat(path, "/tasks"); error = chown(path, cgroup->tasks_uid, cgroup->tasks_gid); - if (!error) { + if (error) { error = ECGFAIL; goto err; } diff --git a/cgconfig.c b/cgconfig.c new file mode 100644 index 00000000..b98769f0 --- /dev/null +++ b/cgconfig.c @@ -0,0 +1,55 @@ + +/* + * Copyright IBM Corporation. 2007 + * + * Authors: Dhaval Giani + * Balbir Singh + * + * 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. + * + * Code initiated and designed by Dhaval Giani. All faults are most likely + * his mistake. + */ + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int c; + char filename[PATH_MAX]; + int ret; + + if (argc < 2) { + fprintf(stderr, "usage is %s