粗略看了一下 linux 下虚拟磁盘实现方式,与 windows 实现方式来个简单对比。
1 实现原理
两者实现原理相同的,说明万物不离其宗,大家都是实现电子操作的工具而已: 用文件模
拟硬盘,当然也可以使用内存,网络,串口,并口等所有可以实现的方式。
两者也有不同点:
a Windows 磁盘驱动实现了转接口,上层(up interface)实现磁盘的操作接口,下层(down
interface)实现文件的操作。类似 usb 实现方式,不过 usb 是逻辑上分为了两个模块。(当
然使用文件方式虚拟磁盘的也可以分为两种模块:一个 sys 实现 up 接口,一个 sys 实现
down 接口,两个 sys 之间实现 stack 上的有序排列和数据交互,共享内存即可)
主要接口函数和流程:
DriverEntry->Dispatch-> 每 个 虚 拟 磁 盘
的 Thread->ZwWrite/ZwRead->Encrypto/Decrypto->ZwClose
Windows 操作大家都很熟悉,这里不再累赘,具体可以参考 filedisk(比较简单明了)或者
truecypto(相对成熟).
b Linux 实现方法有些不同,它是通过 dm_register_type 注册一个 target_type 类型,该类
型是用户定义的,如 cyliu_type, 由 name 来保存类型名称。dm(device map)驱动是磁
盘驱动类的框架接口,通过 bio 接口实现对磁盘的读写操作,由于再 linux 中设备也是当作
文件操作,因此可以说对应用来说都是对文件系统的操作,那么 linux 系统的文件系统框架
就具有很好的扩展性和通用性。
Device mapper 在内核中向外提供了一个从逻辑设备到物理设备的映射架构,只要用户在
用户空间制定好映射策略,按照自己的需要编写处理具体 IO 请求的 target driver 插件,就
可以很方便的实现一个类似 LVM 的逻辑卷管理器。Device mapper 以 ioctl 的方式向外提供
接口,用户通过用户空间的 device mapper 库,向 device mapper 的字符设备发送 ioctl 命
令,完成向内的通信。它还通过 ioctl 提供向往的事件通知机制,允许 target driver 将 IO 相
关的某些事件传送到用户空间。 因此 linux 实现虚拟磁盘比较简单,只需要对数据加密/解
密即可,其他操作都有 linux 的驱动完成。
mapped_device 结构用于表示 mapped device,它主要包括该 mapped device 相关的锁,
注册的请求队列和一些内存池以及指向它所对应映射表的指针等域。Mapped device 对应
的映射表是由 dm_table 结构表示的,该结构中包含一个 dm_target 结构数组,dm_target
结构具体描述了 mapped_device 到它某个 target device 的映射关系.
struct mapped_device {
struct rw_semaphore io_lock;
struct semaphore suspend_lock;