summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKen'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>2009-06-26 14:51:20 +0900
committerDhaval Giani <dhaval@linux.vnet.ibm.com>2009-06-29 16:51:11 +0530
commit581ce3c1ebbfdf0026de7bee75bd928be2a39982 (patch)
tree4d4b92749c1690ade4e2e9174998605f28867cff
parent1c29610af69bf3bb0e088ed3eca770589849b0da (diff)
downloadlibcg-581ce3c1ebbfdf0026de7bee75bd928be2a39982.tar.gz
libcg-581ce3c1ebbfdf0026de7bee75bd928be2a39982.tar.xz
libcg-581ce3c1ebbfdf0026de7bee75bd928be2a39982.zip
Apply a new rule to 'cgexec' command.
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>
-rw-r--r--doc/man/cgexec.111
-rw-r--r--src/tools/Makefile.am3
-rw-r--r--src/tools/cgexec.c42
3 files changed, 47 insertions, 9 deletions
diff --git a/doc/man/cgexec.1 b/doc/man/cgexec.1
index ca963f0..2ab6fd6 100644
--- a/doc/man/cgexec.1
+++ b/doc/man/cgexec.1
@@ -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
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index f82916c..19cc339 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -17,4 +17,7 @@ cgconfigparser_SOURCES = cgconfig.c
cgclear_SOURCES = cgclear.c
+install-exec-hook:
+ chmod u+s $(DESTDIR)$(bindir)/cgexec
+
endif
diff --git a/src/tools/cgexec.c b/src/tools/cgexec.c
index 0853894..a036870 100644
--- a/src/tools/cgexec.c
+++ b/src/tools/cgexec.c
@@ -30,27 +30,33 @@
#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;