From: Dhaval Giani Date: Wed, 25 Feb 2009 13:05:56 +0000 (+0000) Subject: cgclassify: Add -g option to cgclassify X-Git-Tag: v0.34~104 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55c6712f697d5d92d6363fbeb19ca4c399b7f621;p=thirdparty%2Flibcgroup.git cgclassify: Add -g option to cgclassify From: Jan Safranek cgclassify tools currently moves processes to groups only as specified in cgrules.conf. It would be nice to move processes to another group, specified on command line, like cgexec does. Signed-off-by: Jan Safranek Signed-off-by: Dhaval Giani git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@340 4f4bb910-9a46-0410-90c8-c897d4f1cd53 --- diff --git a/Makefile.in b/Makefile.in index 349f1836..aa369e68 100644 --- a/Makefile.in +++ b/Makefile.in @@ -40,8 +40,8 @@ cgconfigparser: libcgroup.so cgconfig.c libcgroup.h cgexec: libcgroup.so cgexec.c libcgroup.h tools-common.c tools-common.h $(CC) $(CFLAGS) -Wall -o $@ cgexec.c tools-common.c $(LDFLAGS) $(LIBS) -cgclassify: libcgroup.so cgclassify.c - $(CC) $(CFLAGS) -Wall -o $@ cgclassify.c $(LDFLAGS) $(LIBS) +cgclassify: libcgroup.so cgclassify.c tools-common.c tools-common.h + $(CC) $(CFLAGS) -Wall -o $@ cgclassify.c tools-common.c $(LDFLAGS) $(LIBS) cgrulesengd: libcgroup.so libcgroup.h cgrulesengd.c cgrulesengd.h $(CC) -std=gnu99 $(CFLAGS) -Wall -o $@ cgrulesengd.c \ diff --git a/cgclassify.c b/cgclassify.c index 4f7adb4e..df9cb724 100644 --- a/cgclassify.c +++ b/cgclassify.c @@ -26,6 +26,8 @@ #include #include +#include "tools-common.h" + #define TEMP_BUF 81 /* @@ -98,19 +100,100 @@ int egid_of_pid(pid_t pid) return -1; } -int main(int argc, char *argv[]) +/* + * Change process group as specified on command line. + */ +int change_group_path(pid_t pid, struct cgroup_group_spec *cgroup_list[]) +{ + int i; + int ret = 0; + + for (i = 0; i < CG_HIER_MAX; i++) { + if (!cgroup_list[i]) + break; + + ret = cgroup_change_cgroup_path(cgroup_list[i]->path, pid, + cgroup_list[i]->controllers); + if (ret) + fprintf(stderr, "Error changing group of pid %d: %s\n", + pid, cgroup_strerror(ret)); + return -1; + } + + return 0; +} + +/* + * Change process group as specified in cgrules.conf. + */ +int change_group_uid_gid(pid_t pid) { - int ret = 0, i; uid_t euid; gid_t egid; + int ret; + + /* Put pid into right cgroup as per rules in /etc/cgrules.conf */ + euid = euid_of_pid(pid); + if (euid == -1) { + fprintf(stderr, "Error in determining euid of" + " pid %d\n", pid); + return -1; + } + + egid = egid_of_pid(pid); + if (egid == -1) { + fprintf(stderr, "Error in determining egid of" + " pid %d\n", pid); + return -1; + } + + /* Change the cgroup by determining the rules based on uid */ + ret = cgroup_change_cgroup_uid_gid(euid, egid, pid); + if (ret) { + fprintf(stderr, "Error: change of cgroup failed for" + " pid %d: %s\n", + pid, cgroup_strerror(ret)); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0, i, exit_code = 0; pid_t pid; + int cg_specified = 0; + struct cgroup_group_spec *cgroup_list[CG_HIER_MAX]; + int c; + if (argc < 2) { - fprintf(stderr, "usage is %s \n", + fprintf(stderr, "usage is %s " + "[-g :] " + " \n", argv[0]); exit(2); } + memset(cgroup_list, 0, sizeof(cgroup_list)); + while ((c = getopt(argc, argv, "+g:")) > 0) { + switch (c) { + case 'g': + if (parse_cgroup_spec(cgroup_list, optarg)) { + fprintf(stderr, "cgroup controller and path" + "parsing failed\n"); + return -1; + } + cg_specified = 1; + break; + default: + fprintf(stderr, "Invalid command line option\n"); + exit(2); + break; + } + } + /* Initialize libcg */ ret = cgroup_init(); @@ -119,31 +202,18 @@ int main(int argc, char *argv[]) return ret; } - /* Put pids into right cgroups as per rules in /etc/cgrules.conf */ - for (i = 1; i < argc; i++) { + for (i = optind; i < argc; i++) { pid = (uid_t) atoi(argv[i]); - euid = euid_of_pid(pid); - if (euid == -1) { - fprintf(stderr, "Error in determining euid of" - " pid %d\n", pid); - return -1; - } - egid = egid_of_pid(pid); - if (egid == -1) { - fprintf(stderr, "Error in determining egid of" - " pid %d\n", pid); - return -1; - } + if (cg_specified) + ret = change_group_path(pid, cgroup_list); + else + ret = change_group_uid_gid(pid); - /* Change the cgroup by determining the rules based on uid */ - ret = cgroup_change_cgroup_uid_gid(euid, egid, pid); - if (ret) { - fprintf(stderr, "Error: change of cgroup failed for" - " pid %d: %s\n", - pid, cgroup_strerror(ret)); - return ret; - } + /* if any group change fails */ + if (ret) + exit_code = 1; } - return 0; + return exit_code; + }