Hi,

This patch adds the parser of process name in /etc/cgrules.conf.

A new rule based on process name is as the following, and the process
name is stored into the member "procname" in struct cgroup_rule.
  <user>:<process name>  <controllers>   <destination>


Thanks
Ken'ichi Ohmichi
 
Signed-off-by: Ken'ichi Ohmichi <[email protected]>
---
 include/libcgroup.h      |    7 ++++++-
 src/api.c                |   43 +++++++++++++++++++++++++++++++++++++++----
 src/libcgroup-internal.h |    1 +
 3 files changed, 46 insertions(+), 5 deletions(-)

diff --git a/include/libcgroup.h b/include/libcgroup.h
index 7db02d4..10b41aa 100644
--- a/include/libcgroup.h
+++ b/include/libcgroup.h
@@ -48,9 +48,14 @@ __BEGIN_DECLS
  * would require us to use a scanner/parser that can parse beyond ASCII
  */
 
+/* Task command name length (from linux-2.6.29) */
+#define TASK_COMM_LEN          16
+
+/* Maximum length of a key(<user>:<process name>) in the daemon config file */
+#define CGROUP_RULE_MAXKEY     (LOGIN_NAME_MAX + TASK_COMM_LEN + 1)
 
 /* Maximum length of a line in the daemon config file */
-#define CGROUP_RULE_MAXLINE (FILENAME_MAX + LOGIN_NAME_MAX + \
+#define CGROUP_RULE_MAXLINE    (FILENAME_MAX + CGROUP_RULE_MAXKEY + \
        CG_CONTROLLER_MAX + 3)
 
 /* Definitions for the uid and gid members of a cgroup_rules */
diff --git a/src/api.c b/src/api.c
index 0739642..3e063cb 100644
--- a/src/api.c
+++ b/src/api.c
@@ -206,7 +206,10 @@ static void cgroup_free_rule(struct cgroup_rule *r)
                cgroup_dbg("Warning: Attempted to free NULL rule.\n");
                return;
        }
-
+       if (r->procname) {
+               free(r->procname);
+               r->procname = NULL;
+       }
        /* We must free any used controller strings, too. */
        for(i = 0; i < MAX_MNT_ELEMENTS; i++) {
                if (r->controllers[i])
@@ -297,6 +300,9 @@ static int cgroup_parse_rules(bool cache, uid_t muid, gid_t 
mgid)
        /* Iterator for the line we're working on */
        char *itr = NULL;
 
+       /* Pointer to process name in a line of the configuration file */
+       char *procname = NULL;
+
        /* Pointer to the list that we're using */
        struct cgroup_rule_list *lst = NULL;
 
@@ -310,11 +316,14 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
gid_t mgid)
        struct passwd *pwd = NULL;
 
        /* Temporary storage for a configuration rule */
+       char key[CGROUP_RULE_MAXKEY] = { '\0' };
        char user[LOGIN_NAME_MAX] = { '\0' };
        char controllers[CG_CONTROLLER_MAX] = { '\0' };
        char destination[FILENAME_MAX] = { '\0' };
        uid_t uid = CGRULE_INVALID;
        gid_t gid = CGRULE_INVALID;
+       int len_username;
+       int len_procname;
 
        /* The current line number */
        unsigned int linenum = 0;
@@ -381,16 +390,33 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
gid_t mgid)
                 * there's an error in the configuration file.
                 */
                skipped = false;
+               memset(key, '\0', sizeof(key));
                memset(user, '\0', sizeof(user));
                memset(controllers, '\0', sizeof(controllers));
                memset(destination, '\0', sizeof(destination));
-               i = sscanf(itr, "%s%s%s", user, controllers, destination);
+               i = sscanf(itr, "%s%s%s", key, controllers, destination);
                if (i != 3) {
                        cgroup_dbg("Failed to parse configuration file on"
                                        " line %d.\n", linenum);
                        goto parsefail;
                }
 
+               if (strchr(key, ':')) {
+                       /* <user>:<procname>    <subsystem>     <destination> */
+                       procname = strchr(key, ':') + 1;
+                       len_username = procname - key - 1;
+                       len_procname = strlen(key) - len_username - 1;
+                       if (len_procname < 0) {
+                               cgroup_dbg("Failed to parse configuration file 
on"
+                                               " line %d.\n", linenum);
+                               goto parsefail;
+                       }
+               } else {
+                       len_username = strlen(key);
+                       len_procname = 0;
+               }
+               strncpy(user, key, len_username);
+
                /*
                 * Next, check the user/group.  If it's a % sign, then we
                 * are continuing another rule and UID/GID should not be
@@ -479,7 +505,13 @@ static int cgroup_parse_rules(bool cache, uid_t muid, 
gid_t mgid)
 
                newrule->uid = uid;
                newrule->gid = gid;
-               strncpy(newrule->username, user, strlen(user));
+               strncpy(newrule->username, user, len_username);
+               if (len_procname) {
+                       newrule->procname = calloc(1, len_procname + 1);
+                       strncpy(newrule->procname, procname, len_procname);
+               } else {
+                       newrule->procname = NULL;
+               }
                strncpy(newrule->destination, destination, strlen(destination));
                newrule->next = NULL;
 
@@ -2008,7 +2040,10 @@ void cgroup_print_rules_config(FILE *fp)
 
        itr = rl.head;
        while (itr) {
-               fprintf(fp, "Rule: %s\n", itr->username);
+               fprintf(fp, "Rule: %s", itr->username);
+               if (itr->procname)
+                       fprintf(fp, ":%s", itr->procname);
+               fprintf(fp, "\n");
 
                if (itr->uid == CGRULE_WILD)
                        fprintf(fp, "  UID: any\n");
diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h
index 9e69f10..6f314b6 100644
--- a/src/libcgroup-internal.h
+++ b/src/libcgroup-internal.h
@@ -74,6 +74,7 @@ struct cgroup_rules_data {
 struct cgroup_rule {
        uid_t uid;
        gid_t gid;
+       char *procname;
        char username[LOGIN_NAME_MAX];
        char destination[FILENAME_MAX];
        char *controllers[MAX_MNT_ELEMENTS];

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT
is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & 
iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian
Group, R/GA, & Big Spaceship. http://www.creativitycat.com 
_______________________________________________
Libcg-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to