diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/api.c | 43 | ||||
-rw-r--r-- | src/libcgroup-internal.h | 1 |
2 files changed, 40 insertions, 4 deletions
@@ -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]; |