lkml.org 
[lkml]   [2012]   [Aug]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v6 2/4] cgroup: revise how we re-populate root directory
    From: Li Zefan <lizefan@huawei.com>

    When remounting cgroupfs with some subsystems added to it and some
    removed, cgroup will remove all the files in root directory and then
    re-popluate it.

    What I'm doing here is, only remove files which belong to subsystems that
    are to be unbinded, and only create files for newly-added subsystems.
    The purpose is to have all other files untouched.

    This is a preparation for cgroup xattr support.

    v6:
    - no changes
    v5:
    - no changes
    v4:
    - refactored cgroup_clear_directory() to not use cgroup_rm_file()
    - instead of going thru the list of files, get the file list using the
    subsystems
    - use 'subsys_mask' instead of {added,removed}_bits and made
    cgroup_populate_dir() to match the parameters with cgroup_clear_directory()
    v3:
    - refresh patches after recent refactoring

    Cc: Li Zefan <lizefan@huawei.com>
    Cc: Tejun Heo <tj@kernel.org>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: Hillf Danton <dhillf@gmail.com>
    Cc: Lennart Poettering <lpoetter@redhat.com>
    Signed-off-by: Li Zefan <lizefan@huawei.com>
    Signed-off-by: Aristeu Rozanski <aris@redhat.com>

    ---
    kernel/cgroup.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------------
    1 file changed, 48 insertions(+), 13 deletions(-)

    Index: github/kernel/cgroup.c
    ===================================================================
    --- github.orig/kernel/cgroup.c 2012-08-16 11:28:12.683272452 -0400
    +++ github/kernel/cgroup.c 2012-08-16 11:28:42.592089681 -0400
    @@ -824,7 +824,8 @@
    static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode);
    static struct dentry *cgroup_lookup(struct inode *, struct dentry *, unsigned int);
    static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
    -static int cgroup_populate_dir(struct cgroup *cgrp);
    +static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files,
    + unsigned long subsys_mask);
    static const struct inode_operations cgroup_dir_inode_operations;
    static const struct file_operations proc_cgroupstats_operations;

    @@ -963,12 +964,29 @@
    return -ENOENT;
    }

    -static void cgroup_clear_directory(struct dentry *dir)
    +/**
    + * cgroup_clear_directory - selective removal of base and subsystem files
    + * @dir: directory containing the files
    + * @base_files: true if the base files should be removed
    + * @subsys_mask: mask of the subsystem ids whose files should be removed
    + */
    +static void cgroup_clear_directory(struct dentry *dir, bool base_files,
    + unsigned long subsys_mask)
    {
    struct cgroup *cgrp = __d_cgrp(dir);
    + struct cgroup_subsys *ss;

    - while (!list_empty(&cgrp->files))
    - cgroup_rm_file(cgrp, NULL);
    + for_each_subsys(cgrp->root, ss) {
    + struct cftype_set *set;
    + if (!test_bit(ss->subsys_id, &subsys_mask))
    + continue;
    + list_for_each_entry(set, &ss->cftsets, node)
    + cgroup_rm_file(cgrp, set->cfts);
    + }
    + if (base_files) {
    + while (!list_empty(&cgrp->files))
    + cgroup_rm_file(cgrp, NULL);
    + }
    }

    /*
    @@ -977,8 +995,9 @@
    static void cgroup_d_remove_dir(struct dentry *dentry)
    {
    struct dentry *parent;
    + struct cgroupfs_root *root = dentry->d_sb->s_fs_info;

    - cgroup_clear_directory(dentry);
    + cgroup_clear_directory(dentry, true, root->subsys_bits);

    parent = dentry->d_parent;
    spin_lock(&parent->d_lock);
    @@ -1339,6 +1358,7 @@
    struct cgroupfs_root *root = sb->s_fs_info;
    struct cgroup *cgrp = &root->top_cgroup;
    struct cgroup_sb_opts opts;
    + unsigned long added_bits, removed_bits;

    mutex_lock(&cgrp->dentry->d_inode->i_mutex);
    mutex_lock(&cgroup_mutex);
    @@ -1354,6 +1374,9 @@
    pr_warning("cgroup: option changes via remount are deprecated (pid=%d comm=%s)\n",
    task_tgid_nr(current), current->comm);

    + added_bits = opts.subsys_bits & ~root->subsys_bits;
    + removed_bits = root->subsys_bits & ~opts.subsys_bits;
    +
    /* Don't allow flags or name to change at remount */
    if (opts.flags != root->flags ||
    (opts.name && strcmp(opts.name, root->name))) {
    @@ -1369,8 +1392,9 @@
    }

    /* clear out any existing files and repopulate subsystem files */
    - cgroup_clear_directory(cgrp->dentry);
    - cgroup_populate_dir(cgrp);
    + cgroup_clear_directory(cgrp->dentry, false, removed_bits);
    + /* re-populate subsystem files */
    + cgroup_populate_dir(cgrp, false, added_bits);

    if (opts.release_agent)
    strcpy(root->release_agent_path, opts.release_agent);
    @@ -1669,7 +1693,7 @@
    BUG_ON(root->number_of_cgroups != 1);

    cred = override_creds(&init_cred);
    - cgroup_populate_dir(root_cgrp);
    + cgroup_populate_dir(root_cgrp, true, root->subsys_bits);
    revert_creds(cred);
    mutex_unlock(&cgroup_root_mutex);
    mutex_unlock(&cgroup_mutex);
    @@ -3843,18 +3867,29 @@
    { } /* terminate */
    };

    -static int cgroup_populate_dir(struct cgroup *cgrp)
    +/**
    + * cgroup_populate_dir - selectively creation of files in a directory
    + * @cgrp: target cgroup
    + * @base_files: true if the base files should be added
    + * @subsys_mask: mask of the subsystem ids whose files should be added
    + */
    +static int cgroup_populate_dir(struct cgroup *cgrp, bool base_files,
    + unsigned long subsys_mask)
    {
    int err;
    struct cgroup_subsys *ss;

    - err = cgroup_addrm_files(cgrp, NULL, files, true);
    - if (err < 0)
    - return err;
    + if (base_files) {
    + err = cgroup_addrm_files(cgrp, NULL, files, true);
    + if (err < 0)
    + return err;
    + }

    /* process cftsets of each subsystem */
    for_each_subsys(cgrp->root, ss) {
    struct cftype_set *set;
    + if (!test_bit(ss->subsys_id, &subsys_mask))
    + continue;

    list_for_each_entry(set, &ss->cftsets, node)
    cgroup_addrm_files(cgrp, ss, set->cfts, true);
    @@ -3988,7 +4023,7 @@

    list_add_tail(&cgrp->allcg_node, &root->allcg_list);

    - err = cgroup_populate_dir(cgrp);
    + err = cgroup_populate_dir(cgrp, true, root->subsys_bits);
    /* If err < 0, we have a half-filled directory - oh well ;) */

    mutex_unlock(&cgroup_mutex);


    \
     
     \ /
      Last update: 2012-08-16 22:01    [W:0.031 / U:120.396 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site