#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/err.h>
static struct kobject *parent;
static struct kobject *child;
static struct kset *c_kset;
static unsigned long flag = 1;
static ssize_t att_show(struct kobject *kobj, struct attribute *attr, char *buf)
{
size_t count = 0;
count += sprintf(&buf[count], "%lu\n", flag);
return count;
}
static ssize_t att_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count)
{
flag = buf[0] - '0';
switch(flag)
{
case 0:
kobject_uevent(kobj, KOBJ_ADD);
break;
case 1:
kobject_uevent(kobj, KOBJ_REMOVE);
break;
case 2:
kobject_uevent(kobj, KOBJ_CHANGE);
break;
case 3:
kobject_uevent(kobj, KOBJ_MOVE);
break;
case 4:
kobject_uevent(kobj, KOBJ_ONLINE);
break;
case 5:
kobject_uevent(kobj, KOBJ_OFFLINE);
break;
}
return count;
}
static struct attribute cld_att = {
.name = "cldattr",
.mode = S_IRUGO | S_IWUSR,
};
static const struct sysfs_ops att_ops = {
.show = att_show,
.store = att_store,
};
static struct kobj_type cld_ktype = {
.sysfs_ops = &att_ops,
};
static int kobj_demo_init(void)
{
int err;
parent = kobject_create_and_add("pa_obj", NULL);
child = kzalloc(sizeof(*child), GFP_KERNEL);
if(!child)
return PTR_ERR(child);
c_kset = kset_create_and_add("c_kset", NULL, parent);
if(!c_kset)
return -1;
child->kset = c_kset;
err = kobject_init_and_add(child, &cld_ktype, parent, "cld_obj");
if (err)
return err;
err = sysfs_create_file(child, &cld_att);
return err;
}
static void kobj_demo_exit(void)
{
sysfs_remove_file(child, &cld_att);
kset_unregister(c_kset);
kobject_del(child);
kobject_del(parent);
}
module_init(kobj_demo_init);
module_exit(kobj_demo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FORSAKENING-HDU");
MODULE_DESCRIPTION("KOBJECT TEST");
Makefile:
obj-m:=kobject-test.o
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
$(MAKE) -C$(KERNELDIR) M=$(PWD)
clean:
rm -f *.o *.ko *.mod.*
用户态模拟/sbin/hotplug的函数为:
#include <stdio.h>
#include <syslog.h>
extern char **environ;
int main(int argc, char **argv)
{
char **var;
syslog(LOG_INFO | LOG_LOCAL0, "------------------------\n");
syslog(LOG_INFO | LOG_LOCAL0, "argv[1]=%s\n", argv[1]);
for (var = environ; *var != NULL; ++var)
syslog(LOG_INFO | LOG_LOCAL0, "env=%s\n", *var);
syslog(LOG_INFO | LOG_LOCAL0, "------------------------\n");
return 0;
}
将这个函数编为hotplug添加为/sbin/hotplug, 并且echo "sbin/hotplug" > /proc/sys/kernel/hotpug
当运行insmod kobject-test.ko时候,在/var/log/message中打印:
[root@zx kobject]# echo "sbin/hotplug" > /proc/sys/kernel/hotplug
[root@zx kobject]# rmmod kobject-test.ko
[root@zx kobject]# cat /dev/null > /var/log/messages
[root@zx kobject]# insmod kobject-test.ko
[root@zx kobject]# cat /var/log/messages
Oct 5 12:22:23 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:28 zx hotplug: ------------------------
Oct 5 12:22:28 zx hotplug: argv[1]=module
Oct 5 12:22:28 zx hotplug: env=ACTION=add
Oct 5 12:22:28 zx hotplug: env=DEVPATH=/module/kobject_test
Oct 5 12:22:28 zx hotplug: env=SUBSYSTEM=module
Oct 5 12:22:28 zx hotplug: env=SEQNUM=1374
Oct 5 12:22:28 zx hotplug: env=HOME=/
Oct 5 12:22:28 zx hotplug: env=PATH=/sbin:/bin:/usr/sbin:/usr/bin
Oct 5 12:22:28 zx hotplug: ------------------------
Oct 5 12:22:28 zx kernel: __ratelimit: 40 callbacks suppressed
修改child的属性文件cldattr来模拟kobject的状态变化:
[root@zx kobject]# echo '0' > /sys/pa_obj/cld_obj/cldattr
[root@zx kobject]# echo '1' > /sys/pa_obj/cld_obj/cldattr
[root@zx kobject]# echo '2' > /sys/pa_obj/cld_obj/cldattr
[root@zx kobject]# cat /var/log/messages
Oct 5 12:22:23 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:28 zx hotplug: ------------------------
Oct 5 12:22:28 zx hotplug: argv[1]=module
Oct 5 12:22:28 zx hotplug: env=ACTION=add
Oct 5 12:22:28 zx hotplug: env=DEVPATH=/module/kobject_test
Oct 5 12:22:28 zx hotplug: env=SUBSYSTEM=module
Oct 5 12:22:28 zx hotplug: env=SEQNUM=1374
Oct 5 12:22:28 zx hotplug: env=HOME=/
Oct 5 12:22:28 zx hotplug: env=PATH=/sbin:/bin:/usr/sbin:/usr/bin
Oct 5 12:22:28 zx hotplug: ------------------------
Oct 5 12:22:28 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:33 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:38 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:43 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:49 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:49 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:22:52 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:22:54 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:22:59 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:01 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:04 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:09 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:09 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:11 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:14 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:15 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:17 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:19 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:19 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:23 zx pulseaudio[3186]: module-alsa-sink.c: ALSA woke us up to write new data to the device, but there was actually nothing to write! Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.
Oct 5 12:23:24 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:29 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:35 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:40 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:45 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:50 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:55 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:23:57 zx hotplug: ------------------------
Oct 5 12:23:57 zx hotplug: argv[1]=c_kset
Oct 5 12:23:57 zx hotplug: env=ACTION=add
Oct 5 12:23:57 zx hotplug: env=DEVPATH=/pa_obj/cld_obj
Oct 5 12:23:57 zx hotplug: env=SUBSYSTEM=c_kset
Oct 5 12:23:57 zx hotplug: env=SEQNUM=1375
Oct 5 12:23:57 zx hotplug: env=HOME=/
Oct 5 12:23:57 zx hotplug: env=PATH=/sbin:/bin:/usr/sbin:/usr/bin
Oct 5 12:23:57 zx hotplug: ------------------------
Oct 5 12:24:00 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:24:01 zx hotplug: ------------------------
Oct 5 12:24:01 zx hotplug: argv[1]=c_kset
Oct 5 12:24:01 zx hotplug: env=ACTION=remove
Oct 5 12:24:01 zx hotplug: env=DEVPATH=/pa_obj/cld_obj
Oct 5 12:24:01 zx hotplug: env=SUBSYSTEM=c_kset
Oct 5 12:24:01 zx hotplug: env=SEQNUM=1376
Oct 5 12:24:01 zx hotplug: env=HOME=/
Oct 5 12:24:01 zx hotplug: env=PATH=/sbin:/bin:/usr/sbin:/usr/bin
Oct 5 12:24:01 zx hotplug: ------------------------
Oct 5 12:24:05 zx hotplug: ------------------------
Oct 5 12:24:05 zx hotplug: argv[1]=c_kset
Oct 5 12:24:05 zx hotplug: env=ACTION=change
Oct 5 12:24:05 zx hotplug: env=DEVPATH=/pa_obj/cld_obj
Oct 5 12:24:05 zx hotplug: env=SUBSYSTEM=c_kset
Oct 5 12:24:05 zx hotplug: env=SEQNUM=1377
Oct 5 12:24:05 zx hotplug: env=HOME=/
Oct 5 12:24:05 zx hotplug: env=PATH=/sbin:/bin:/usr/sbin:/usr/bin
Oct 5 12:24:05 zx hotplug: ------------------------
Oct 5 12:24:05 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:24:10 zx kernel: __ratelimit: 40 callbacks suppressed
Oct 5 12:24:15 zx kernel: __ratelimit: 40 callbacks suppressed
[root@zx kobject]#
参考:深入Linux设备驱动程序内核机制 - 陈学松