diff -urN linux-2.6.8.1-mm3/arch/i386/kernel/cpu/mcheck/p4.c linux/arch/i386/kernel/cpu/mcheck/p4.c --- linux-2.6.8.1-mm3/arch/i386/kernel/cpu/mcheck/p4.c 2004-08-14 06:55:35.000000000 -0400 +++ linux/arch/i386/kernel/cpu/mcheck/p4.c 2004-08-20 14:14:09.826871408 -0400 @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -59,9 +60,15 @@ if (l & 0x1) { printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", - cpu); + cpu); + send_kevent(KEVENT_GENERAL, + "/org/kernel/arch/kernel/cpu/temperature", "high", + "Cpu: %d\n", cpu); } else { printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); + send_kevent(KEVENT_GENERAL, + "/org/kernel/arch/kernel/cpu/temperature", "normal", + "Cpu: %d\n", cpu); } } diff -urN linux-2.6.8.1-mm3/include/linux/kevent.h linux/include/linux/kevent.h --- linux-2.6.8.1-mm3/include/linux/kevent.h 1969-12-31 19:00:00.000000000 -0500 +++ linux/include/linux/kevent.h 2004-08-20 14:14:09.827871256 -0400 @@ -0,0 +1,39 @@ +#ifndef _LINUX_KEVENT_H +#define _LINUX_KEVENT_H + +#include + +/* kevent types - these are used as the multicast group */ +enum kevent { + KEVENT_GENERAL = 0, + KEVENT_STORAGE = 1, + KEVENT_POWER = 2, + KEVENT_FS = 3, + KEVENT_HOTPLUG = 4, +}; + +#ifdef CONFIG_KERNEL_EVENTS + +int send_kevent(enum kevent type, const char *object, + const char *signal, const char *fmt, ...); + +int send_kevent_atomic(enum kevent type, const char *object, + const char *signal, const char *fmt, ...); + +#else + +static inline int send_kevent(enum kevent type, const char *object, + const char *signal, const char *fmt, ...) +{ + return 0; +} + +static inline int send_kevent_atomic(enum kevent type, const char *object, + const char *signal, const char *fmt, ...) +{ + return 0; +} + +#endif /* ! CONFIG_KERNEL_EVENTS */ + +#endif /* _LINUX_KEVENT_H */ diff -urN linux-2.6.8.1-mm3/include/linux/netlink.h linux/include/linux/netlink.h --- linux-2.6.8.1-mm3/include/linux/netlink.h 2004-08-14 06:56:00.000000000 -0400 +++ linux/include/linux/netlink.h 2004-08-20 14:14:09.827871256 -0400 @@ -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_KEVENT 15 /* Kernel messages to userspace */ #define NETLINK_TAPBASE 16 /* 16 to 31 are ethertap */ #define MAX_LINKS 32 diff -urN linux-2.6.8.1-mm3/init/Kconfig linux/init/Kconfig --- linux-2.6.8.1-mm3/init/Kconfig 2004-08-20 14:05:49.454939504 -0400 +++ linux/init/Kconfig 2004-08-20 14:14:09.828871104 -0400 @@ -149,6 +149,20 @@ logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL. +config KERNEL_EVENTS + bool "Kernel Events Layer" + depends on NET + default y + help + This option enables the kernel events layer, which is a simple + mechanism for kernel-to-user communication over a netlink socket. + The goal of the kernel events layer is to provide a simple and + efficient logging, error, and events system. Specifically, code + is available to link the events into D-BUS. Say Y, unless you + are building a system requiring minimal memory consumption. + + D-BUS is available at http://dbus.freedesktop.org/ + config AUDITSYSCALL bool "Enable system-call auditing support" depends on AUDIT && (X86 || PPC64 || ARCH_S390 || IA64) diff -urN linux-2.6.8.1-mm3/kernel/kevent.c linux/kernel/kevent.c --- linux-2.6.8.1-mm3/kernel/kevent.c 1969-12-31 19:00:00.000000000 -0500 +++ linux/kernel/kevent.c 2004-08-20 14:18:45.812915152 -0400 @@ -0,0 +1,127 @@ +/* + * kernel/kevent.c - kernel event delivery via netlink socket + * + * Copyright (C) 2004 Red Hat, Inc. All rights reserved. + * + * Licensed under the GNU GPL v2. + * + * Authors: + * Arjan van de Ven + * Robert Love + * Kay Sievers + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct sock *kevent_sock = NULL; /* kevent's global netlink socket */ + +static int netlink_send(__u32 groups, int gfp_mask, const char *buffer, int len) +{ + struct sk_buff *skb; + char *data_start; + + if (!kevent_sock) + return -EIO; + if (!buffer) + return -EINVAL; + if (len > PAGE_SIZE) + return -EINVAL; + + skb = alloc_skb(len, gfp_mask); + if (!skb) + return -ENOMEM; + data_start = skb_put(skb, len); + memcpy(data_start, buffer, len); + + return netlink_broadcast(kevent_sock, skb, 0, groups, gfp_mask); +} + +static int do_send_kevent(enum kevent type, int gfp_mask, const char *object, + const char *signal, const char *fmt, va_list args) +{ + char *buffer; + int len; + int ret; + + if (!object) + return -EINVAL; + if (!signal) + return -EINVAL; + if (strlen(object) > PAGE_SIZE) + return -EINVAL; + + buffer = (char *) alloc_page(gfp_mask); + if (!buffer) + return -ENOMEM; + + snprintf(buffer, PAGE_SIZE, "%s\n%s\n", object, signal); + len = strlen(buffer); + + /* optionally, the payload */ + if (fmt) + len += vscnprintf(buffer+len, PAGE_SIZE-len-1, fmt, args); + buffer[len++] = '\0'; + + ret = netlink_send((1 << type), gfp_mask, buffer, len); + free_page((unsigned long) buffer); + + return ret; +} + +/** + * send_kevent - send a message to user-space via the kernel events layer + */ +int send_kevent(enum kevent type, const char *object, + const char *signal, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = do_send_kevent(type, GFP_KERNEL, object, signal, fmt, args); + va_end(args); + + return ret; +} + +EXPORT_SYMBOL_GPL(send_kevent); + +/** + * send_kevent_atomic - send a message to user-space via the kernel events layer + */ +int send_kevent_atomic(enum kevent type, const char *object, + const char *signal, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = do_send_kevent(type, GFP_ATOMIC, object, signal, fmt, args); + va_end(args); + + return ret; +} + +EXPORT_SYMBOL_GPL(send_kevent_atomic); + +static int kevent_init(void) +{ + kevent_sock = netlink_kernel_create(NETLINK_KEVENT, NULL); + + if (!kevent_sock) { + printk(KERN_ERR + "kevent: unable to create netlink socket!\n"); + return -ENODEV; + } + + return 0; +} + +module_init(kevent_init); diff -urN linux-2.6.8.1-mm3/kernel/Makefile linux/kernel/Makefile --- linux-2.6.8.1-mm3/kernel/Makefile 2004-08-20 14:05:49.476936160 -0400 +++ linux/kernel/Makefile 2004-08-20 14:14:22.981871544 -0400 @@ -26,6 +26,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDITSYSCALL) += auditsc.o obj-$(CONFIG_KPROBES) += kprobes.o +obj-$(CONFIG_KERNEL_EVENTS) += kevent.o ifneq ($(CONFIG_IA64),y) # According to Alan Modra , the -fno-omit-frame-pointer is