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

Reply via email to