summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKen'ichi Ohmichi <oomichi@mxs.nes.nec.co.jp>2009-06-26 14:49:36 +0900
committerDhaval Giani <dhaval@linux.vnet.ibm.com>2009-06-29 16:28:38 +0530
commitd297b6fc17d51b8c2f6cdc094ada378d49e9a583 (patch)
tree9ce840be0a666a8ad1f13756639c13c886306728
parent404007be1a80ab2ab75f64195fb692d520df0623 (diff)
downloadlibcg-d297b6fc17d51b8c2f6cdc094ada378d49e9a583.tar.gz
libcg-d297b6fc17d51b8c2f6cdc094ada378d49e9a583.tar.xz
libcg-d297b6fc17d51b8c2f6cdc094ada378d49e9a583.zip
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. <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>
-rw-r--r--include/libcgroup.h5
-rw-r--r--src/api.c49
-rw-r--r--src/daemon/cgrulesengd.h3
-rw-r--r--src/libcgroup-internal.h11
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) {
+ /* <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");
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(<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];