Re: [PATCH v2 2/4] device_cgroup: keep track of local group settings

2013-01-24 Thread Tejun Heo
On Thu, Jan 24, 2013 at 02:49:59PM -0500, a...@redhat.com wrote:
> In preparation for better hierarchy support, it's needed to retain the local
> settings in order to try to reapply them after a propagated change if they're
> still valid.
> 
> Cc: Tejun Heo 
> Cc: Serge Hallyn 
> Signed-off-by: Aristeu Rozanski 

Looks okay to me but it would be better if you separate out moving
dev_exception_rm() above dev_exception_add() into a separate patch.
It currently mixes functional and non-functional changes which isn't
very nice.

Thanks.

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


[PATCH v2 2/4] device_cgroup: keep track of local group settings

2013-01-24 Thread aris
In preparation for better hierarchy support, it's needed to retain the local
settings in order to try to reapply them after a propagated change if they're
still valid.

Cc: Tejun Heo 
Cc: Serge Hallyn 
Signed-off-by: Aristeu Rozanski 
 
---
 security/device_cgroup.c |  115 +--
 1 file changed, 83 insertions(+), 32 deletions(-)

--- github.orig/security/device_cgroup.c2013-01-24 10:40:33.913068234 
-0500
+++ github/security/device_cgroup.c 2013-01-24 10:40:46.384253615 -0500
@@ -39,13 +39,27 @@ struct dev_exception_item {
struct rcu_head rcu;
 };
 
+enum devcg_behavior {
+   DEVCG_DEFAULT_NONE,
+   DEVCG_DEFAULT_ALLOW,
+   DEVCG_DEFAULT_DENY,
+};
+
 struct dev_cgroup {
struct cgroup_subsys_state css;
+
+   /* result of merging the parent's rules with local ones */
struct list_head exceptions;
-   enum {
-   DEVCG_DEFAULT_ALLOW,
-   DEVCG_DEFAULT_DENY,
-   } behavior;
+   enum devcg_behavior behavior;
+
+   /*
+* local set rules, saved so when a parent propagates new rules, the
+* local preferences can be preserved
+*/
+   struct {
+   struct list_head exceptions;
+   enum devcg_behavior behavior;
+   } local;
 };
 
 static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state 
*s)
@@ -104,8 +118,41 @@ free_and_exit:
 /*
  * called under devcgroup_mutex
  */
-static int dev_exception_add(struct list_head *exceptions,
-struct dev_exception_item *ex)
+static void __dev_exception_rm(struct list_head *exceptions,
+  struct dev_exception_item *ex)
+{
+   struct dev_exception_item *walk, *tmp;
+
+   lockdep_assert_held(_mutex);
+
+   list_for_each_entry_safe(walk, tmp, exceptions, list) {
+   if (walk->type != ex->type)
+   continue;
+   if (walk->major != ex->major)
+   continue;
+   if (walk->minor != ex->minor)
+   continue;
+
+   walk->access &= ~ex->access;
+   if (!walk->access) {
+   list_del_rcu(>list);
+   kfree_rcu(walk, rcu);
+   }
+   }
+}
+
+static void dev_exception_rm(struct dev_cgroup *devcgroup,
+   struct dev_exception_item *ex)
+{
+   __dev_exception_rm(>local.exceptions, ex);
+   __dev_exception_rm(>exceptions, ex);
+}
+
+/*
+ * called under devcgroup_mutex
+ */
+static int __dev_exception_add(struct list_head *exceptions,
+  struct dev_exception_item *ex)
 {
struct dev_exception_item *excopy, *walk;
 
@@ -133,30 +180,26 @@ static int dev_exception_add(struct list
return 0;
 }
 
-/*
- * called under devcgroup_mutex
- */
-static void dev_exception_rm(struct list_head *exceptions,
+static int dev_exception_add(struct dev_cgroup *devcgroup,
 struct dev_exception_item *ex)
 {
-   struct dev_exception_item *walk, *tmp;
+   int rc;
 
lockdep_assert_held(_mutex);
 
-   list_for_each_entry_safe(walk, tmp, exceptions, list) {
-   if (walk->type != ex->type)
-   continue;
-   if (walk->major != ex->major)
-   continue;
-   if (walk->minor != ex->minor)
-   continue;
+   /*
+* we add to the local list so we can preserve local preferences if
+* the parent propagates down new rules
+*/
+   rc = __dev_exception_add(>local.exceptions, ex);
+   if (rc)
+   return rc;
+
+   rc = __dev_exception_add(>exceptions, ex);
+   if (rc)
+   __dev_exception_rm(>local.exceptions, ex);
 
-   walk->access &= ~ex->access;
-   if (!walk->access) {
-   list_del_rcu(>list);
-   kfree_rcu(walk, rcu);
-   }
-   }
+   return rc;
 }
 
 static void __dev_exception_clean(struct dev_cgroup *dev_cgroup)
@@ -167,6 +210,11 @@ static void __dev_exception_clean(struct
list_del_rcu(>list);
kfree_rcu(ex, rcu);
}
+   list_for_each_entry_safe(ex, tmp, _cgroup->local.exceptions,
+list) {
+   list_del_rcu(>list);
+   kfree_rcu(ex, rcu);
+   }
 }
 
 /**
@@ -195,6 +243,8 @@ static struct cgroup_subsys_state *devcg
if (!dev_cgroup)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(_cgroup->exceptions);
+   INIT_LIST_HEAD(_cgroup->local.exceptions);
+   dev_cgroup->local.behavior = DEVCG_DEFAULT_NONE;
parent_cgroup = cgroup->parent;
 
if (parent_cgroup == NULL)
@@ -413,18 +463,19 @@   memset(, 0, sizeof(ex));
if (!may_allow_all(parent))

[PATCH v2 2/4] device_cgroup: keep track of local group settings

2013-01-24 Thread aris
In preparation for better hierarchy support, it's needed to retain the local
settings in order to try to reapply them after a propagated change if they're
still valid.

Cc: Tejun Heo t...@kernel.org
Cc: Serge Hallyn serge.hal...@canonical.com
Signed-off-by: Aristeu Rozanski a...@redhat.com
 
---
 security/device_cgroup.c |  115 +--
 1 file changed, 83 insertions(+), 32 deletions(-)

--- github.orig/security/device_cgroup.c2013-01-24 10:40:33.913068234 
-0500
+++ github/security/device_cgroup.c 2013-01-24 10:40:46.384253615 -0500
@@ -39,13 +39,27 @@ struct dev_exception_item {
struct rcu_head rcu;
 };
 
+enum devcg_behavior {
+   DEVCG_DEFAULT_NONE,
+   DEVCG_DEFAULT_ALLOW,
+   DEVCG_DEFAULT_DENY,
+};
+
 struct dev_cgroup {
struct cgroup_subsys_state css;
+
+   /* result of merging the parent's rules with local ones */
struct list_head exceptions;
-   enum {
-   DEVCG_DEFAULT_ALLOW,
-   DEVCG_DEFAULT_DENY,
-   } behavior;
+   enum devcg_behavior behavior;
+
+   /*
+* local set rules, saved so when a parent propagates new rules, the
+* local preferences can be preserved
+*/
+   struct {
+   struct list_head exceptions;
+   enum devcg_behavior behavior;
+   } local;
 };
 
 static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state 
*s)
@@ -104,8 +118,41 @@ free_and_exit:
 /*
  * called under devcgroup_mutex
  */
-static int dev_exception_add(struct list_head *exceptions,
-struct dev_exception_item *ex)
+static void __dev_exception_rm(struct list_head *exceptions,
+  struct dev_exception_item *ex)
+{
+   struct dev_exception_item *walk, *tmp;
+
+   lockdep_assert_held(devcgroup_mutex);
+
+   list_for_each_entry_safe(walk, tmp, exceptions, list) {
+   if (walk-type != ex-type)
+   continue;
+   if (walk-major != ex-major)
+   continue;
+   if (walk-minor != ex-minor)
+   continue;
+
+   walk-access = ~ex-access;
+   if (!walk-access) {
+   list_del_rcu(walk-list);
+   kfree_rcu(walk, rcu);
+   }
+   }
+}
+
+static void dev_exception_rm(struct dev_cgroup *devcgroup,
+   struct dev_exception_item *ex)
+{
+   __dev_exception_rm(devcgroup-local.exceptions, ex);
+   __dev_exception_rm(devcgroup-exceptions, ex);
+}
+
+/*
+ * called under devcgroup_mutex
+ */
+static int __dev_exception_add(struct list_head *exceptions,
+  struct dev_exception_item *ex)
 {
struct dev_exception_item *excopy, *walk;
 
@@ -133,30 +180,26 @@ static int dev_exception_add(struct list
return 0;
 }
 
-/*
- * called under devcgroup_mutex
- */
-static void dev_exception_rm(struct list_head *exceptions,
+static int dev_exception_add(struct dev_cgroup *devcgroup,
 struct dev_exception_item *ex)
 {
-   struct dev_exception_item *walk, *tmp;
+   int rc;
 
lockdep_assert_held(devcgroup_mutex);
 
-   list_for_each_entry_safe(walk, tmp, exceptions, list) {
-   if (walk-type != ex-type)
-   continue;
-   if (walk-major != ex-major)
-   continue;
-   if (walk-minor != ex-minor)
-   continue;
+   /*
+* we add to the local list so we can preserve local preferences if
+* the parent propagates down new rules
+*/
+   rc = __dev_exception_add(devcgroup-local.exceptions, ex);
+   if (rc)
+   return rc;
+
+   rc = __dev_exception_add(devcgroup-exceptions, ex);
+   if (rc)
+   __dev_exception_rm(devcgroup-local.exceptions, ex);
 
-   walk-access = ~ex-access;
-   if (!walk-access) {
-   list_del_rcu(walk-list);
-   kfree_rcu(walk, rcu);
-   }
-   }
+   return rc;
 }
 
 static void __dev_exception_clean(struct dev_cgroup *dev_cgroup)
@@ -167,6 +210,11 @@ static void __dev_exception_clean(struct
list_del_rcu(ex-list);
kfree_rcu(ex, rcu);
}
+   list_for_each_entry_safe(ex, tmp, dev_cgroup-local.exceptions,
+list) {
+   list_del_rcu(ex-list);
+   kfree_rcu(ex, rcu);
+   }
 }
 
 /**
@@ -195,6 +243,8 @@ static struct cgroup_subsys_state *devcg
if (!dev_cgroup)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(dev_cgroup-exceptions);
+   INIT_LIST_HEAD(dev_cgroup-local.exceptions);
+   dev_cgroup-local.behavior = DEVCG_DEFAULT_NONE;
parent_cgroup = cgroup-parent;
 
if (parent_cgroup == NULL)
@@ -413,18 +463,19 

Re: [PATCH v2 2/4] device_cgroup: keep track of local group settings

2013-01-24 Thread Tejun Heo
On Thu, Jan 24, 2013 at 02:49:59PM -0500, a...@redhat.com wrote:
 In preparation for better hierarchy support, it's needed to retain the local
 settings in order to try to reapply them after a propagated change if they're
 still valid.
 
 Cc: Tejun Heo t...@kernel.org
 Cc: Serge Hallyn serge.hal...@canonical.com
 Signed-off-by: Aristeu Rozanski a...@redhat.com

Looks okay to me but it would be better if you separate out moving
dev_exception_rm() above dev_exception_add() into a separate patch.
It currently mixes functional and non-functional changes which isn't
very nice.

Thanks.

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