public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@suse.de>
To: linux-kernel@vger.kernel.org
Cc: "Eric W. Biederman" <ebiederm@xmission.com>,
	Greg Kroah-Hartman <gregkh@suse.de>
Subject: [PATCH 20/38] kobj: Add basic infrastructure for dealing with namespaces.
Date: Fri, 21 May 2010 09:53:50 -0700	[thread overview]
Message-ID: <1274460848-11377-20-git-send-email-gregkh@suse.de> (raw)
In-Reply-To: <20100521165106.GA11216@kroah.com>

From: Eric W. Biederman <ebiederm@xmission.com>

Move complete knowledge of namespaces into the kobject layer
so we can use that information when reporting kobjects to
userspace.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 drivers/base/class.c    |    9 ++++
 drivers/base/core.c     |   77 ++++++++++++++++++++++++++++------
 include/linux/device.h  |    3 +
 include/linux/kobject.h |   26 ++++++++++++
 lib/kobject.c           |  103 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 204 insertions(+), 14 deletions(-)

diff --git a/drivers/base/class.c b/drivers/base/class.c
index 9c6a0d6..8e231d0 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -63,6 +63,14 @@ static void class_release(struct kobject *kobj)
 	kfree(cp);
 }
 
+static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj)
+{
+	struct class_private *cp = to_class(kobj);
+	struct class *class = cp->class;
+
+	return class->ns_type;
+}
+
 static const struct sysfs_ops class_sysfs_ops = {
 	.show	= class_attr_show,
 	.store	= class_attr_store,
@@ -71,6 +79,7 @@ static const struct sysfs_ops class_sysfs_ops = {
 static struct kobj_type class_ktype = {
 	.sysfs_ops	= &class_sysfs_ops,
 	.release	= class_release,
+	.child_ns_type	= class_child_ns_type,
 };
 
 /* Hotplug events for classes go to the class class_subsys */
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 356dd01..f069991 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -131,9 +131,21 @@ static void device_release(struct kobject *kobj)
 	kfree(p);
 }
 
+static const void *device_namespace(struct kobject *kobj)
+{
+	struct device *dev = to_dev(kobj);
+	const void *ns = NULL;
+
+	if (dev->class && dev->class->ns_type)
+		ns = dev->class->namespace(dev);
+
+	return ns;
+}
+
 static struct kobj_type device_ktype = {
 	.release	= device_release,
 	.sysfs_ops	= &dev_sysfs_ops,
+	.namespace	= device_namespace,
 };
 
 
@@ -595,11 +607,59 @@ static struct kobject *virtual_device_parent(struct device *dev)
 	return virtual_dir;
 }
 
-static struct kobject *get_device_parent(struct device *dev,
-					 struct device *parent)
+struct class_dir {
+	struct kobject kobj;
+	struct class *class;
+};
+
+#define to_class_dir(obj) container_of(obj, struct class_dir, kobj)
+
+static void class_dir_release(struct kobject *kobj)
+{
+	struct class_dir *dir = to_class_dir(kobj);
+	kfree(dir);
+}
+
+static const
+struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj)
 {
+	struct class_dir *dir = to_class_dir(kobj);
+	return dir->class->ns_type;
+}
+
+static struct kobj_type class_dir_ktype = {
+	.release	= class_dir_release,
+	.sysfs_ops	= &kobj_sysfs_ops,
+	.child_ns_type	= class_dir_child_ns_type
+};
+
+static struct kobject *
+class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
+{
+	struct class_dir *dir;
 	int retval;
 
+	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
+	if (!dir)
+		return NULL;
+
+	dir->class = class;
+	kobject_init(&dir->kobj, &class_dir_ktype);
+
+	dir->kobj.kset = &class->p->class_dirs;
+
+	retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
+	if (retval < 0) {
+		kobject_put(&dir->kobj);
+		return NULL;
+	}
+	return &dir->kobj;
+}
+
+
+static struct kobject *get_device_parent(struct device *dev,
+					 struct device *parent)
+{
 	if (dev->class) {
 		static DEFINE_MUTEX(gdp_mutex);
 		struct kobject *kobj = NULL;
@@ -634,18 +694,7 @@ static struct kobject *get_device_parent(struct device *dev,
 		}
 
 		/* or create a new class-directory at the parent device */
-		k = kobject_create();
-		if (!k) {
-			mutex_unlock(&gdp_mutex);
-			return NULL;
-		}
-		k->kset = &dev->class->p->class_dirs;
-		retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
-		if (retval < 0) {
-			mutex_unlock(&gdp_mutex);
-			kobject_put(k);
-			return NULL;
-		}
+		k = class_dir_create_and_add(dev->class, parent_kobj);
 		/* do not emit an uevent for this simple "glue" directory */
 		mutex_unlock(&gdp_mutex);
 		return k;
diff --git a/include/linux/device.h b/include/linux/device.h
index 6f96191..7bb9f42 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -202,6 +202,9 @@ struct class {
 	int (*suspend)(struct device *dev, pm_message_t state);
 	int (*resume)(struct device *dev);
 
+	const struct kobj_ns_type_operations *ns_type;
+	const void *(*namespace)(struct device *dev);
+
 	const struct dev_pm_ops *pm;
 
 	struct class_private *p;
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 3950d3c..d9456f6 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -108,6 +108,8 @@ struct kobj_type {
 	void (*release)(struct kobject *kobj);
 	const struct sysfs_ops *sysfs_ops;
 	struct attribute **default_attrs;
+	const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
+	const void *(*namespace)(struct kobject *kobj);
 };
 
 struct kobj_uevent_env {
@@ -134,6 +136,30 @@ struct kobj_attribute {
 
 extern const struct sysfs_ops kobj_sysfs_ops;
 
+enum kobj_ns_type {
+	KOBJ_NS_TYPE_NONE = 0,
+	KOBJ_NS_TYPES
+};
+
+struct sock;
+struct kobj_ns_type_operations {
+	enum kobj_ns_type type;
+	const void *(*current_ns)(void);
+	const void *(*netlink_ns)(struct sock *sk);
+	const void *(*initial_ns)(void);
+};
+
+int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
+int kobj_ns_type_registered(enum kobj_ns_type type);
+const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
+const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
+
+const void *kobj_ns_current(enum kobj_ns_type type);
+const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk);
+const void *kobj_ns_initial(enum kobj_ns_type type);
+void kobj_ns_exit(enum kobj_ns_type type, const void *ns);
+
+
 /**
  * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
  *
diff --git a/lib/kobject.c b/lib/kobject.c
index 8115eb1..bbb2bb4 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -850,6 +850,109 @@ struct kset *kset_create_and_add(const char *name,
 }
 EXPORT_SYMBOL_GPL(kset_create_and_add);
 
+
+static DEFINE_SPINLOCK(kobj_ns_type_lock);
+static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
+
+int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
+{
+	enum kobj_ns_type type = ops->type;
+	int error;
+
+	spin_lock(&kobj_ns_type_lock);
+
+	error = -EINVAL;
+	if (type >= KOBJ_NS_TYPES)
+		goto out;
+
+	error = -EINVAL;
+	if (type <= KOBJ_NS_TYPE_NONE)
+		goto out;
+
+	error = -EBUSY;
+	if (kobj_ns_ops_tbl[type])
+		goto out;
+
+	error = 0;
+	kobj_ns_ops_tbl[type] = ops;
+
+out:
+	spin_unlock(&kobj_ns_type_lock);
+	return error;
+}
+
+int kobj_ns_type_registered(enum kobj_ns_type type)
+{
+	int registered = 0;
+
+	spin_lock(&kobj_ns_type_lock);
+	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
+		registered = kobj_ns_ops_tbl[type] != NULL;
+	spin_unlock(&kobj_ns_type_lock);
+
+	return registered;
+}
+
+const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
+{
+	const struct kobj_ns_type_operations *ops = NULL;
+
+	if (parent && parent->ktype->child_ns_type)
+		ops = parent->ktype->child_ns_type(parent);
+
+	return ops;
+}
+
+const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
+{
+	return kobj_child_ns_ops(kobj->parent);
+}
+
+
+const void *kobj_ns_current(enum kobj_ns_type type)
+{
+	const void *ns = NULL;
+
+	spin_lock(&kobj_ns_type_lock);
+	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
+	    kobj_ns_ops_tbl[type])
+		ns = kobj_ns_ops_tbl[type]->current_ns();
+	spin_unlock(&kobj_ns_type_lock);
+
+	return ns;
+}
+
+const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
+{
+	const void *ns = NULL;
+
+	spin_lock(&kobj_ns_type_lock);
+	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
+	    kobj_ns_ops_tbl[type])
+		ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
+	spin_unlock(&kobj_ns_type_lock);
+
+	return ns;
+}
+
+const void *kobj_ns_initial(enum kobj_ns_type type)
+{
+	const void *ns = NULL;
+
+	spin_lock(&kobj_ns_type_lock);
+	if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
+	    kobj_ns_ops_tbl[type])
+		ns = kobj_ns_ops_tbl[type]->initial_ns();
+	spin_unlock(&kobj_ns_type_lock);
+
+	return ns;
+}
+
+void kobj_ns_exit(enum kobj_ns_type type, const void *ns)
+{
+}
+
+
 EXPORT_SYMBOL(kobject_get);
 EXPORT_SYMBOL(kobject_put);
 EXPORT_SYMBOL(kobject_del);
-- 
1.7.0.3


  parent reply	other threads:[~2010-05-21 16:54 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-21 16:51 [GIT PATCH] driver core patches for .35 Greg KH
2010-05-21 16:53 ` [PATCH 01/38] drivers/base/cpu.c: fix the output from /sys/devices/system/cpu/offline Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 02/38] firmware_class: fix memory leak - free allocated pages Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 03/38] kref: remove kref_set Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 04/38] Driver core: Reduce the level of request_firmware() messages Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 05/38] driver-core: fix potential race condition in drivers/base/dd.c Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 06/38] Driver core: don't initialize wakeup flags Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 07/38] driver core: module.c: Use kasprintf Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 08/38] devtmpfs: support !CONFIG_TMPFS Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 09/38] platform_bus: allow custom extensions to system PM methods Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 10/38] drivers/base: Convert dev->sem to mutex Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 11/38] lockdep: Add novalidate class for dev->mutex conversion Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 12/38] firmware class: export nowait to userspace Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 13/38] firmware loader: rely on driver core to create class attribute Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 14/38] firmware loader: split out builtin firmware handling Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 15/38] firmware loader: do not allocate firmare id separately Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 16/38] Driver core: Protect device shutdown from hot unplug events Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 17/38] generate "change" uevent for loop device Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 18/38] sysfs: Basic support for multiple super blocks Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 19/38] sysfs: Remove double free sysfs_get_sb Greg Kroah-Hartman
2010-05-21 16:53 ` Greg Kroah-Hartman [this message]
2010-05-21 16:53 ` [PATCH 21/38] sysfs: Implement sysfs tagged directory support Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 22/38] sysfs: Add support for tagged directories with untagged members Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 23/38] sysfs: Implement sysfs_delete_link Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 24/38] driver core: Implement ns directory support for device classes Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 25/38] sysfs: Comment sysfs directory tagging logic Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 26/38] sysfs-namespaces: add a high-level Documentation file Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 27/38] sysfs: Don't use enums in inline function declaration Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 28/38] sysfs: Remove usage of S_BIAS to avoid merge conflict with the vfs tree Greg Kroah-Hartman
2010-05-21 16:53 ` [PATCH 29/38] sysfs: add struct file* to bin_attr callbacks Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 30/38] pci: check caps from sysfs file open to read device dependent config space Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 31/38] driver-core: fix Typo in drivers/base/core.c for CONFIG_MODULE Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 32/38] kobject: Send hotplug events in all network namespaces Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 33/38] netns: Teach network device kobjects which namespace they are in Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 34/38] net/sysfs: Fix the bitrot in network device kobject namespace support Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 35/38] netlink: Implment netlink_broadcast_filtered Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 36/38] kobj: Send hotplug events in the proper namespace Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 37/38] hotplug: netns aware uevent_helper Greg Kroah-Hartman
2010-05-21 16:54 ` [PATCH 38/38] net: Expose all network devices in a namespaces in sysfs Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1274460848-11377-20-git-send-email-gregkh@suse.de \
    --to=gregkh@suse.de \
    --cc=ebiederm@xmission.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox