我有一个加密分区,我想在插入包含密钥的 USB 记忆棒时自动挂载该分区,并且我想在拔出 USB 记忆棒时卸载该分区(并关闭映射器)。我正在使用 Ubuntu Karmic。
似乎有几个项目尝试对 TrueCrypt 进行此操作(例如, http://sourceforge.net/projects/tc-wrapper/),但没有基于 dmcrypt/LUKS 的东西。所以我想试试写一个 udev 规则。经过许多令人沮丧的几个小时,我想出了这个:
ACTION=="add", SUBSYSTEM=="block", ATTRS{model}=="Flash Disk", ATTRS{vendor}=="USB2.0", RUN+="/home/michael/trigger-mount.sh encrypted"
ACTION=="remove", SUBSYSTEM=="block", ENV{ID_VENDOR_ID}=="0204", ENV{ID_MODEL_ID}=="6025", RUN+="/home/michael/trigger-mount.sh encrypted"
它可以工作,但效果并不好。这里的问题是,第一条规则在删除时不匹配,第二条规则在添加时不匹配。
udevadm monitor --property
显示这一点(和“添加”上几乎相同的内容)。
UDEV [1264556064.762870] remove /devices/pci0000:00/0000:00:02.0/usb2/2-4/2-4:1.0/host47/target47:0:0/47:0:0:0/block/sde (block)
UDEV_LOG=3
ACTION=remove
DEVPATH=/devices/pci0000:00/0000:00:02.0/usb2/2-4/2-4:1.0/host47/target47:0:0/47:0:0:0/block/sde
SUBSYSTEM=block
DEVNAME=/dev/sde
DEVTYPE=disk
SEQNUM=3512
ID_VENDOR=USB2.0
ID_VENDOR_ENC=USB2.0\x20\x20
ID_VENDOR_ID=0204
ID_MODEL=Flash_Disk
ID_MODEL_ENC=Flash\x20Disk\x20\x20\x20\x20\x20\x20
ID_MODEL_ID=6025
ID_REVISION=2.00
ID_SERIAL=USB2.0_Flash_Disk-0:0
ID_TYPE=disk
ID_INSTANCE=0:0
ID_BUS=usb
ID_USB_INTERFACES=:080650:
ID_USB_INTERFACE_NUM=00
ID_USB_DRIVER=usb-storage
ID_PATH=pci-0000:00:02.0-usb-0:4:1.0-scsi-0:0:0:0
DKD_MEDIA_AVAILABLE=1
DKD_PRESENTATION_NOPOLICY=0
MAJOR=8
MINOR=64
DEVLINKS=/dev/block/8:64 /dev/disk/by-id/usb-USB2.0_Flash_Disk-0:0 /dev/disk/by-path/pci-0000:00:02.0-usb-0:4:1.0-scsi-0:0:0:0
这似乎包含了在两种情况下(添加、删除)匹配两个规则所需的所有数据。
为了完整起见,这里是输出udevadm info -a -p /sys/block/sde/
:
looking at device '/devices/pci0000:00/0000:00:02.0/usb2/2-4/2-4:1.0/host48/target48:0:0/48:0:0:0/block/sde':
KERNEL=="sde"
SUBSYSTEM=="block"
DRIVER==""
ATTR{range}=="16"
ATTR{ext_range}=="256"
ATTR{removable}=="1"
ATTR{ro}=="0"
ATTR{size}=="512000"
ATTR{alignment_offset}=="0"
ATTR{capability}=="53"
ATTR{stat}==" 16 47 504 510 0 0 0 0 0 380 510"
looking at parent device '/devices/pci0000:00/0000:00:02.0/usb2/2-4/2-4:1.0/host48/target48:0:0/48:0:0:0':
KERNELS=="48:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{device_blocked}=="0"
ATTRS{type}=="0"
ATTRS{scsi_level}=="3"
ATTRS{vendor}=="USB2.0 "
ATTRS{model}=="Flash Disk "
ATTRS{rev}=="2.00"
ATTRS{state}=="running"
ATTRS{timeout}=="30"
ATTRS{iocounterbits}=="32"
ATTRS{iorequest_cnt}=="0x41"
ATTRS{iodone_cnt}=="0x41"
ATTRS{ioerr_cnt}=="0x0"
ATTRS{modalias}=="scsi:t-0x00"
ATTRS{evt_media_change}=="0"
ATTRS{queue_depth}=="1"
ATTRS{queue_type}=="none"
ATTRS{max_sectors}=="240"
....
有人可以解释一下这个问题吗?
答案1
我写了一些关于使用 udev 作为自动挂载程序的信息先前的答案;它(或它链接到的资源)可能会给你提供一些启发。
我不清楚你的问题到底是什么
关于单独的添加和删除规则:如果你放弃行动匹配,但这可能会导致规则触发过于频繁。我认为最好明确匹配每条规则。或者更好的是(出于在卸载部分),删除“消除”统治。
关于跑步uDev 规则中的操作:这跑步uDev 规则中的操作需要完成迅速地。看看我链接的例子;你会发现有二脚本——uDev 调用一个脚本,然后另一个脚本会分拆出来执行实际的挂载,从而允许第一个脚本及时将处理控制权返回给 uDev。如果您已经这样做了,那很好;如果没有,请考虑以类似的方式调整您的脚本。
关于卸载:我在设备移除时自动卸载方面遇到了很多麻烦,最终我决定不是使用“消除”规则。相反,我编写了一个单独的卸载程序脚本来替换“消除”规则。
这是因为在物理移除设备之前,您确实应该给操作系统足够的时间来关闭设备。如果您以只读方式挂载了文件系统,那么移除驱动器是一回事,但只要有可能,就应该彻底卸载完整的读写文件系统。(这就是 Windows 中的“安全移除驱动器”选项的作用——它是一种卸载驱动器的机制前设备从系统中物理移除。)
使用常规文件系统,我能够通过sync
在挂载时使用选项和umount -l
在卸载时使用(延迟卸载)来“正确”地完成一些卸载。延迟卸载会告诉内核立即分离文件系统,但稍后在文件系统不再繁忙时清理对文件系统的引用。这种方法可行,但对数据而言不如完全卸载安全前删除设备。
出于同样的原因,您可能无法使延迟卸载与加密文件系统配合使用。设备映射器在标准文件系统问题之上又增加了一层复杂性。在我看来,这会使加密文件系统对不干净的卸载更加敏感。(不过,我对加密文件系统不是很有经验,所以他们可能能够容忍它。)
希望这能给你一些指引。坦白地说,对于自动挂载来说,uDev 是可行的,但并不理想。HalEvt 守护进程或者较新的 DeviceKit 可能更合适。