]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Apply a new rule to 'cgexec' command.
authorKen'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Fri, 26 Jun 2009 05:51:20 +0000 (14:51 +0900)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Mon, 29 Jun 2009 11:21:11 +0000 (16:51 +0530)
Hi,

Changelog of v6:
================
 * No change.

Changelog of v5:
================
 * Add the description of a new option "--sticky".

Changelog of v4:
================
 * Add a new option "--sticky" so that cgrulesengd daemon does not change
   the children's cgroups which is executed by 'cgexec' command.

Changelog of v3:
================
 * Set a SETUID to "cgexec" command file.
 * An euid is changed to the executing user from a root user.

Changelog of v2:
================
 * New patch.

Description:
============
This patch applies a new rule to 'cgexec' command.

cgroup_register_unchanged_process() is called so that cgrulesengd
daemon does not change the cgroup of a process, which is executed
by 'cgexec' command.
And cgroup_change_cgroup_flags() is called for applying a new rule.

Thanks
Ken'ichi Ohmichi

Signed-off-by: Ken'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
doc/man/cgexec.1
src/tools/Makefile.am
src/tools/cgexec.c

index ca963f0e86e9016f92d7b652598a36602af1f639..2ab6fd68f6c538242707d05444cf5fea08cf1484 100644 (file)
@@ -7,7 +7,7 @@
 cgexec \- run the task in given control groups
 
 .SH SYNOPSIS
-\fBcgexec\fR [\fB-g\fR <\fIcontrollers>:<path\fR>] \fBcommand\fR [\fIarguments\fR]
+\fBcgexec\fR [\fB-g\fR <\fIcontrollers>:<path\fR>] [--sticky] \fBcommand\fR [\fIarguments\fR]
 
 .SH DESCRIPTION
 The \fBcgexec\fR
@@ -31,6 +31,15 @@ If this option is not used then
 \fBcgexec\fR will automatically place the task to the right
 cgroup based on \fB/etc/cgrules.conf\fR.
 
+.TP
+.B --sticky
+If running the task \fBcommand\fR with this option, the daemon of
+service cgred (cgrulesengd process) does not change both the task
+of the \fBcommand\fR and the children tasks. Without this option,
+the daemon does not change the task of the \fBcommand\fR but it
+changes the children tasks to the right cgroup based on
+\fB/etc/cgrules.conf\fR automatically.
+
 .LP
 
 .SH EXAMPLES
index f82916c63a8a7016152ccc59496ee8460364267f..19cc3392675b0e881ef488c90ab1ddc6685e0291 100644 (file)
@@ -17,4 +17,7 @@ cgconfigparser_SOURCES = cgconfig.c
 
 cgclear_SOURCES = cgclear.c
 
+install-exec-hook:
+       chmod u+s $(DESTDIR)$(bindir)/cgexec
+
 endif
index 085389416fc22566a6bc00b4eb55fe326c660ecb..a0368703b02ee0fd48708cdf8aaff2cb25ab3bc8 100644 (file)
 
 #include "tools-common.h"
 
+static struct option longopts[] = {
+       {"sticky", no_argument, NULL, 's'}, 
+       {0, 0, 0, 0}
+};
+
 int main(int argc, char *argv[])
 {
        int ret = 0, i;
        int cg_specified = 0;
-       uid_t euid;
+       int flag_child = 0;
+       uid_t uid;
+       gid_t gid;
        pid_t pid;
-       gid_t egid;
        char c;
        struct cgroup_group_spec *cgroup_list[CG_HIER_MAX];
 
        if (argc < 2) {
                fprintf(stderr, "Usage is %s"
                        " [-g <list of controllers>:<relative path to cgroup>]"
-                       " command [arguments]  \n",
+                       " [--sticky] command [arguments]  \n",
                        argv[0]);
                exit(2);
        }
 
        memset(cgroup_list, 0, sizeof(cgroup_list));
 
-       while ((c = getopt(argc, argv, "+g:")) > 0) {
+       while ((c = getopt_long(argc, argv, "+g:s", longopts, NULL)) > 0) {
                switch (c) {
                case 'g':
                        if (parse_cgroup_spec(cgroup_list, optarg)) {
@@ -60,6 +66,9 @@ int main(int argc, char *argv[])
                        }
                        cg_specified = 1;
                        break;
+               case 's':
+                       flag_child |= CGROUP_DAEMON_UNCHANGE_CHILDREN;
+                       break;
                default:
                        fprintf(stderr, "Invalid command line option\n");
                        exit(1);
@@ -81,10 +90,26 @@ int main(int argc, char *argv[])
                return ret;
        }
 
-       euid = geteuid();
-       egid = getegid();
+       uid = getuid();
+       gid = getgid();
        pid = getpid();
 
+       ret = cgroup_register_unchanged_process(pid, flag_child);
+       if (ret) {
+               fprintf(stderr, "registration of process failed\n");
+               return ret;
+       }
+
+       /*
+        * 'cgexec' command file needs the root privilege for executing
+        * a cgroup_register_unchanged_process() by using unix domain
+        * socket, and an euid should be changed to the executing user
+        * from a root user.
+        */
+       if (seteuid(uid)) {
+               fprintf(stderr, "%s", strerror(errno));
+               return -1;
+       }
        if (cg_specified) {
                /*
                 * User has specified the list of control group and
@@ -105,8 +130,9 @@ int main(int argc, char *argv[])
                }
        } else {
 
-               /* Change the cgroup by determining the rules based on euid */
-               ret = cgroup_change_cgroup_uid_gid(euid, egid, pid);
+               /* Change the cgroup by determining the rules based on uid */
+               ret = cgroup_change_cgroup_flags(uid, gid,
+                                                argv[optind], pid, 0);
                if (ret) {
                        fprintf(stderr, "cgroup change of group failed\n");
                        return ret;