aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorPaul Menage <menage@google.com>2008-04-29 04:00:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:08 -0400
commit9179656961adcea3c25403365597e486d851ac5e (patch)
tree13acbdd7ae045ed46fa679e613783717eb3b9138 /kernel/cgroup.c
parent700fe1ab99240c1a9c4d155e2a0612a1b044bb69 (diff)
CGroup API files: add cgroup map data type
Adds a new type of supported control file representation, a map from strings to u64 values. Each map entry is printed as a line in a similar format to /proc/vmstat, i.e. "$key $value\n" Signed-off-by: Paul Menage <menage@google.com> Cc: "Li Zefan" <lizf@cn.fujitsu.com> Cc: Balbir Singh <balbir@in.ibm.com> Cc: Paul Jackson <pj@sgi.com> Cc: Pavel Emelyanov <xemul@openvz.org> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: "YAMAMOTO Takashi" <yamamoto@valinux.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 57afdde871ac..693bcc03188b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1492,6 +1492,46 @@ static ssize_t cgroup_file_read(struct file *file, char __user *buf,
1492 return -EINVAL; 1492 return -EINVAL;
1493} 1493}
1494 1494
1495/*
1496 * seqfile ops/methods for returning structured data. Currently just
1497 * supports string->u64 maps, but can be extended in future.
1498 */
1499
1500struct cgroup_seqfile_state {
1501 struct cftype *cft;
1502 struct cgroup *cgroup;
1503};
1504
1505static int cgroup_map_add(struct cgroup_map_cb *cb, const char *key, u64 value)
1506{
1507 struct seq_file *sf = cb->state;
1508 return seq_printf(sf, "%s %llu\n", key, (unsigned long long)value);
1509}
1510
1511static int cgroup_seqfile_show(struct seq_file *m, void *arg)
1512{
1513 struct cgroup_seqfile_state *state = m->private;
1514 struct cftype *cft = state->cft;
1515 struct cgroup_map_cb cb = {
1516 .fill = cgroup_map_add,
1517 .state = m,
1518 };
1519 return cft->read_map(state->cgroup, cft, &cb);
1520}
1521
1522int cgroup_seqfile_release(struct inode *inode, struct file *file)
1523{
1524 struct seq_file *seq = file->private_data;
1525 kfree(seq->private);
1526 return single_release(inode, file);
1527}
1528
1529static struct file_operations cgroup_seqfile_operations = {
1530 .read = seq_read,
1531 .llseek = seq_lseek,
1532 .release = cgroup_seqfile_release,
1533};
1534
1495static int cgroup_file_open(struct inode *inode, struct file *file) 1535static int cgroup_file_open(struct inode *inode, struct file *file)
1496{ 1536{
1497 int err; 1537 int err;
@@ -1504,7 +1544,18 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
1504 cft = __d_cft(file->f_dentry); 1544 cft = __d_cft(file->f_dentry);
1505 if (!cft) 1545 if (!cft)
1506 return -ENODEV; 1546 return -ENODEV;
1507 if (cft->open) 1547 if (cft->read_map) {
1548 struct cgroup_seqfile_state *state =
1549 kzalloc(sizeof(*state), GFP_USER);
1550 if (!state)
1551 return -ENOMEM;
1552 state->cft = cft;
1553 state->cgroup = __d_cgrp(file->f_dentry->d_parent);
1554 file->f_op = &cgroup_seqfile_operations;
1555 err = single_open(file, cgroup_seqfile_show, state);
1556 if (err < 0)
1557 kfree(state);
1558 } else if (cft->open)
1508 err = cft->open(inode, file); 1559 err = cft->open(inode, file);
1509 else 1560 else
1510 err = 0; 1561 err = 0;