]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
cgclassify: Add -g option to cgclassify
authorDhaval Giani <dhaval@linux.vnet.ibm.com>
Wed, 25 Feb 2009 13:05:56 +0000 (13:05 +0000)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Wed, 25 Feb 2009 13:05:56 +0000 (13:05 +0000)
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

Makefile.in
cgclassify.c

index 349f18365a69ea9e69c2bf322383dbc3ddd05763..aa369e68f7a7115557f6eb36a3b394ccf5dfc33c 100644 (file)
@@ -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 \
index 4f7adb4e566e7e5e5c93873833878c9cac701499..df9cb724a30f2258c51422000f625a85175f74be 100644 (file)
@@ -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;
+
 }