From: Ken'ichi Ohmichi Date: Fri, 26 Jun 2009 05:51:20 +0000 (+0900) Subject: Apply a new rule to 'cgexec' command. X-Git-Tag: v0.34~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=581ce3c1ebbfdf0026de7bee75bd928be2a39982;p=thirdparty%2Flibcgroup.git 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 Signed-off-by: Dhaval Giani --- diff --git a/doc/man/cgexec.1 b/doc/man/cgexec.1 index ca963f0e..2ab6fd68 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>:] \fBcommand\fR [\fIarguments\fR] +\fBcgexec\fR [\fB-g\fR <\fIcontrollers>:] [--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 f82916c6..19cc3392 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 08538941..a0368703 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 :]" - " 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;