]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
Add the parser of process name in /etc/cgrules.conf.
authorKen'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>
Fri, 26 Jun 2009 05:49:36 +0000 (14:49 +0900)
committerDhaval Giani <dhaval@linux.vnet.ibm.com>
Mon, 29 Jun 2009 10:58:38 +0000 (16:28 +0530)
Hi,

Changelog of v6:
================
 * The definations of CGROUP_RULE_MAXKEY and CGROUP_RULE_MAXLINE are
   moved to libcgroup-internal.h since no one from outside should be
   using them.

Changelog of v5:
================
 * Rebase the patch to the latest code.

Changelog of v4:
================
 * Use more safety length of a user name for the buffer "username".
 * Move the macros min()/max() to src/libcgroup-internal.h for using
   in src/api.c also.

Changelog of v3:
================
 * Fix unclear buffer of user by memset().

Changelog of v2:
================
 * Remove unnecessary memset().
 * Some cleanups.

Description:
============
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 <oomichi@mxs.nes.nec.co.jp>
Signed-off-by: Dhaval Giani <dhaval@linux.vnet.ibm.com>
include/libcgroup.h
src/api.c
src/daemon/cgrulesengd.h
src/libcgroup-internal.h

index 9bc74d64ca0f0d32a7878f3fadb0f7a60b014a1d..6155f09b2ff47647b10d1ce26b2d6c3891308150 100644 (file)
@@ -48,11 +48,6 @@ __BEGIN_DECLS
  * would require us to use a scanner/parser that can parse beyond ASCII
  */
 
-
-/* Maximum length of a line in the daemon config file */
-#define CGROUP_RULE_MAXLINE (FILENAME_MAX + LOGIN_NAME_MAX + \
-       CG_CONTROLLER_MAX + 3)
-
 /* Definitions for the uid and gid members of a cgroup_rules */
 #define CGRULE_INVALID (-1)
 #define CGRULE_WILD (-2)
index 2d691625a13231afb7cfb81b81388843603c1af0..c5a3579412c295f7ad1eebde86453eb94aacff1d 100644 (file)
--- a/src/api.c
+++ b/src/api.c
@@ -209,7 +209,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])
@@ -302,6 +305,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;
 
@@ -315,11 +321,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;
@@ -385,12 +394,30 @@ static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid)
                 * there's an error in the configuration file.
                 */
                skipped = false;
-               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;
                }
+               procname = strchr(key, ':');
+               if (procname) {
+                       /* <user>:<procname>  <subsystem>  <destination> */
+                       procname++;     /* skip ':' */
+                       len_username = procname - key - 1;
+                       len_procname = strlen(procname);
+                       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;
+               }
+               len_username = min(len_username, sizeof(user) - 1);
+               memset(user, '\0', sizeof(user));
+               strncpy(user, key, len_username);
 
                /*
                 * Next, check the user/group.  If it's a % sign, then we
@@ -478,7 +505,18 @@ static int cgroup_parse_rules(bool cache, uid_t muid, gid_t mgid)
 
                newrule->uid = uid;
                newrule->gid = gid;
-               strncpy(newrule->username, user, sizeof(newrule->username) - 1);
+               len_username = min(len_username, sizeof(newrule->username) - 1);
+               strncpy(newrule->username, user, len_username);
+               if (len_procname) {
+                       newrule->procname = strdup(procname);
+                       if (!newrule->procname) {
+                               last_errno = errno;
+                               ret = ECGOTHER;
+                               goto close;
+                       }
+               } else {
+                       newrule->procname = NULL;
+               }
                strncpy(newrule->destination, destination,
                        sizeof(newrule->destination) - 1);
                newrule->next = NULL;
@@ -2025,7 +2063,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");
index 506cb5d346d789748c7c74c6c288d073510b2d26..ddb1af0ce7672fe5d0c48bfd31deee8625107611 100644 (file)
@@ -40,9 +40,6 @@ __BEGIN_DECLS
 #define SEND_MESSAGE_SIZE (NLMSG_SPACE(SEND_MESSAGE_LEN))
 #define RECV_MESSAGE_SIZE (NLMSG_SPACE(RECV_MESSAGE_LEN))
 
-#define max(x,y) ((y)<(x)?(x):(y))
-#define min(x,y) ((y)>(x)?(x):(y))
-
 #define BUFF_SIZE (max(max(SEND_MESSAGE_SIZE, RECV_MESSAGE_SIZE), 1024))
 #define MIN_RECV_SIZE (min(SEND_MESSAGE_SIZE, RECV_MESSAGE_SIZE))
 
index fac82a11db57f12ba9149b5f9fc8c83d5252c647..fa92048666bed975f7e3f9fbcae0e25024e548e5 100644 (file)
@@ -30,12 +30,22 @@ __BEGIN_DECLS
 
 #define CGROUP_BUFFER_LEN (5 * FILENAME_MAX)
 
+/* Maximum length of a key(<user>:<process name>) in the daemon config file */
+#define CGROUP_RULE_MAXKEY     (LOGIN_NAME_MAX + FILENAME_MAX + 1)
+
+/* Maximum length of a line in the daemon config file */
+#define CGROUP_RULE_MAXLINE    (FILENAME_MAX + CGROUP_RULE_MAXKEY + \
+       CG_CONTROLLER_MAX + 3)
+
 #ifdef CGROUP_DEBUG
 #define cgroup_dbg(x...) printf(x)
 #else
 #define cgroup_dbg(x...) do {} while (0)
 #endif
 
+#define max(x,y) ((y)<(x)?(x):(y))
+#define min(x,y) ((y)>(x)?(x):(y))
+
 struct control_value {
        char name[FILENAME_MAX];
        char value[CG_VALUE_MAX];
@@ -77,6 +87,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];