9.2.1 Netlink和Uevent介绍
最后更新于:2022-04-02 05:53:12
在分析Vold的代码前,先介绍一下Linux系统中的Netlink和Uevent。
1. Netlink的介绍
Netlink是Linux系统中一种用户空间进程和Kernel进行通信的机制,通过这个机制,位于用户空间的进程,可接收来自Kernel的一些信息(例如Vold中用到的USB或SD的插拔消息),同时应用层也可通过Netlink向Kernel发送一些控制命令。
目前,Linux系统并没有为Netlink单独设计一套系统调用,而是复用了Socket的操作接口,只在创建Socket时会有一些特殊的地方。Netlink的具体使用方法,在进行代码分析时再来了解,读者目前只需知道,通过Netlink机制应用层,可接收来自Kernel的消息即可。
2. Uevent介绍
Uevent和Linux的Udev设备文件系统和设备模型有关系,它实际上就是一串字符串,字符串的内容可告知发生了什么事情。下面通过一个实例来直观感受Uevent:
在SD卡插入手机后(我们这里以SD卡为例),系统会检测到这个设备的插入,然后内核会通过Netlink发送一个消息给Vold,Vold将根据接收到的消息进行处理,例如挂载这个SD卡。内核发送的这个消息,就是Uevent,其中U代表User space(应用层空间)。下面看SD卡插入时Vold截获到的Uevent消息。在我的G7手机上,Uevent的内容如下,注意,其中//号或/**/号中的内容是为方便读者理解而加的注释:
**SD卡插入的Uevent消息**
~~~
//mmc表示MultiMedia Card,这里统称为SD卡
add@/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:c9f2/block/mmcblk0
ACTION=add //add表示设备插入,另外还有remove和change等动作
//DEVPATH表示该设备位于/sys目录中的设备路径
DEVPATH=/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:c9f2/block/mmcblk0
/*
SUBSYSTEM表示该设备属于哪一类设备,block为块设备,磁盘也属于这一类设备,另外还有
character(字符)设备等类型。
*/
SUBSYSTEM=block
MAJOR=179//MAJOR和MINOR分别表示该设备的主次设备号,二者联合起来可以标识一个设备
MINOR=0
DEVNAME=mmcblk0
DEVTYPE=disk//设备Type为disk
NPARTS=3 //这个表示该SD卡上的分区,我的SD卡上有三块分区
SEQNUM=1357//序号
~~~
由于我的SD卡上还有分区,所以还会接收到和分区相关的Uevent。简单看一下:
**SD卡插入后和分区相关的Uevent消息**
~~~
add@/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:c9f2/block/mmcblk0/mmcblk0p1
ACTION=add
//比上面那个DEVPATH多了一个mmcblk0p1
DEVPATH=/devices/platform/msm_sdcc.2/mmc_host/mmc1/mmc1:c9f2/block/mmcblk0/mmcblk0p1
SUBSYSTEM=block
MAJOR=179
MINOR=1
DEVNAME=mmcblk0p1
DEVTYPE=partition //设备类型变为partition,表示分区
PARTN=1
SEQNUM=1358
~~~
通过上面实例,我们和Uevent来了一次亲密接触,具体到Vold,也就是内核通过Uevent告知外部存储系统发生了哪些事情,那么Uevent在什么情况下会由Kernel发出呢?
- 当设备发生变化时,这会引起Kernel发送Uevent消息,例如设备的插入和拔出等。如果Vold在设备发生变化之前已经建立了Netlink IPC通信,那么Vold可以接收到这些Uevent消息。这种情况是由设备发生变化而触发的。
- 设备一般在/sys对应的目录下有一个叫uevent的文件,往该文件中写入指定的数据,也会触Kernel发送和该设备相关的Uevent消息,这是由应用层触发的。例如Vold启动时,会往这些uevent文件中写数据,通过这种方式促使内核发送Uevent消息,这样Vold就能得到这些设备的当前信息了。
根据上面介绍可知,Netlink和Uevent的目的,就是让Vold随时获悉外部存储系统的信息,这至关重要。我们总不会希望发生诸如SD卡都被拔了,而Vold却一无所知的情况吧?
';