[PATCH 1/1] cgroups: introduce cft->read_seq() (v2) - Kernel

This is a discussion on [PATCH 1/1] cgroups: introduce cft->read_seq() (v2) - Kernel ; From 973226ae7b5f9343f50fc5fbf132175b6ec815cb Mon Sep 17 00:00:00 2001 From: Serge E. Hallyn Date: Thu, 3 Apr 2008 12:55:39 -0700 Subject: [PATCH 1/1] cgroups: introduce cft->read_seq() (v2) Introduce a read_seq() helper in cftype, which uses seq_file to print out lists. Use it ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: [PATCH 1/1] cgroups: introduce cft->read_seq() (v2)

  1. [PATCH 1/1] cgroups: introduce cft->read_seq() (v2)

    From 973226ae7b5f9343f50fc5fbf132175b6ec815cb Mon Sep 17 00:00:00 2001
    From: Serge E. Hallyn
    Date: Thu, 3 Apr 2008 12:55:39 -0700
    Subject: [PATCH 1/1] cgroups: introduce cft->read_seq() (v2)

    Introduce a read_seq() helper in cftype, which uses
    seq_file to print out lists. Use it in the devices
    cgroup. Also split devices.allow into two files, so
    now devices.deny and devices.allow are the ones to
    use to manipulate the whitelist, while devices.list
    outputs the cgroup's current whitelist.

    (Patch is against 2.6.25-rc8-mm1)

    Changelog:
    Apr 3: Incorporate Paul's comments. Call cft->read_seq()
    read_seq_string(), and integrate its use more closely
    with read_map().

    Signed-off-by: Serge E. Hallyn
    ---
    include/linux/cgroup.h | 6 ++++
    kernel/cgroup.c | 15 +++++----
    security/device_cgroup.c | 74 ++++++++++++++-------------------------------
    3 files changed, 38 insertions(+), 57 deletions(-)

    diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
    index 2d1d151..b39d964 100644
    --- a/include/linux/cgroup.h
    +++ b/include/linux/cgroup.h
    @@ -227,6 +227,12 @@ struct cftype {
    */
    int (*read_map) (struct cgroup *cont, struct cftype *cft,
    struct cgroup_map_cb *cb);
    + /*
    + * read_seq_string() is used for outputting a simple sequence
    + * using seqfile.
    + */
    + int (*read_seq_string) (struct cgroup *cont, struct cftype *cft,
    + struct seq_file *m);

    ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft,
    struct file *file,
    diff --git a/kernel/cgroup.c b/kernel/cgroup.c
    index 85f31ad..4abd845 100644
    --- a/kernel/cgroup.c
    +++ b/kernel/cgroup.c
    @@ -1522,11 +1522,14 @@ static int cgroup_seqfile_show(struct seq_file *m, void *arg)
    {
    struct cgroup_seqfile_state *state = m->private;
    struct cftype *cft = state->cft;
    - struct cgroup_map_cb cb = {
    - .fill = cgroup_map_add,
    - .state = m,
    - };
    - return cft->read_map(state->cgroup, cft, &cb);
    + if (cft->read_map) {
    + struct cgroup_map_cb cb = {
    + .fill = cgroup_map_add,
    + .state = m,
    + };
    + return cft->read_map(state->cgroup, cft, &cb);
    + }
    + return cft->read_seq_string(state->cgroup, cft, m);
    }

    int cgroup_seqfile_release(struct inode *inode, struct file *file)
    @@ -1554,7 +1557,7 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
    cft = __d_cft(file->f_dentry);
    if (!cft)
    return -ENODEV;
    - if (cft->read_map) {
    + if (cft->read_map || cft->read_seq_string) {
    struct cgroup_seqfile_state *state =
    kzalloc(sizeof(*state), GFP_USER);
    if (!state)
    diff --git a/security/device_cgroup.c b/security/device_cgroup.c
    index 4237b19..4ea5836 100644
    --- a/security/device_cgroup.c
    +++ b/security/device_cgroup.c
    @@ -9,6 +9,7 @@
    #include
    #include
    #include
    +#include

    #define ACC_MKNOD 1
    #define ACC_READ 2
    @@ -201,11 +202,15 @@ static void devcgroup_destroy(struct cgroup_subsys *ss,

    #define DEVCG_ALLOW 1
    #define DEVCG_DENY 2
    +#define DEVCG_LIST 3
    +
    +#define MAJMINLEN 10
    +#define ACCLEN 4

    static void set_access(char *acc, short access)
    {
    int idx = 0;
    - memset(acc, 0, 4);
    + memset(acc, 0, ACCLEN);
    if (access & ACC_READ)
    acc[idx++] = 'r';
    if (access & ACC_WRITE)
    @@ -225,70 +230,33 @@ static char type_to_char(short type)
    return 'X';
    }

    -static void set_majmin(char *str, int len, unsigned m)
    +static void set_majmin(char *str, unsigned m)
    {
    - memset(str, 0, len);
    + memset(str, 0, MAJMINLEN);
    if (m == ~0)
    sprintf(str, "*");
    else
    - snprintf(str, len, "%d", m);
    + snprintf(str, MAJMINLEN, "%d", m);
    }

    -static char *print_whitelist(struct dev_cgroup *devcgroup, int *len)
    +static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft,
    + struct seq_file *m)
    {
    - char *buf, *s, acc[4];
    + struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
    struct dev_whitelist_item *wh;
    - int ret;
    - int count = 0;
    - char maj[10], min[10];
    -
    - buf = kmalloc(4096, GFP_KERNEL);
    - if (!buf)
    - return ERR_PTR(-ENOMEM);
    - s = buf;
    - *s = '\0';
    - *len = 0;
    + char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];

    spin_lock(&devcgroup->lock);
    list_for_each_entry(wh, &devcgroup->whitelist, list) {
    set_access(acc, wh->access);
    - set_majmin(maj, 10, wh->major);
    - set_majmin(min, 10, wh->minor);
    - ret = snprintf(s, 4095-(s-buf), "%c %s:%s %s\n",
    - type_to_char(wh->type), maj, min, acc);
    - if (s+ret >= buf+4095) {
    - kfree(buf);
    - buf = ERR_PTR(-ENOMEM);
    - break;
    - }
    - s += ret;
    - *len += ret;
    - count++;
    + set_majmin(maj, wh->major);
    + set_majmin(min, wh->minor);
    + seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type),
    + maj, min, acc);
    }
    spin_unlock(&devcgroup->lock);

    - return buf;
    -}
    -
    -static ssize_t devcgroup_access_read(struct cgroup *cgroup,
    - struct cftype *cft, struct file *file,
    - char __user *userbuf, size_t nbytes, loff_t *ppos)
    -{
    - struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
    - int filetype = cft->private;
    - char *buffer;
    - int uninitialized_var(len);
    - int retval;
    -
    - if (filetype != DEVCG_ALLOW)
    - return -EINVAL;
    - buffer = print_whitelist(devcgroup, &len);
    - if (IS_ERR(buffer))
    - return PTR_ERR(buffer);
    -
    - retval = simple_read_from_buffer(userbuf, nbytes, ppos, buffer, len);
    - kfree(buffer);
    - return retval;
    + return 0;
    }

    /*
    @@ -501,7 +469,6 @@ out1:
    static struct cftype dev_cgroup_files[] = {
    {
    .name = "allow",
    - .read = devcgroup_access_read,
    .write = devcgroup_access_write,
    .private = DEVCG_ALLOW,
    },
    @@ -510,6 +477,11 @@ static struct cftype dev_cgroup_files[] = {
    .write = devcgroup_access_write,
    .private = DEVCG_DENY,
    },
    + {
    + .name = "list",
    + .read_seq_string = devcgroup_seq_read,
    + .private = DEVCG_LIST,
    + },
    };

    static int devcgroup_populate(struct cgroup_subsys *ss,
    --
    1.5.3.6

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH 1/1] cgroups: introduce cft->read_seq() (v2)

    On Thu, Apr 3, 2008 at 1:13 PM, Serge E. Hallyn wrote:
    > From 973226ae7b5f9343f50fc5fbf132175b6ec815cb Mon Sep 17 00:00:00 2001
    > From: Serge E. Hallyn
    > Date: Thu, 3 Apr 2008 12:55:39 -0700
    > Subject: [PATCH 1/1] cgroups: introduce cft->read_seq() (v2)
    >
    > Introduce a read_seq() helper in cftype, which uses
    > seq_file to print out lists. Use it in the devices
    > cgroup. Also split devices.allow into two files, so
    > now devices.deny and devices.allow are the ones to
    > use to manipulate the whitelist, while devices.list
    > outputs the cgroup's current whitelist.
    >
    > (Patch is against 2.6.25-rc8-mm1)
    >
    > Changelog:
    > Apr 3: Incorporate Paul's comments. Call cft->read_seq()
    > read_seq_string(), and integrate its use more closely
    > with read_map().
    >
    > Signed-off-by: Serge E. Hallyn


    Acked-by: Paul Menage

    Looks good. Thanks.

    > ---
    > include/linux/cgroup.h | 6 ++++
    > kernel/cgroup.c | 15 +++++----
    > security/device_cgroup.c | 74 ++++++++++++++-------------------------------
    > 3 files changed, 38 insertions(+), 57 deletions(-)
    >
    > diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
    > index 2d1d151..b39d964 100644
    > --- a/include/linux/cgroup.h
    > +++ b/include/linux/cgroup.h
    > @@ -227,6 +227,12 @@ struct cftype {
    > */
    > int (*read_map) (struct cgroup *cont, struct cftype *cft,
    > struct cgroup_map_cb *cb);
    > + /*
    > + * read_seq_string() is used for outputting a simple sequence
    > + * using seqfile.
    > + */
    > + int (*read_seq_string) (struct cgroup *cont, struct cftype *cft,
    > + struct seq_file *m);
    >
    > ssize_t (*write) (struct cgroup *cgrp, struct cftype *cft,
    > struct file *file,
    > diff --git a/kernel/cgroup.c b/kernel/cgroup.c
    > index 85f31ad..4abd845 100644
    > --- a/kernel/cgroup.c
    > +++ b/kernel/cgroup.c
    > @@ -1522,11 +1522,14 @@ static int cgroup_seqfile_show(struct seq_file *m, void *arg)
    > {
    > struct cgroup_seqfile_state *state = m->private;
    > struct cftype *cft = state->cft;
    > - struct cgroup_map_cb cb = {
    > - .fill = cgroup_map_add,
    > - .state = m,
    > - };
    > - return cft->read_map(state->cgroup, cft, &cb);
    > + if (cft->read_map) {
    > + struct cgroup_map_cb cb = {
    > + .fill = cgroup_map_add,
    > + .state = m,
    > + };
    > + return cft->read_map(state->cgroup, cft, &cb);
    > + }
    > + return cft->read_seq_string(state->cgroup, cft, m);
    > }
    >
    > int cgroup_seqfile_release(struct inode *inode, struct file *file)
    > @@ -1554,7 +1557,7 @@ static int cgroup_file_open(struct inode *inode, struct file *file)
    > cft = __d_cft(file->f_dentry);
    > if (!cft)
    > return -ENODEV;
    > - if (cft->read_map) {
    > + if (cft->read_map || cft->read_seq_string) {
    > struct cgroup_seqfile_state *state =
    > kzalloc(sizeof(*state), GFP_USER);
    > if (!state)
    > diff --git a/security/device_cgroup.c b/security/device_cgroup.c
    > index 4237b19..4ea5836 100644
    > --- a/security/device_cgroup.c
    > +++ b/security/device_cgroup.c
    > @@ -9,6 +9,7 @@
    > #include
    > #include
    > #include
    > +#include
    >
    > #define ACC_MKNOD 1
    > #define ACC_READ 2
    > @@ -201,11 +202,15 @@ static void devcgroup_destroy(struct cgroup_subsys *ss,
    >
    > #define DEVCG_ALLOW 1
    > #define DEVCG_DENY 2
    > +#define DEVCG_LIST 3
    > +
    > +#define MAJMINLEN 10
    > +#define ACCLEN 4
    >
    > static void set_access(char *acc, short access)
    > {
    > int idx = 0;
    > - memset(acc, 0, 4);
    > + memset(acc, 0, ACCLEN);
    > if (access & ACC_READ)
    > acc[idx++] = 'r';
    > if (access & ACC_WRITE)
    > @@ -225,70 +230,33 @@ static char type_to_char(short type)
    > return 'X';
    > }
    >
    > -static void set_majmin(char *str, int len, unsigned m)
    > +static void set_majmin(char *str, unsigned m)
    > {
    > - memset(str, 0, len);
    > + memset(str, 0, MAJMINLEN);
    > if (m == ~0)
    > sprintf(str, "*");
    > else
    > - snprintf(str, len, "%d", m);
    > + snprintf(str, MAJMINLEN, "%d", m);
    > }
    >
    > -static char *print_whitelist(struct dev_cgroup *devcgroup, int *len)
    > +static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft,
    > + struct seq_file *m)
    > {
    > - char *buf, *s, acc[4];
    > + struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
    > struct dev_whitelist_item *wh;
    > - int ret;
    > - int count = 0;
    > - char maj[10], min[10];
    > -
    > - buf = kmalloc(4096, GFP_KERNEL);
    > - if (!buf)
    > - return ERR_PTR(-ENOMEM);
    > - s = buf;
    > - *s = '\0';
    > - *len = 0;
    > + char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
    >
    > spin_lock(&devcgroup->lock);
    > list_for_each_entry(wh, &devcgroup->whitelist, list) {
    > set_access(acc, wh->access);
    > - set_majmin(maj, 10, wh->major);
    > - set_majmin(min, 10, wh->minor);
    > - ret = snprintf(s, 4095-(s-buf), "%c %s:%s %s\n",
    > - type_to_char(wh->type), maj, min, acc);
    > - if (s+ret >= buf+4095) {
    > - kfree(buf);
    > - buf = ERR_PTR(-ENOMEM);
    > - break;
    > - }
    > - s += ret;
    > - *len += ret;
    > - count++;
    > + set_majmin(maj, wh->major);
    > + set_majmin(min, wh->minor);
    > + seq_printf(m, "%c %s:%s %s\n", type_to_char(wh->type),
    > + maj, min, acc);
    > }
    > spin_unlock(&devcgroup->lock);
    >
    > - return buf;
    > -}
    > -
    > -static ssize_t devcgroup_access_read(struct cgroup *cgroup,
    > - struct cftype *cft, struct file *file,
    > - char __user *userbuf, size_t nbytes, loff_t *ppos)
    > -{
    > - struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup);
    > - int filetype = cft->private;
    > - char *buffer;
    > - int uninitialized_var(len);
    > - int retval;
    > -
    > - if (filetype != DEVCG_ALLOW)
    > - return -EINVAL;
    > - buffer = print_whitelist(devcgroup, &len);
    > - if (IS_ERR(buffer))
    > - return PTR_ERR(buffer);
    > -
    > - retval = simple_read_from_buffer(userbuf, nbytes, ppos, buffer, len);
    > - kfree(buffer);
    > - return retval;
    > + return 0;
    > }
    >
    > /*
    > @@ -501,7 +469,6 @@ out1:
    > static struct cftype dev_cgroup_files[] = {
    > {
    > .name = "allow",
    > - .read = devcgroup_access_read,
    > .write = devcgroup_access_write,
    > .private = DEVCG_ALLOW,
    > },
    > @@ -510,6 +477,11 @@ static struct cftype dev_cgroup_files[] = {
    > .write = devcgroup_access_write,
    > .private = DEVCG_DENY,
    > },
    > + {
    > + .name = "list",
    > + .read_seq_string = devcgroup_seq_read,
    > + .private = DEVCG_LIST,
    > + },
    > };
    >
    > static int devcgroup_populate(struct cgroup_subsys *ss,
    > --
    > 1.5.3.6
    >
    >

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread