On Wed, Dec 15, 2010 at 4:34 PM, Michal Hrusecky <mic...@hrusecky.net> 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> > --- > 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 859190a..4212840 100644 > --- a/src/api.c > +++ b/src/api.c > @@ -2366,6 +2366,13 @@ 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 s, l;
minor nit. The names "a" and "l" don't tell me a lot. If it works fine (after some testing) I will probably rename these variables when I merge it. > + struct passwd *user_info; > + struct group *group_info; > + > /* Return codes */ > int ret = 0; > > @@ -2418,7 +2425,93 @@ 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 > */ > + s = 0; > + /* How many bytes can we write */ So, if the names were a bit more descriptive, we would have done without this comment ;-) > + l = FILENAME_MAX - j - 2; > + /* Substitution */ > + switch(tmp->destination[++i]) { > + case 'u': > + s = snprintf(newdest+j, l, > "%d", > + uid); > + break; > + case 'U': > + user_info = getpwuid(uid); > + if(user_info) { > + s = > snprintf(newdest+j, > + l, "%s", > + user_info -> > + pw_name); > + } else { > + s = > snprintf(newdest+j, > + l, "%d", uid); > + } > + break; > + case 'g': > + s = snprintf(newdest+j, l, > "%d", > + gid); > + break; > + case 'G': > + group_info = getgrgid(gid); > + if(group_info) { > + s = > snprintf(newdest+j, > + l, "%s", > + group_info -> > + gr_name); > + } else { > + s = > snprintf(newdest+j, > + l, "%d", gid); > + } > + break; > + case 'p': > + s = snprintf(newdest+j, l, > "%d", > + pid); > + break; > + case 'P': > + if(procname) { > + s = > snprintf(newdest+j, > + l, "%s", > + procname); > + } else { > + s = > snprintf(newdest+j, > + l, "%d", pid); > + } > + break; > + } > + /* > + * s<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(s<1) { > + newdest[j] = '%'; > + if(l>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 (that's the reason for -1) > + */ > + j += s - 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); > -- So, I am looking to merge this in a day or two, unless of course someone has things I did nt note (with of course those changes I mentioned.). Michal, if you resend the patch with those changes, you are more than welcome to add Acked-by: Dhaval Giani <dhaval.gi...@gmail.com> Thanks Dhaval ------------------------------------------------------------------------------ Lotusphere 2011 Register now for Lotusphere 2011 and learn how to connect the dots, take your collaborative environment to the next level, and enter the era of Social Business. http://p.sf.net/sfu/lotusphere-d2d _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel