From d297b6fc17d51b8c2f6cdc094ada378d49e9a583 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Fri, 26 Jun 2009 14:49:36 +0900 Subject: Add the parser of process name in /etc/cgrules.conf. 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. : Thanks Ken'ichi Ohmichi Signed-off-by: Ken'ichi Ohmichi Signed-off-by: Dhaval Giani --- include/libcgroup.h | 5 ----- src/api.c | 49 ++++++++++++++++++++++++++++++++++++++++++++---- src/daemon/cgrulesengd.h | 3 --- src/libcgroup-internal.h | 11 +++++++++++ 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/include/libcgroup.h b/include/libcgroup.h index 9bc74d6..6155f09 100644 --- a/include/libcgroup.h +++ b/include/libcgroup.h @@ -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) diff --git a/src/api.c b/src/api.c index 2d69162..c5a3579 100644 --- 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) { + /* : */ + 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"); diff --git a/src/daemon/cgrulesengd.h b/src/daemon/cgrulesengd.h index 506cb5d..ddb1af0 100644 --- a/src/daemon/cgrulesengd.h +++ b/src/daemon/cgrulesengd.h @@ -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)) diff --git a/src/libcgroup-internal.h b/src/libcgroup-internal.h index fac82a1..fa92048 100644 --- a/src/libcgroup-internal.h +++ b/src/libcgroup-internal.h @@ -30,12 +30,22 @@ __BEGIN_DECLS #define CGROUP_BUFFER_LEN (5 * FILENAME_MAX) +/* Maximum length of a key(:) 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]; -- cgit