bk://kernel.bkbits.net/gregkh/linux/driver-2.6
greg@kroah.com|ChangeSet|20040910234535|55231 greg

# This is a BitKeeper generated diff -Nru style patch.
#
# lib/kobject.c
#   2004/09/10 16:45:17-07:00 greg@kroah.com +5 -128
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# lib/kobject.c
#   2004/09/08 17:33:38-07:00 greg@kroah.com +1 -1
#   ksyms: don't implement /sys/kernel/hotplug_seqnum if CONFIG_HOTPLUG is not enabled.
# 
# lib/kobject.c
#   2004/09/08 21:17:58-07:00 greg@kroah.com +1 -1
#   kobject: hotplug_seqnum is not 64 bits on all platforms, so fix it.
# 
# lib/kobject.c
#   2004/09/05 00:58:23+02:00 greg@kroah.com +1 -1
#   kobject: fix build error if CONFIG_HOTPLUG is not enabled.
#   
#   Thanks to Kay Sievers for pointing this out.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# lib/kobject.c
#   2004/09/04 01:19:44+02:00 greg@kroah.com +1 -1
#   kobject: adjust hotplug_seqnum increment to keep userspace and kernel agreeing.
# 
# lib/kobject.c
#   2004/09/03 11:00:55+02:00 kay.sievers@vrfy.org +2 -2
#   export of SEQNUM to userspace (creates /sys/kernel)
# 
# include/linux/kobject.h
#   2004/09/10 16:45:17-07:00 greg@kroah.com +29 -3
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/kobject.h
#   2004/09/08 21:19:11-07:00 greg@kroah.com +1 -1
#   kobject: hotplug_seqnum is not 64 bits on all platforms, so fix it.
# 
# include/linux/kobject.h
#   2004/09/03 11:00:55+02:00 kay.sievers@vrfy.org +3 -0
#   export of SEQNUM to userspace (creates /sys/kernel)
# 
# ChangeSet
#   2004/09/11 15:06:46-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# init/Kconfig
#   2004/09/11 15:06:42-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/10 16:45:35-07:00 greg@kroah.com 
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# lib/kobject_uevent.c
#   2004/09/10 16:45:17-07:00 greg@kroah.com +264 -0
# 
# lib/kobject_uevent.c
#   2004/09/10 16:45:17-07:00 greg@kroah.com +0 -0
#   BitKeeper file /home/greg/linux/BK/driver-2.6/lib/kobject_uevent.c
# 
# lib/Makefile
#   2004/09/10 16:45:17-07:00 greg@kroah.com +1 -1
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# init/Kconfig
#   2004/09/10 16:45:17-07:00 greg@kroah.com +19 -0
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# include/linux/netlink.h
#   2004/09/10 16:45:17-07:00 greg@kroah.com +1 -0
#   Kobject Userspace Event Notification
#     
#   Implemetation of userspace events through a netlink socket. The kernel events
#   layer provides the functionality to raise an event from a given kobject
#   represented by its sysfs-path and a signal string to describe the type of
#   event.
#     
#   Currently, kobject additions and removals are signalized to userspace by forking
#   the /sbin/hotplug helper. This patch moves this special case of userspace-event
#   out of the kobject core to the new kobject_uevent implementation. This makes it
#   possible to send all hotplug messages also through the new netlink transport.
#     
#   Possible new users of the kernel userspace functionality are filesystem
#   mount events (block device claim/release) or simple device state transitions
#   (cpu overheating).
#     
#   To send an event, the user needs to pass the kobject, a optional
#   sysfs-attribute and the signal string to the following function:
#     
#     kobject_uevent(const char *signal,
#                    struct kobject *kobj,
#                    struct attribute *attr)
#     
#     Example:
#     kobject_uevent("overheating", &cpu->kobj, NULL);
#     
#   The message itself is sent over multicast netlink socket, which makes
#   it possible for userspace to listen with multiple applications for the same
#   messages.
#     
#   Signed-off-by: Robert Love <rml@novell.com>
#   Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/08 21:25:19-07:00 greg@kroah.com 
#   [PATCH] ksyms: don't implement /sys/kernel/hotplug_seqnum if CONFIG_HOTPLUG is not enabled.
#   
#   Signed-off-by: Andrew Morton <akpm@osdl.org>
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# kernel/ksysfs.c
#   2004/09/08 17:33:38-07:00 greg@kroah.com +6 -2
#   ksyms: don't implement /sys/kernel/hotplug_seqnum if CONFIG_HOTPLUG is not enabled.
# 
# ChangeSet
#   2004/09/08 21:23:42-07:00 greg@kroah.com 
#   [PATCH] kobject: hotplug_seqnum is not 64 bits on all platforms, so fix it.
#   
#   Thanks to Kay Sievers for pointing this out.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# kernel/ksysfs.c
#   2004/09/08 21:17:58-07:00 greg@kroah.com +1 -1
#   kobject: hotplug_seqnum is not 64 bits on all platforms, so fix it.
# 
# ChangeSet
#   2004/09/04 17:52:24-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6
#   into bix.(none):/usr/src/bk-driver-core
# 
# kernel/Makefile
#   2004/09/04 17:52:20-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/09/05 00:59:19+02:00 greg@kroah.com 
#   kobject: fix build error if CONFIG_HOTPLUG is not enabled.
#   
#   Thanks to Kay Sievers for pointing this out.
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/04 18:56:35+02:00 greg@kroah.com 
#   ksysfs: don't build ksysfs if CONFIG_SYSFS is not enabled.
#   
#   Thanks to Kay Sievers for pointing this out.
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# kernel/Makefile
#   2004/09/04 18:56:13+02:00 greg@kroah.com +2 -1
#   ksysfs: don't build ksysfs if CONFIG_SYSFS is not enabled.
#   
#   Thanks to Kay Sievers for pointing this out.
#     
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# ChangeSet
#   2004/09/04 01:20:44+02:00 greg@kroah.com 
#   kobject: adjust hotplug_seqnum increment to keep userspace and kernel agreeing.
# 
# ChangeSet
#   2004/09/04 00:11:26+02:00 kay.sievers@vrfy.org 
#   [PATCH] export of SEQNUM to userspace (creates /sys/kernel)
#   
#   o /sys/kernel/hotplug_seqnum exports the current number
#   o lib/kobject.c's  sequence_num is renamed to hotplug_seqnum and
#     exported by include/linux/kobject.h
#   o the source file ksysfs.c in kernel/ creates on init the
#     sybsystem "/sys/kernel/" in sysfs
#   
#   
#   Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
# 
# kernel/Makefile
#   2004/09/03 11:00:55+02:00 kay.sievers@vrfy.org +1 -1
#   export of SEQNUM to userspace (creates /sys/kernel)
# 
# kernel/ksysfs.c
#   2004/09/03 11:00:55+02:00 kay.sievers@vrfy.org +52 -0
#   export of SEQNUM to userspace (creates /sys/kernel)
# 
# kernel/ksysfs.c
#   2004/09/03 11:00:55+02:00 kay.sievers@vrfy.org +0 -0
#   BitKeeper file /home/greg/linux/BK/driver-2.6/kernel/ksysfs.c
# 
# ChangeSet
#   2004/09/02 16:50:51-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/char/tty_io.c
#   2004/09/02 16:50:47-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/28 16:22:31-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/scsi/sr.c
#   2004/08/28 16:22:27-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/sd.c
#   2004/08/28 16:22:27-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/26 19:33:03-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/usb/core/message.c
#   2004/08/26 19:32:57-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/25 14:11:23-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6
#   into bix.(none):/usr/src/bk-driver-core
# 
# drivers/usb/core/urb.c
#   2004/08/25 14:11:19-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/08/25 14:11:19-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/sr.c
#   2004/08/25 14:11:19-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/sd.c
#   2004/08/25 14:11:19-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/char/tty_io.c
#   2004/08/25 14:11:19-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/24 17:43:51-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/char/tty_io.c
#   2004/08/24 17:43:47-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/23 21:36:39-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6
#   into bix.(none):/usr/src/bk-driver-core
# 
# ChangeSet
#   2004/08/23 16:45:53-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/scsi/sr.c
#   2004/08/23 21:36:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/sd.c
#   2004/08/23 21:36:35-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/urb.c
#   2004/08/23 16:45:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/usb/core/message.c
#   2004/08/23 16:45:49-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/23 13:56:59-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/scsi/sd.c
#   2004/08/23 13:56:55-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/15 01:06:01-07:00 akpm@bix.(none) 
#   Merge bk://kernel.bkbits.net/gregkh/linux/driver-2.6
#   into bix.(none):/usr/src/bk-driver-core
# 
# drivers/char/tty_io.c
#   2004/08/15 01:05:58-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# ChangeSet
#   2004/08/15 01:05:05-07:00 akpm@bix.(none) 
#   Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-driver-core
# 
# drivers/scsi/sr.c
#   2004/08/15 01:05:02-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
# drivers/scsi/sd.c
#   2004/08/15 01:05:01-07:00 akpm@bix.(none) +0 -0
#   Auto merged
# 
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h	2004-09-12 22:03:52 -07:00
+++ b/include/linux/kobject.h	2004-09-12 22:03:52 -07:00
@@ -26,6 +26,9 @@
 
 #define KOBJ_NAME_LEN	20
 
+/* counter to tag the hotplug event, read only except for the kobject core */
+extern u64 hotplug_seqnum;
+
 struct kobject {
 	char			* k_name;
 	char			name[KOBJ_NAME_LEN];
@@ -59,9 +62,7 @@
 extern struct kobject * kobject_get(struct kobject *);
 extern void kobject_put(struct kobject *);
 
-extern void kobject_hotplug(const char *action, struct kobject *);
-
-extern char * kobject_get_path(struct kset *, struct kobject *, int);
+extern char * kobject_get_path(struct kobject *, int);
 
 struct kobj_type {
 	void (*release)(struct kobject *);
@@ -233,6 +234,34 @@
 
 extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
 extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
+
+
+#ifdef CONFIG_HOTPLUG
+extern void kobject_hotplug(const char *action, struct kobject *kobj);
+#else
+static inline void kobject_hotplug(const char *action, struct kobject *kobj) { }
+#endif
+
+
+#ifdef CONFIG_KOBJECT_UEVENT
+extern int kobject_uevent(const char *signal, struct kobject *kobj,
+			  struct attribute *attr);
+
+extern int kobject_uevent_atomic(const char *signal, struct kobject *kobj,
+				 struct attribute *attr);
+#else
+static inline int kobject_uevent(const char *signal, struct kobject *kobj,
+				 struct attribute *attr)
+{
+	return 0;
+}
+
+static inline int kobject_uevent_atomic(const char *signal, struct kobject *kobj,
+					struct attribute *attr)
+{
+	return 0;
+}
+#endif
 
 #endif /* __KERNEL__ */
 #endif /* _KOBJECT_H_ */
diff -Nru a/include/linux/netlink.h b/include/linux/netlink.h
--- a/include/linux/netlink.h	2004-09-12 22:03:52 -07:00
+++ b/include/linux/netlink.h	2004-09-12 22:03:52 -07:00
@@ -17,6 +17,7 @@
 #define NETLINK_ROUTE6		11	/* af_inet6 route comm channel */
 #define NETLINK_IP6_FW		13
 #define NETLINK_DNRTMSG		14	/* DECnet routing messages */
+#define NETLINK_KOBJECT_UEVENT	15	/* Kernel messages to userspace */
 #define NETLINK_TAPBASE		16	/* 16 to 31 are ethertap */
 
 #define MAX_LINKS 32		
diff -Nru a/init/Kconfig b/init/Kconfig
--- a/init/Kconfig	2004-09-12 22:03:52 -07:00
+++ b/init/Kconfig	2004-09-12 22:03:52 -07:00
@@ -205,6 +205,25 @@
 	  agent" (/sbin/hotplug) to load modules and set up software needed
 	  to use devices as you hotplug them.
 
+config KOBJECT_UEVENT
+	bool "Kernel Userspace Events"
+	depends on NET
+	default y
+	help
+	  This option enables the kernel userspace event layer, which is a
+	  simple mechanism for kernel-to-user communication over a netlink
+	  socket.
+	  The goal of the kernel userspace events layer is to provide a simple
+	  and efficient events system, that notifies userspace about kobject
+	  state changes. This will enable applications to just listen for
+	  events instead of polling system devices and files.
+	  Hotplug events (kobject addition and removal) are also available on
+	  the netlink socket in addition to the execution of /sbin/hotplug if
+	  CONFIG_HOTPLUG is enabled.
+
+	  Say Y, unless you are building a system requiring minimal memory
+	  consumption.
+
 config IKCONFIG
 	bool "Kernel .config support"
 	---help---
diff -Nru a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile	2004-09-12 22:03:52 -07:00
+++ b/kernel/Makefile	2004-09-12 22:03:52 -07:00
@@ -7,7 +7,7 @@
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
-	    kthread.o
+	    kthread.o 
 
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
@@ -24,6 +24,7 @@
 obj-$(CONFIG_AUDIT) += audit.o
 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
 obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_SYSFS) += ksysfs.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff -Nru a/kernel/ksysfs.c b/kernel/ksysfs.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/kernel/ksysfs.c	2004-09-12 22:03:52 -07:00
@@ -0,0 +1,56 @@
+/*
+ * kernel/ksysfs.c - sysfs attributes in /sys/kernel, which
+ * 		     are not related to any other subsystem
+ *
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * 
+ * This file is release under the GPLv2
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#define KERNEL_ATTR_RO(_name) \
+static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
+
+#define KERNEL_ATTR_RW(_name) \
+static struct subsys_attribute _name##_attr = \
+	__ATTR(_name, 0644, _name##_show, _name##_store)
+
+#ifdef CONFIG_HOTPLUG
+static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page)
+{
+	return sprintf(page, "%llu\n", hotplug_seqnum);
+}
+KERNEL_ATTR_RO(hotplug_seqnum);
+#endif
+
+static decl_subsys(kernel, NULL, NULL);
+
+static struct attribute * kernel_attrs[] = {
+#ifdef CONFIG_HOTPLUG
+	&hotplug_seqnum_attr.attr,
+#endif
+	NULL
+};
+
+static struct attribute_group kernel_attr_group = {
+	.attrs = kernel_attrs,
+};
+
+static int __init ksysfs_init(void)
+{
+	int error = subsystem_register(&kernel_subsys);
+	if (!error)
+		error = sysfs_create_group(&kernel_subsys.kset.kobj,
+					   &kernel_attr_group);
+
+	return error;
+}
+
+core_initcall(ksysfs_init);
diff -Nru a/lib/Makefile b/lib/Makefile
--- a/lib/Makefile	2004-09-12 22:03:52 -07:00
+++ b/lib/Makefile	2004-09-12 22:03:52 -07:00
@@ -6,7 +6,7 @@
 lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
 	 bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
 	 kobject.o kref.o idr.o div64.o parser.o int_sqrt.o \
-	 bitmap.o extable.o
+	 bitmap.o extable.o kobject_uevent.o
 
 lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
 lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c	2004-09-12 22:03:52 -07:00
+++ b/lib/kobject.c	2004-09-12 22:03:52 -07:00
@@ -63,7 +63,7 @@
 	return container_of(entry,struct kobject,entry);
 }
 
-static int get_kobj_path_length(struct kset *kset, struct kobject *kobj)
+static int get_kobj_path_length(struct kobject *kobj)
 {
 	int length = 1;
 	struct kobject * parent = kobj;
@@ -79,7 +79,7 @@
 	return length;
 }
 
-static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path, int length)
+static void fill_kobj_path(struct kobject *kobj, char *path, int length)
 {
 	struct kobject * parent;
 
@@ -99,146 +99,24 @@
  * kobject_get_path - generate and return the path associated with a given kobj
  * and kset pair.  The result must be freed by the caller with kfree().
  *
- * @kset:	kset in question, with which to build the path
  * @kobj:	kobject in question, with which to build the path
  * @gfp_mask:	the allocation type used to allocate the path
  */
-char * kobject_get_path(struct kset *kset, struct kobject *kobj, int gfp_mask)
+char *kobject_get_path(struct kobject *kobj, int gfp_mask)
 {
 	char *path;
 	int len;
 
-	len = get_kobj_path_length(kset, kobj);
+	len = get_kobj_path_length(kobj);
 	path = kmalloc(len, gfp_mask);
 	if (!path)
 		return NULL;
 	memset(path, 0x00, len);
-	fill_kobj_path(kset, kobj, path, len);
+	fill_kobj_path(kobj, path, len);
 
 	return path;
 }
 
-#ifdef CONFIG_HOTPLUG
-
-#define BUFFER_SIZE	1024	/* should be enough memory for the env */
-#define NUM_ENVP	32	/* number of env pointers */
-static unsigned long sequence_num;
-static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
-
-static void kset_hotplug(const char *action, struct kset *kset,
-			 struct kobject *kobj)
-{
-	char *argv [3];
-	char **envp = NULL;
-	char *buffer = NULL;
-	char *scratch;
-	int i = 0;
-	int retval;
-	char *kobj_path = NULL;
-	char *name = NULL;
-	unsigned long seq;
-
-	/* If the kset has a filter operation, call it. If it returns
-	   failure, no hotplug event is required. */
-	if (kset->hotplug_ops->filter) {
-		if (!kset->hotplug_ops->filter(kset, kobj))
-			return;
-	}
-
-	pr_debug ("%s\n", __FUNCTION__);
-
-	if (!hotplug_path[0])
-		return;
-
-	envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
-	if (!envp)
-		return;
-	memset (envp, 0x00, NUM_ENVP * sizeof (char *));
-
-	buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
-	if (!buffer)
-		goto exit;
-
-	if (kset->hotplug_ops->name)
-		name = kset->hotplug_ops->name(kset, kobj);
-	if (name == NULL)
-		name = kset->kobj.name;
-
-	argv [0] = hotplug_path;
-	argv [1] = name;
-	argv [2] = NULL;
-
-	/* minimal command environment */
-	envp [i++] = "HOME=/";
-	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
-	scratch = buffer;
-
-	envp [i++] = scratch;
-	scratch += sprintf(scratch, "ACTION=%s", action) + 1;
-
-	spin_lock(&sequence_lock);
-	seq = sequence_num++;
-	spin_unlock(&sequence_lock);
-
-	envp [i++] = scratch;
-	scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1;
-
-	kobj_path = kobject_get_path(kset, kobj, GFP_KERNEL);
-	if (!kobj_path)
-		goto exit;
-
-	envp [i++] = scratch;
-	scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
-
-	if (kset->hotplug_ops->hotplug) {
-		/* have the kset specific function add its stuff */
-		retval = kset->hotplug_ops->hotplug (kset, kobj,
-				  &envp[i], NUM_ENVP - i, scratch,
-				  BUFFER_SIZE - (scratch - buffer));
-		if (retval) {
-			pr_debug ("%s - hotplug() returned %d\n",
-				  __FUNCTION__, retval);
-			goto exit;
-		}
-	}
-
-	pr_debug ("%s: %s %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],
-		  envp[0], envp[1], envp[2], envp[3], envp[4]);
-	retval = call_usermodehelper (argv[0], argv, envp, 0);
-	if (retval)
-		pr_debug ("%s - call_usermodehelper returned %d\n",
-			  __FUNCTION__, retval);
-
-exit:
-	kfree(kobj_path);
-	kfree(buffer);
-	kfree(envp);
-	return;
-}
-
-void kobject_hotplug(const char *action, struct kobject *kobj)
-{
-	struct kobject * top_kobj = kobj;
-
-	/* If this kobj does not belong to a kset,
-	   try to find a parent that does. */
-	if (!top_kobj->kset && top_kobj->parent) {
-		do {
-			top_kobj = top_kobj->parent;
-		} while (!top_kobj->kset && top_kobj->parent);
-	}
-
-	if (top_kobj->kset && top_kobj->kset->hotplug_ops)
-		kset_hotplug(action, top_kobj->kset, kobj);
-}
-#else
-void kobject_hotplug(const char *action, struct kobject *kobj)
-{
-	return;
-}
-#endif	/* CONFIG_HOTPLUG */
-
 /**
  *	kobject_init - initialize object.
  *	@kobj:	object in question.
@@ -654,7 +532,6 @@
 EXPORT_SYMBOL(kobject_add);
 EXPORT_SYMBOL(kobject_del);
 EXPORT_SYMBOL(kobject_rename);
-EXPORT_SYMBOL(kobject_hotplug);
 
 EXPORT_SYMBOL(kset_register);
 EXPORT_SYMBOL(kset_unregister);
diff -Nru a/lib/kobject_uevent.c b/lib/kobject_uevent.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/lib/kobject_uevent.c	2004-09-12 22:03:52 -07:00
@@ -0,0 +1,264 @@
+/*
+ * kernel userspace event delivery
+ *
+ * Copyright (C) 2004 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2004 Novell, Inc.  All rights reserved.
+ * Copyright (C) 2004 IBM, Inc. All rights reserved.
+ *
+ * Licensed under the GNU GPL v2.
+ *
+ * Authors:
+ *	Robert Love		<rml@novell.com>
+ *	Kay Sievers		<kay.sievers@vrfy.org>
+ *	Arjan van de Ven	<arjanv@redhat.com>
+ *	Greg Kroah-Hartman	<greg@kroah.com>
+ */
+
+#include <linux/spinlock.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/string.h>
+#include <linux/kobject.h>
+#include <net/sock.h>
+
+#ifdef CONFIG_KOBJECT_UEVENT
+static struct sock *uevent_sock;
+
+/**
+ * send_uevent - notify userspace by sending event trough netlink socket
+ *
+ * @signal: signal name
+ * @obj: object path (kobject)
+ * @buf: buffer used to pass auxiliary data like the hotplug environment
+ * @buflen:
+ * gfp_mask:
+ */
+static int send_uevent(const char *signal, const char *obj, const void *buf,
+			int buflen, int gfp_mask)
+{
+	struct sk_buff *skb;
+	char *pos;
+	int len;
+
+	if (!uevent_sock)
+		return -EIO;
+
+	len = strlen(signal) + 1;
+	len += strlen(obj) + 1;
+	len += buflen;
+
+	skb = alloc_skb(len, gfp_mask);
+	if (!skb)
+		return -ENOMEM;
+
+	pos = skb_put(skb, len);
+
+	pos += sprintf(pos, "%s@%s", signal, obj) + 1;
+	memcpy(pos, buf, buflen);
+
+	return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask);
+}
+
+static int do_kobject_uevent(const char *signal, struct kobject *kobj,
+			     struct attribute *attr, int gfp_mask)
+{
+	char *path;
+	char *attrpath;
+	int len;
+	int rc = -ENOMEM;
+
+	path = kobject_get_path(kobj, gfp_mask);
+	if (!path)
+		return -ENOMEM;
+
+	if (attr) {
+		len = strlen(path);
+		len += strlen(attr->name) + 2;
+		attrpath = kmalloc(len, gfp_mask);
+		if (!attrpath)
+			goto exit;
+		sprintf(attrpath, "%s/%s", path, attr->name);
+		rc = send_uevent(signal, attrpath, NULL, 0, gfp_mask);
+		kfree(attrpath);
+	} else {
+		rc = send_uevent(signal, path, NULL, 0, gfp_mask);
+	}
+
+exit:
+	kfree(path);
+	return rc;
+}
+
+/**
+ * kobject_uevent - notify userspace by sending event through netlink socket
+ * 
+ * @signal: signal name
+ * @kobj: struct kobject that the event is happening to
+ * @attr: optional struct attribute the event belongs to
+ */
+int kobject_uevent(const char *signal, struct kobject *kobj,
+		   struct attribute *attr)
+{
+	return do_kobject_uevent(signal, kobj, attr, GFP_KERNEL);
+}
+EXPORT_SYMBOL_GPL(kobject_uevent);
+
+int kobject_uevent_atomic(const char *signal, struct kobject *kobj,
+			  struct attribute *attr)
+{
+	return do_kobject_uevent(signal, kobj, attr, GFP_ATOMIC);
+}
+
+EXPORT_SYMBOL_GPL(kobject_uevent_atomic);
+
+static int __init kobject_uevent_init(void)
+{
+	uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, NULL);
+
+	if (!uevent_sock) {
+		printk(KERN_ERR
+		       "kobject_uevent: unable to create netlink socket!\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+core_initcall(kobject_uevent_init);
+
+#else
+static inline int send_uevent(const char *signal, const char *obj,
+			      const void *buf, int buflen, int gfp_mask)
+{
+	return 0;
+}
+
+#endif /* CONFIG_KOBJECT_UEVENT */
+
+
+#ifdef CONFIG_HOTPLUG
+u64 hotplug_seqnum;
+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+
+#define BUFFER_SIZE	1024	/* should be enough memory for the env */
+#define NUM_ENVP	32	/* number of env pointers */
+/**
+ * kobject_hotplug - notify userspace by executing /sbin/hotplug
+ *
+ * @action: action that is happening (usually "ADD" or "REMOVE")
+ * @kobj: struct kobject that the action is happening to
+ */
+void kobject_hotplug(const char *action, struct kobject *kobj)
+{
+	char *argv [3];
+	char **envp = NULL;
+	char *buffer = NULL;
+	char *scratch;
+	int i = 0;
+	int retval;
+	char *kobj_path = NULL;
+	char *name = NULL;
+	u64 seq;
+	struct kobject *top_kobj = kobj;
+	struct kset *kset;
+
+	if (!top_kobj->kset && top_kobj->parent) {
+		do {
+			top_kobj = top_kobj->parent;
+		} while (!top_kobj->kset && top_kobj->parent);
+	}
+
+	if (top_kobj->kset && top_kobj->kset->hotplug_ops)
+		kset = top_kobj->kset;
+	else
+		return;
+
+	/* If the kset has a filter operation, call it.
+	   Skip the event, if the filter returns zero. */
+	if (kset->hotplug_ops->filter) {
+		if (!kset->hotplug_ops->filter(kset, kobj))
+			return;
+	}
+
+	pr_debug ("%s\n", __FUNCTION__);
+
+	envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
+	if (!envp)
+		return;
+	memset (envp, 0x00, NUM_ENVP * sizeof (char *));
+
+	buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
+	if (!buffer)
+		goto exit;
+
+	if (kset->hotplug_ops->name)
+		name = kset->hotplug_ops->name(kset, kobj);
+	if (name == NULL)
+		name = kset->kobj.name;
+
+	argv [0] = hotplug_path;
+	argv [1] = name;
+	argv [2] = NULL;
+
+	/* minimal command environment */
+	envp [i++] = "HOME=/";
+	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+	scratch = buffer;
+
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "ACTION=%s", action) + 1;
+
+	kobj_path = kobject_get_path(kobj, GFP_KERNEL);
+	if (!kobj_path)
+		goto exit;
+
+	envp [i++] = scratch;
+	scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
+
+	spin_lock(&sequence_lock);
+	seq = ++hotplug_seqnum;
+	spin_unlock(&sequence_lock);
+
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "SEQNUM=%lld", seq) + 1;
+
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "SUBSYSTEM=%s", name) + 1;
+
+	if (kset->hotplug_ops->hotplug) {
+		/* have the kset specific function add its stuff */
+		retval = kset->hotplug_ops->hotplug (kset, kobj,
+				  &envp[i], NUM_ENVP - i, scratch,
+				  BUFFER_SIZE - (scratch - buffer));
+		if (retval) {
+			pr_debug ("%s - hotplug() returned %d\n",
+				  __FUNCTION__, retval);
+			goto exit;
+		}
+	}
+
+	pr_debug ("%s: %s %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],
+		  envp[0], envp[1], envp[2], envp[3], envp[4]);
+
+	send_uevent(action, kobj_path, buffer, scratch - buffer, GFP_KERNEL);
+
+	if (!hotplug_path[0])
+		goto exit;
+
+	retval = call_usermodehelper (argv[0], argv, envp, 0);
+	if (retval)
+		pr_debug ("%s - call_usermodehelper returned %d\n",
+			  __FUNCTION__, retval);
+
+exit:
+	kfree(kobj_path);
+	kfree(buffer);
+	kfree(envp);
+	return;
+}
+EXPORT_SYMBOL(kobject_hotplug);
+#endif /* CONFIG_HOTPLUG */
+
+
