cryptsetup не может закрыть подключенное устройство

Когда я бегу:

LANG=C cryptsetup --debug luksClose /dev/mapper/Pool-A

it fails as follows:

    device-mapper: remove ioctl on Pool-A failed: Device or resource busy

Device /dev/mapper/Pool-A is still in use.
Command failed with code 16: Device or resource busy

(...) (повторяет много таких строк)

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

(...) (повторяет 25 строк)

# Releasing crypt device /dev/sdb1 context.
# Releasing device-mapper backend.
# Unlocking memory.


I've found that this problem arises when I tri to use udev rules like that:

ACTION=="add",ENV{ID_SERIAL_SHORT}=="57584E314135364632334141", RUN+="/etc/bacula/openmount.sh A" 
ACTION=="remove",ENV{ID_SERIAL_SHORT}=="57584E314135364632334141", RUN+="/etc/bacula/umountclose.sh A"

Это информация низкого уровня:

[root@backup ~]# dmsetup info Pool-A 
Name:              Pool-A
State:             ACTIVE
Read Ahead:        256
Tables present:    LIVE
Open count:        1
Event number:      0
Major, minor:      253, 3
Number of targets: 1
UUID: CRYPT-LUKS1-2b69b6e48b6d4bd1942ae7505d530f27-Pool-A

И информация об устройстве блока выглядит следующим образом:

    lsblk -o +UUID /dev/sdb
NAME       MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT UUID
sdb          8:16   0  1,8T  0 disk             
└─sdb1       8:17   0  1,8T  0 part             
  └─Pool-A 253:3    0  1,8T  0 crypt            48c1accf-47a6-45ec-aacc-6686e8a8a2fa

Моя ОС это:

CentOS Linux выпуск 7.2.1511 (Core) с ядром 3.10.0-327.36.3.el7.x86_64

Это проблема systemd-udev? Как я могу это исправить? Или это безобидное предупреждение?

1 ответ

В этом разница между systemd-udev и классическим udev. systemd-udev монтируется в отдельном пространстве имен, поэтому монтирования в сценариях RUN не будут видны пользователям. Можешь попробоватьsystemctl restart udevи если это снимет блокировку, это проблема. Чтобы сделать это правильно, вам придется работать в systemd. У меня работает следующее: правило udev для перехвата подключаемого USB-накопителя:

      ACTION=="add", KERNEL=="sd?1", ENV{ID_SERIAL_SHORT}=="575...", SYMLINK+="offsitebackup", TAG+="systemd", ENV{SYSTEMD_WANTS}+="offsite-backup.service"

При этом создается ссылка /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

Затем скрипт выполняет luksOpen/mount/copy/umount/luksClose. Кроме того, чтобы проверить это, вы можете смоделировать отключение/повторное подключение USB-накопителя с помощью:

      udevadm trigger -v -c remove /dev/sda
udevadm trigger -v -c add /dev/sda

и вы можете увидеть состояние устройства/скрипта в systemd, используя:

      systemctl status dev-offsitebackup.device
systemctl status offsite-backup.service

Две страницы, которые помогли во всем этом разобраться, находятся здесь и здесь.

Другие вопросы по тегам