Adds support for cgroup subsystems to specify dependencies on other subsystems From: Ben Blum This patch adds a mechanism with which a subsystem can specify dependencies on other subsystems. Since subsystems can come and go, it would not be useful to refer to a depended-upon subsystem by subsys_id, so instead a NULL-terminated array of strings must be specified. Validation is done by scanning for each potential subsystem its list of subsystem names with strcmp at the end of parse_cgroupfs_options. Signed-off-by: Ben Blum --- Documentation/cgroups/cgroups.txt | 4 ++++ include/linux/cgroup.h | 8 ++++++++ kernel/cgroup.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 0 deletions(-) diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt index 110228e..a8de651 100644 --- a/Documentation/cgroups/cgroups.txt +++ b/Documentation/cgroups/cgroups.txt @@ -458,6 +458,10 @@ Other fields in the cgroup_subsys object include: - name: should be initialized to a unique subsystem name. Should be no longer than MAX_CGROUP_TYPE_NAMELEN. +- depends: allows subsystems to specify dependencies in the form of + a list (NULL-terminated) of names of other subsystems. A subsystem + cannot be mounted unless all of its dependencies are also mounted. + - early_init: indicate if the subsystem needs early initialization at system boot. diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 1cbb07f..6f77e30 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -457,6 +457,14 @@ struct cgroup_subsys { bool use_id; #define MAX_CGROUP_TYPE_NAMELEN 32 const char *name; + /* + * A subsystem can specify dependencies in the form of a list of names + * of other subsystems. Such a subsystem can only be mounted on a + * hierarchy if all subsystems named in this list are also to be + * mounted. If this list of strings is initialized, it must be null + * terminated. + */ + const char **depends; /* * Protects sibling/children links of cgroups in this diff --git a/kernel/cgroup.c b/kernel/cgroup.c index c2c7681..5bbc45a 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1015,6 +1015,38 @@ struct cgroup_sb_opts { }; /* + * Given a mask of subsystems to be mounted, ensure all dependencies are met. + */ +static bool check_subsys_dependencies(unsigned long subsys_bits) +{ + unsigned long i, j, k; + bool matched; + + for_each_bit(i, &subsys_bits, CGROUP_SUBSYS_COUNT) { + BUG_ON(!subsys[i]); + if (!subsys[i]->depends) + continue; + /* For each specified dependency, make sure there's a matching + * subsystem among the ones intended for mounting. */ + for (j = 0; subsys[i]->depends[j]; j++) { + matched = false; + for_each_bit(k, &subsys_bits, CGROUP_SUBSYS_COUNT) { + BUG_ON(!subsys[k]); + BUG_ON(!subsys[k]->name); + if (!strcmp(subsys[i]->depends[j], + subsys[k]->name)) { + matched = true; + break; + } + } + if (!matched) + return false; + } + } + return true; +} + +/* * Convert a hierarchy specifier into a bitmask of subsystems and flags. Call * with subsys_mutex held to guard subsys[] between us and rebind_subsystems. */ @@ -1123,6 +1155,10 @@ static int parse_cgroupfs_options(char *data, if (!opts->subsys_bits && !opts->name) return -EINVAL; + /* Check subsystem dependencies */ + if (opts->subsys_bits && !check_subsys_dependencies(opts->subsys_bits)) + return -ESRCH; + return 0; } -- 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/