summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDhaval Giani <dhaval@linux.vnet.ibm.com>2009-02-25 13:05:56 +0000
committerDhaval Giani <dhaval@linux.vnet.ibm.com>2009-02-25 13:05:56 +0000
commit55c6712f697d5d92d6363fbeb19ca4c399b7f621 (patch)
tree6f56905b2160bfe38e4b09ae4cc4689b73feaeda
parent3b09fd0c50de2188a0772d329061bb2444e0f091 (diff)
downloadlibcg-55c6712f697d5d92d6363fbeb19ca4c399b7f621.tar.gz
libcg-55c6712f697d5d92d6363fbeb19ca4c399b7f621.tar.xz
libcg-55c6712f697d5d92d6363fbeb19ca4c399b7f621.zip
cgclassify: Add -g option to cgclassify
From: Jan Safranek <jsafrane@redhat.com> 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 <jsafrane@redhat.com> Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com> git-svn-id: https://libcg.svn.sourceforge.net/svnroot/libcg/trunk@340 4f4bb910-9a46-0410-90c8-c897d4f1cd53
-rw-r--r--Makefile.in4
-rw-r--r--cgclassify.c122
2 files changed, 98 insertions, 28 deletions
diff --git a/Makefile.in b/Makefile.in
index 349f183..aa369e6 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 4f7adb4..df9cb72 100644
--- a/cgclassify.c
+++ b/cgclassify.c
@@ -26,6 +26,8 @@
#include <sys/stat.h>
#include <sys/types.h>
+#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 <list of pids> \n",
+ fprintf(stderr, "usage is %s "
+ "[-g <list of controllers>:<relative path to cgroup>] "
+ "<list of pids> \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;
+
}