Skip to contentSkip to conversation

kobject hotplug support for 2.5.66

RFC New Greg KH 1 participant 1 message Apr 4, 2003

Subsystems (6)
Networking VFS Block layer ACPI +2 more subsystems
lore
Share & tools
lore

Greg KH

author
#0 lore raw

RFC 1/1 kobject hotplug support for 2.5.66

Hi,

Here's a patch against 2.5.66 that adds /sbin/hotplug support for kobjects that are registered with a subsystem. This allows partitions in /sys/block to get hotplug calls. The /sys/device/ hotplug calls were also moved to use this logic, but the /sys/class/ hotplug call can not, as it does not create new kobjects.

This work is based on work done by Kevin Fleming, who originally got the hotplug support working for /sys/block.

Any comments or objections to me sending this on to Linus?

thanks,

greg k-h

arch/i386/kernel/edd.c +1 -1
diff -Nru a/arch/i386/kernel/edd.c b/arch/i386/kernel/edd.c
@@ -598,7 +598,7 @@
 	.default_attrs	= def_attrs,
 };
 
-static decl_subsys(edd,&ktype_edd);
+static decl_subsys(edd,&ktype_edd,NULL);
 
 
 /**
drivers/acpi/bus.c +1 -1
diff -Nru a/drivers/acpi/bus.c b/drivers/acpi/bus.c
@@ -676,7 +676,7 @@
 	return_VALUE(-ENODEV);
 }
 
-decl_subsys(acpi,NULL);
+decl_subsys(acpi,NULL,NULL);
 
 static int __init acpi_init (void)
 {
drivers/base/base.h +0 -5
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
@@ -20,13 +20,8 @@
 
 
 #ifdef CONFIG_HOTPLUG
-extern int dev_hotplug(struct device *dev, const char *action);
 extern int class_hotplug(struct device *dev, const char *action);
 #else
-static inline int dev_hotplug(struct device *dev, const char *action)
-{
-	return 0;
-}
 static inline int class_hotplug(struct device *dev, const char *action)
 {
 	return 0;
drivers/base/bus.c +1 -1
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
@@ -132,7 +132,7 @@
 
 };
 
-decl_subsys(bus,&ktype_bus);
+decl_subsys(bus,&ktype_bus,NULL);
 
 /**
  *	bus_for_each_dev - device iterator.
drivers/base/class.c +3 -1
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
@@ -49,7 +49,9 @@
 	.sysfs_ops	= &class_sysfs_ops,
 };
 
-static decl_subsys(class,&ktype_devclass);
+/* Classes can't use the kobject hotplug logic, as
+ * they do not add new kobjects to the system */
+static decl_subsys(class,&ktype_devclass,NULL);
 
 
 static int devclass_dev_link(struct device_class * cls, struct device * dev)
drivers/base/core.c +46 -9

88 lines not on this page · raw message

drivers/base/firmware.c +1 -1
diff -Nru a/drivers/base/firmware.c b/drivers/base/firmware.c
@@ -6,7 +6,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
-static decl_subsys(firmware,NULL);
+static decl_subsys(firmware,NULL,NULL);
 
 int firmware_register(struct subsystem * s)
 {
drivers/base/hotplug.c +2 -30
diff -Nru a/drivers/base/hotplug.c b/drivers/base/hotplug.c
@@ -2,8 +2,8 @@
  * drivers/base/hotplug.c - hotplug call code
  * 
  * Copyright (c) 2000-2001 David Brownell
- * Copyright (c) 2002 Greg Kroah-Hartman
- * Copyright (c) 2002 IBM Corp.
+ * Copyright (c) 2002-2003 Greg Kroah-Hartman
+ * Copyright (c) 2002-2003 IBM Corp.
  *
  * Based off of drivers/usb/core/usb.c:call_agent(), which was 
  * written by David Brownell.
@@ -53,17 +53,6 @@
 	if (!hotplug_path [0])
 		return -ENODEV;
 
-	if (in_interrupt ()) {
-		pr_debug ("%s - in_interrupt, not allowed!", __FUNCTION__);
-		return -EIO;
-	}
-
-	if (!current->fs->root) {
-		/* don't try to do anything unless we have a root partition */
-		pr_debug ("%s - %s -- no FS yet\n", __FUNCTION__, action);
-		return -EIO;
-	}
-
 	envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
 	if (!envp)
 		return -ENOMEM;
@@ -127,23 +116,6 @@
 	kfree (envp);
 	return retval;
 }
-
-
-/*
- * dev_hotplug - called when any device is added or removed from a bus
- */
-int dev_hotplug (struct device *dev, const char *action)
-{
-	pr_debug ("%s\n", __FUNCTION__);
-	if (!dev)
-		return -ENODEV;
-
-	if (!dev->bus)
-		return -ENODEV;
-
-	return do_hotplug (dev, dev->bus->name, action, dev->bus->hotplug);
-}
-
 
 /*
  * class_hotplug - called when a class is added or removed from a device
drivers/block/genhd.c +13 -1
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
@@ -525,9 +525,21 @@
 	.default_attrs	= default_attrs,
 };
 
+extern struct kobj_type ktype_part;
+
+static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
+{
+	struct kobj_type *ktype = get_ktype(kobj);
+
+	return ((ktype == &ktype_block) || (ktype == &ktype_part));
+}
+
+static struct kset_hotplug_ops block_hotplug_ops = {
+	.filter	= block_hotplug_filter,
+};
 
 /* declare block_subsys. */
-static decl_subsys(block,&ktype_block);
+static decl_subsys(block, &ktype_block, &block_hotplug_ops);
 
 
 struct gendisk *alloc_disk(int minors)
drivers/hotplug/pci_hotplug_core.c +1 -1
diff -Nru a/drivers/hotplug/pci_hotplug_core.c b/drivers/hotplug/pci_hotplug_core.c
@@ -100,7 +100,7 @@
 	.sysfs_ops = &hotplug_slot_sysfs_ops
 };
 
-static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
+static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
 
 
 /* these strings match up with the values in pci_bus_speed */
fs/filesystems.c +1 -1
diff -Nru a/fs/filesystems.c b/fs/filesystems.c
@@ -61,7 +61,7 @@
 
 
 /* define fs_subsys */
-static decl_subsys(fs, NULL);
+static decl_subsys(fs, NULL, NULL);
 
 static int register_fs_subsys(struct file_system_type * fs)
 {
fs/partitions/check.c +1 -1
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
@@ -248,7 +248,7 @@
 
 extern struct subsystem block_subsys;
 
-static struct kobj_type ktype_part = {
+struct kobj_type ktype_part = {
 	.default_attrs	= default_attrs,
 	.sysfs_ops	= &part_sysfs_ops,
 };
include/linux/kobject.h +21 -1
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
@@ -57,12 +57,24 @@
  *	of object; multiple ksets can belong to one subsystem. All 
  *	ksets of a subsystem share the subsystem's lock.
  *
+ *      Each kset can support hotplugging; if it does, it will be given
+ *      the opportunity to filter out specific kobjects from being
+ *      reported, as well as to add its own "data" elements to the
+ *      environment being passed to the hotplug helper.
  */
+struct kset_hotplug_ops {
+	int (*filter)(struct kset *kset, struct kobject *kobj);
+	char *(*name)(struct kset *kset, struct kobject *kobj);
+	int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
+			int num_envp, char *buffer, int buffer_size);
+};
+
 struct kset {
 	struct subsystem	* subsys;
 	struct kobj_type	* ktype;
 	struct list_head	list;
 	struct kobject		kobj;
+	struct kset_hotplug_ops	* hotplug_ops;
 };
 
 
@@ -86,6 +98,13 @@
 	kobject_put(&k->kobj);
 }
 
+static inline struct kobj_type * get_ktype(struct kobject * k)
+{
+	if (k->kset && k->kset->ktype)
+		return k->kset->ktype;
+	else 
+		return k->ktype;
+}
 
 extern struct kobject * kset_find_obj(struct kset *, const char *);
 
@@ -95,11 +114,12 @@
 	struct rw_semaphore	rwsem;
 };
 
-#define decl_subsys(_name,_type) \
+#define decl_subsys(_name,_type,_hotplug_ops) \
 struct subsystem _name##_subsys = { \
 	.kset = { \
 		.kobj = { .name = __stringify(_name) }, \
 		.ktype = _type, \
+		.hotplug_ops =_hotplug_ops, \
 	} \
 }
 
lib/kobject.c +162 -8

200 lines not on this page · raw message

net/core/dev.c +1 -1
diff -Nru a/net/core/dev.c b/net/core/dev.c
@@ -2811,7 +2811,7 @@
 extern void dv_init(void);
 #endif /* CONFIG_NET_DIVERT */
 
-static decl_subsys(net,NULL);
+static decl_subsys(net,NULL,NULL);
 
 
 /*