On 12/22/2010 08:39 PM, Michal Hrusecky wrote: > Rules can be written using wildcards, but destinations had to be static. > This patch adds support for following strings in destination: > > %u - uid > %U - username, uid in case of error > %g - gid > %G - group name, gid in case of error > %p - pid > %P - proccess name, pid in case of error > > More general rules can be specified using wildcards. Example rule can be: > > *...@users * %G/%U > > This will put all users in their own cgroups named by their login and > group. > > Signed-off-by: Michal Hrusecky<mic...@hrusecky.net> > Acked-by: Dhaval Giani<dhaval.gi...@gmail.com>
I removed trailing spaces, merged and pushed the patch, thanks a lot! Jan > --- > doc/man/cgrules.conf.5 | 11 +++++- > src/api.c | 95 > +++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 104 insertions(+), 2 deletions(-) > > diff --git a/doc/man/cgrules.conf.5 b/doc/man/cgrules.conf.5 > index 4ca6937..9a8a0a3 100644 > --- a/doc/man/cgrules.conf.5 > +++ b/doc/man/cgrules.conf.5 > @@ -57,7 +57,16 @@ can be: > can be: > .nf > - path relative to the controller hierarchy (ex. pgrp1/gid1/uid1) > - > + - following strings will get expanded > + > + %u username, uid if name resolving fails > + %U uid > + %g group name, gid if name resolving fails > + %G gid > + %p process name, pid if name not available > + %P pid > + > + '\\' can be used to escape '%' > .fi > > First rule which matches the criteria will be executed. > diff --git a/src/api.c b/src/api.c > index fa4f02e..e6ca8db 100644 > --- a/src/api.c > +++ b/src/api.c > @@ -2393,6 +2393,14 @@ int cgroup_change_cgroup_flags(uid_t uid, gid_t gid, > /* Temporary pointer to a rule */ > struct cgroup_rule *tmp = NULL; > > + /* Temporary variables for destination substitution */ > + char newdest[FILENAME_MAX]; > + int i, j; > + int written; > + int available; > + struct passwd *user_info; > + struct group *group_info; > + > /* Return codes */ > int ret = 0; > > @@ -2445,7 +2453,92 @@ int cgroup_change_cgroup_flags(uid_t uid, gid_t gid, > do { > cgroup_dbg("Executing rule %s for PID %d... ", tmp->username, > pid); > - ret = cgroup_change_cgroup_path(tmp->destination, > + /* Destination substitutions */ > + for(j = i = 0; i< strlen(tmp->destination)&& > + (j< FILENAME_MAX - 2); ++i, ++j) { > + if(tmp->destination[i] == '%') { > + /* How many bytes did we write / error check */ > + written = 0; > + /* How many bytes can we write */ > + available = FILENAME_MAX - j - 2; > + /* Substitution */ > + switch(tmp->destination[++i]) { > + case 'u': > + written = snprintf(newdest+j, available, > + "%d", uid); > + break; > + case 'U': > + user_info = getpwuid(uid); > + if(user_info) { > + written = snprintf(newdest + j, > + available, "%s", > + user_info -> pw_name); > + } else { > + written = snprintf(newdest + j, > + available, "%d", uid); > + } > + break; > + case 'g': > + written = snprintf(newdest + j, > + available, "%d", gid); > + break; > + case 'G': > + group_info = getgrgid(gid); > + if(group_info) { > + written = snprintf(newdest + j, > + available, "%s", > + group_info -> gr_name); > + } else { > + written = snprintf(newdest + j, > + available, "%d", gid); > + } > + break; > + case 'p': > + written = snprintf(newdest + j, > + available, "%d", pid); > + break; > + case 'P': > + if(procname) { > + written = snprintf(newdest + j, > + available, "%s", > + procname); > + } else { > + written = snprintf(newdest + j, > + available, "%d", pid); > + } > + break; > + } > + written = min(written, available); > + /* > + * written<1 only when either error occurred > + * during snprintf or if no substitution was > + * made at all. In both cases, we want to just > + * copy input string. > + */ > + if(written<1) { > + newdest[j] = '%'; > + if(available>1) > + newdest[++j] = > + tmp->destination[i]; > + } else { > + /* > + * In next iteration, we will write > + * just after the substitution, but j > + * will get incremented in the > + * meantime. > + */ > + j += written - 1; > + } > + } else { > + if(tmp->destination[i] == '\\') > + ++i; > + newdest[j] = tmp->destination[i]; > + } > + } > + newdest[j] = 0; > + > + /* Apply the rule */ > + ret = cgroup_change_cgroup_path(newdest, > pid, (const char * const *)tmp->controllers); > if (ret) { > cgroup_dbg("FAILED! (Error Code: %d)\n", ret); ------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel