打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
NVMe之热拔插事件

 在研究NVMe时,在SSD设备终端为了提高用户体验,常常需要支持自动识别并挂载SSD设备的功能,并且能够侦测到SSD设备断开事件。Linux系统中,当系统配置发生变化时,内核空间会向用户空间发出通知。Linux环境下使用了Netlink进行Hotplug事件侦测。

       Netlink是Linux特有的一种特殊socket,主要用于内核与用户态进程之间的通信。当然,Netlink也可以用于用户空间的两个进程通信,只是由于进程间通信方式有很多,一般不用Netlink。

       内核与用户态进程通信的方式有三种:/proc,ioctl,Netlink。其中只有Netlink是全双工通信,另两种是单向通信。

       /proc目录是系统模拟的一个文件系统,并非物理存在的。/proc目录下的文件表示内核参数的信息,一种信息可读可写,放在“/proc/sys”目录下,剩下的文件就是另外一种,这种信息只读。/proc目录下所有文件都绑定到一个内核函数上,文件被读时及时产生文件内容,如/proc/modules返回当前已经加载的模块列表。/proc文件的作用其实就是提供一个读取的函数,把共享内存的地址从内核空间传递到用户空间。当用于热插拔事件时,只能通过定时检查/proc中的文件,这种办法却并不能知晓设备什么时候插上或者拔掉,只能验证当前设备的状态。

     ioctl机制可以在驱动中扩展特定的ioctl消息,用于将一些状态从内核反映到用户态。它具有数据同步保护机制,但是不适合传输大量数据。且ioctl的发起者一定在用户态,想要内核态主动发送信息到用户态则是很难完成的,需要用户程序采用轮询机制不停的ioctl。所以不适合用于热插拔。

     Netlink是通过特殊的文件描述符(套接字)来进行Linux和用户空间的异步通信。Netlink是面向数据包的服务,为内核与用户空间搭建一个高速通道,用户空间程序不必使用轮询等技术来检测热拔插事件。

       Netlink特点如下:

① 支持全双工、异步通信(当然同步也支持)

② 用户空间可使用标准的BSD socket接口(netlink并没有屏蔽掉协议包的构造与解析过程,推荐使用libnl等第三方库)

③ 在内核空间使用专用的内核API接口

④ 支持多播(因此支持“总线”式通信,可实现消息订阅)

⑤ 在内核端可用于进程上下文与中断上下文

Netlink通信模型与socket通信模型十分相似,不同点在于:

1 Netlink采用自己独立的地址编码,sockaddr_nl

struct sockaddr_nl  

{   

   sa_family_t    nl_family;//AF_NETLINK 或着PF_NETLINK,通信类型

    unsigned short nl_pad;    //未使用,必须为0

    __u32          nl_pid// 接收或发送消息的进程的ID(用户)

    __u32          nl_groups//  多播组

     }; 

2 每个通过Netlink发出的消息都必须附带一个Netlink自己的消息头,nlmsghdr

3 内核态的Netlink操作API与用户态完全不同

4 用户态Netlink操作完全采用socket函数。


用户态创建Netlink socket的过程:

1 Netlink通信地址的设定,如:

addr.nl_family = AF_NETLINK;//通信类型必须是PF_NETLINK或者AF_NETLINK

 

addr.nl_pid = getpid();//通信端口(进程ID)

        addr.nl_groups = 0xffffffff; 

2 用socket函数创建Netlink socket:

socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)

3 用setsockopt函数设置socket选项值,包括socket的recv用的buffersize:

     setsockopt(netlink_fd, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size))

4 ioctl(netlink_fd, FIONBIO, &nonblock)

5 将socket描述符与socket地址绑定:

      bind(netlink_fd, (struct sockaddr *) &addr, sizeof(addr))

       

用户态应用使用标准的socket API就能使用Netlink提供的功能,而内核态则需要专门的内核API来使用Netlink。

在内核态中使用uevent事件通知用户空间。

用户空间只需创建一个socket描述符,然后将描述符绑定到接收地址就能够实现热拔插事件的监听了。


参考:http://blog.csdn.net/wuruixn/article/details/24960935

    http://blog.csdn.net/newnewman80/article/details/8766657

    http://blog.sina.com.cn/s/blog_5e99b41e0101bbo4.html

    http://www.cnblogs.com/oracleloyal/p/5333276.html

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
用户空间和内核空间通讯之Netlink
用户空间和内核空间通讯之【Netlink 下】
netlink socket 编程之 why & how - 内核源码 - ChinaUn...
2.6.24以上内核中netlink使用方法
简化版udev, 抓取uevent事件
netlink 套接字
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服