From 9d3b7b6c8b8855e6bd63aecb9872ef7022394d4f Mon Sep 17 00:00:00 2001 From: Jan Safranek Date: Tue, 26 May 2009 15:08:59 +0200 Subject: 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. : Thanks Ken'ichi Ohmichi Signed-off-by: Ken'ichi Ohmichi --- 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 4da55e4..30c33bb 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(:) 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, ':')) { + /* : */ + 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]; -- cgit