7

When I run:

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

(...) (It repeats a lot of lines like that)

# 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)

(...) (It repeats 25 lines alike)

# 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"

This the low level info:

[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

And block device info is as follows:

    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

My OS is:

CentOS Linux release 7.2.1511 (Core) with kernel 3.10.0-327.36.3.el7.x86_64

Is it a systemd-udev problem? How can I fix it? Or is that a innocuous warning?

sebelk
  • 682
  • 4
  • 13
  • 32

1 Answers1

0

This is a difference between systemd-udev and classic udev. systemd-udev mounts in a separate namespace, so mounts in RUN scripts won't be visible to users. You can try systemctl restart udev and if that releases the lock, it's the issue. To do this correctly, you'll have to work within systemd. What's working for me is the following: a udev rule to catch the USB drive being plugged in:

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

This creates a /dev/offsitebackup link pointing to the first partition of the drive and triggers the service. The service file is:

[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

The script then does luksOpen/mount/copy/umount/luksClose. Additionally, to test these out, you can simulate unplug/replug of the USB drive with:

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

and you can see device/script state within systemd using:

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

Two pages that helped to figure this all out are here and here.