今天把以前做的工作重新总结一下,以前在挂载u盘的时候,kernel是2。4,采用的是hotplug的方式,但是主要是自己写的一个hotplug的方式。
因为在挂u盘的时候,系统中模拟的了一个软scsi的控制器,用户对u盘的操作都采用的是scsi的cmd来进行。
所以在scsi的driver里面,当执行到sd_finish函数时,
加了这样的一个函数。(其实和hotplug的方式一样),采用call_usermodehelper,这个东西就是内核通过khelper工作队列来call用户空间的应用程序。
static void notify_user_level_of_disk_change(int is_add, int major, int minor)
{
char major_string[] = "XXXX";
char minor_string[] = "XXXX";
char *argv[4] =
{
(is_add ? "/sbin/hotdiskadd" : "/sbin/hotdiskremove"),
major_string,
minor_string,
NULL
};
char *envp[3] =
{
"HOME=/",
"PATH=/sbin:/bin:/usr/sbin:/usr/bin",
NULL
};
int value;
if (in_interrupt ()) {
printk(KERN_WARNING "new SCSI disk: In_interrupt/n");
return;
}
if (!current->fs->root) {
/* statically linked USB is initted rather early */
printk(KERN_INFO "new SCSI disk: no FS yet/n");
return;
}
sprintf(major_string, "%d", major);
sprintf(minor_string, "%d", minor);
printk(KERN_INFO "SCSI disk handling: %s %s %s/n", argv[0], argv[1],
argv[2]);
value = call_usermodehelper(argv[0], argv, envp);
if (value != 0) {
printk(KERN_WARNING
"SCSI disk handling user-level notification returned "
"0x%x/n", value);
}
一般来说,设备的热插拔,要调用用户空间的程序以外,还要广播消息到用户空间的其他程序。
这就是通过netlink机制来发送。内核call,send-event。然后通过sock方式。
在我们的实际的做法中,通过上面的hotdiskadd,来修改一个临时的参数在/tmp目录下,有点累世kernel里面的proc。
然后发信号给init进程,SIGUSR1,启动想应的挂载或者remove动作。