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

Reply via email to