cryptsetup 无法关闭映射设备

seb*_*elk 8 disk-encryption udevd luks systemd device-mapper

当我跑步时:

\n\n
LANG=C cryptsetup --debug luksClose /dev/mapper/Pool-A\n\nit fails as follows:\n\n    device-mapper: remove ioctl on Pool-A failed: Device or resource busy\n\nDevice /dev/mapper/Pool-A is still in use.\nCommand failed with code 16: Device or resource busy\n
Run Code Online (Sandbox Code Playgroud)\n\n

(...)(重复了很多这样的台词)

\n\n
# cryptsetup 1.7.2 processing "cryptsetup --debug luksClose /dev/mapper/Pool-A"\n# Running command close.\n# Locking memory.\n# Installing SIGINT/SIGTERM handler.\n# Unblocking interruption on signal.\n# Allocating crypt device context by device /dev/mapper/Pool-A.\n# Initialising device-mapper backend library.\n# dm version   OF   [16384] (*1)\n# dm versions   OF   [16384] (*1)\n# Detected dm-crypt version 1.14.1, dm-ioctl version 4.33.0.\n# Device-mapper backend running with UDEV support enabled.\n# dm status Pool-A  OF   [16384] (*1)\n# Releasing device-mapper backend.\n# Trying to open and read device /dev/sdb1 with direct-io.\n# Allocating crypt device /dev/sdb1 context.\n# Trying to open and read device /dev/sdb1 with direct-io.\n# Initialising device-mapper backend library.\n# dm table Pool-A  OFW    [16384] (*1)\n# Trying to open and read device /dev/sdb1 with direct-io.\n# Crypto backend (gcrypt 1.5.3) initialized in cryptsetup library version 1.7.2.\n# Detected kernel Linux 3.10.0-327.36.3.el7.x86_64 x86_64.\n# Reading LUKS header of size 1024 from device /dev/sdb1\n# Key length 32, device size 3906961375 sectors, header size 2050 sectors.\n# Deactivating volume /dev/mapper/Pool-A.\n# dm status Pool-A  OF   [16384] (*1)\n# Udev cookie 0xd4d14d3 (semid 917504) created\n# Udev cookie 0xd4d14d3 (semid 917504) incremented to 1\n# Udev cookie 0xd4d14d3 (semid 917504) incremented to 2\n# Udev cookie 0xd4d14d3 (semid 917504) assigned to REMOVE task(2) with flags         (0x0)\n# dm remove Pool-A  OFT    [16384] (*1)\n
Run Code Online (Sandbox Code Playgroud)\n\n

(...)(同样重复 25 行)

\n\n
# Releasing crypt device /dev/sdb1 context.\n# Releasing device-mapper backend.\n# Unlocking memory.\n\n\nI\'ve found that this problem arises when I tri to use udev rules like that:\n\nACTION=="add",ENV{ID_SERIAL_SHORT}=="57584E314135364632334141", RUN+="/etc/bacula/openmount.sh A" \nACTION=="remove",ENV{ID_SERIAL_SHORT}=="57584E314135364632334141", RUN+="/etc/bacula/umountclose.sh A"\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是低级信息:

\n\n
[root@backup ~]# dmsetup info Pool-A \nName:              Pool-A\nState:             ACTIVE\nRead Ahead:        256\nTables present:    LIVE\nOpen count:        1\nEvent number:      0\nMajor, minor:      253, 3\nNumber of targets: 1\nUUID: CRYPT-LUKS1-2b69b6e48b6d4bd1942ae7505d530f27-Pool-A\n
Run Code Online (Sandbox Code Playgroud)\n\n

块设备信息如下:

\n\n
    lsblk -o +UUID /dev/sdb\nNAME       MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT UUID\nsdb          8:16   0  1,8T  0 disk             \n\xe2\x94\x94\xe2\x94\x80sdb1       8:17   0  1,8T  0 part             \n  \xe2\x94\x94\xe2\x94\x80Pool-A 253:3    0  1,8T  0 crypt            48c1accf-47a6-45ec-aacc-6686e8a8a2fa\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的操作系统是:

\n\n

CentOS Linux 版本 7.2.1511(核心),内核为 3.10.0-327.36.3.el7.x86_64

\n\n

是 systemd-udev 问题吗?我该如何修复它?或者这是一个无害的警告?

\n

小智 1

这是 systemd-udev 和经典 udev 之间的区别。systemd-udev 挂载在单独的命名空间中,因此 RUN 脚本中的挂载对用户不可见。你可以尝试一下systemctl restart udev,如果锁被释放了,那就是问题所在了。要正确执行此操作,您必须在 systemd 中工作。对我有用的是以下内容:用于捕获插入的 USB 驱动器的 udev 规则:

ACTION=="add", KERNEL=="sd?1", ENV{ID_SERIAL_SHORT}=="575...", SYMLINK+="offsitebackup", TAG+="systemd", ENV{SYSTEMD_WANTS}+="offsite-backup.service"
Run Code Online (Sandbox Code Playgroud)

这将创建一个指向驱动器第一个分区的 /dev/offsitebackup 链接并触发该服务。服务文件是:

[Unit]
Description=Offsite Backup script
Requisite=dev-offsitebackup.device
BindsTo=dev-offsitebackup.device
After=dev-offsitebackup.device

[Service]
ExecStart=/usr/local/scripts/offsite-backup.ksh offsitebackup
Type=oneshot
StandardOutput=journal

[Install]
WantedBy=dev-offsitebackup.device
Run Code Online (Sandbox Code Playgroud)

然后该脚本执行 luksOpen/mount/copy/umount/luksClose。此外,要测试这些,您可以使用以下命令模拟拔出/重新插入 USB 驱动器:

udevadm trigger -v -c remove /dev/sda
udevadm trigger -v -c add /dev/sda
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令查看 systemd 中的设备/脚本状态:

systemctl status dev-offsitebackup.device
systemctl status offsite-backup.service
Run Code Online (Sandbox Code Playgroud)

这里这里有两页帮助解决了这个问题。