Skip to content

"cryptsetup resize" hangs for several minutes

Issue description

Hello, I use the "LUKS on LVM" setup - a LUKS container is created for every individual LV. When I extend the volume, I encounter the situation when the extension of the LUKS device can take minutes. However, the extension of the underlying LV is always very quick. After digging into it, I observed that the "dm resume" stage hangs until all dirty pages are flushed. It can be a coincidence, but it's the only correlation I found. Also, the debug output says dm resume test-resize_crypt [ opencount flush ], which also mentions "flush".

Can you help me understand

  1. Why does it take so long to resize?
  2. Why is the "dm resume" required while the device is ACTIVE (not suspended)?
  3. (assuming it's because of flush) Is this flush required? Can it be safely omitted?

Looking forward to your help. Thank you!

Steps for reproducing the issue

  1. Create LV: lvcreate --size 400G -n test-resize vg-data
  2. Create LUKS: echo -n 'test' | cryptsetup -v luksFormat --type luks2 /dev/vg-data/test-resize -
  3. Open LUKS: echo -n 'test' | cryptsetup luksOpen /dev/vg-data/test-resize -
  4. Create FS: mkfs.ext4 /dev/mapper/test-resize_crypt
  5. Mount FS:
cd /tmp/
mkdir -p test-resize
mount /dev/mapper/test-resize_crypt test-resize

Then I run fio from inside a docker container with a mounted test-resize directory.

fio  --name=global -rw=randwrite --size=3g --name=job1 --numjobs 110  --time_based --runtime=10

After it finishes, there are a lot of dirty pages, and the kernel actively flushes them.

While the flush is happening, try to extend the volume:

  1. Extend LV: lvextend --verbose --size +1G /dev/vg-data/test-resize
  2. Extend LUKS: echo -n 'test' | cryptsetup -v --debug resize /dev/mapper/test-resize_crypt -

The last step always hangs after dm resume test-resize_crypt [ opencount flush ] [16384] (*1).

When I run the cryptsetup resize under strace --tT -ff, I can always see the same long-running syscall:

12:50:32 ioctl(3, DM_DEV_SUSPEND, {version=4.0.0, data_size=16384, name="test-resize_crypt", event_nr=6296210, flags=DM_EXISTS_FLAG} => {version=4.47.0, data_size=305, dev=makedev(0xfe, 0x1), name="test-resize_crypt", uuid="CRYPT-LUKS2-4018353329e44be09b21f54f74a2fd6f-test-resize_crypt", target_count=1, open_count=1, event_nr=0, flags=DM_EXISTS_FLAG|DM_ACTIVE_PRESENT_FLAG|DM_UEVENT_GENERATED_FLAG}) = 0 <303.679976>

The existing dirty pages I checked like this

grep Dirty /proc/meminfo

Additional info

# uname -a
Linux my-host 6.1.30-4 #1 SMP Wed Jul  5 22:36:53 UTC 2023 x86_64 GNU/Linux
#
# cryptsetup --version
cryptsetup 2.3.7
#
# dmsetup --version
Library version:   1.02.175 (2021-01-08)
Driver version:    4.47.0

I also tested this scenario on

  • Debian 5.10
  • crytpsetup 2.6.1
  • LUKS1 and LUKS2

The behavior is the same.

I also tested the volume extension without LUKS (LV + FS) - the extension is very quick.

Debug log

# echo -n 'test' | cryptsetup -v --debug resize  /dev/mapper/test-resize_crypt -
# cryptsetup 2.3.7 processing "cryptsetup -v --debug resize /dev/mapper/test-resize_crypt -"
# Running command resize.
# Locking memory.
# Installing SIGINT/SIGTERM handler.
# Unblocking interruption on signal.
# Allocating crypt device context by device /dev/mapper/test-resize_crypt.
# Initialising device-mapper backend library.
# dm version   [ opencount flush ]   [16384] (*1)
# dm versions   [ opencount flush ]   [16384] (*1)
# Detected dm-ioctl version 4.47.0.
# Detected dm-integrity version 1.10.0.
# Detected dm-crypt version 1.24.0.
# Device-mapper backend running with UDEV support enabled.
# dm status test-resize_crypt  [ opencount noflush ]   [16384] (*1)
# Releasing device-mapper backend.
# Trying to open and read device /dev/mapper/vg--data-test--resize with direct-io.
# Allocating context for crypt device /dev/mapper/vg--data-test--resize.
# Trying to open and read device /dev/mapper/vg--data-test--resize with direct-io.
# Initialising device-mapper backend library.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm table test-resize_crypt  [ opencount flush securedata ]   [16384] (*1)
# dm status   (254:0) [ opencount noflush ]   [16384] (*1)
# Trying to open and read device /dev/mapper/vg--data-test--resize with direct-io.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm deps test-resize_crypt  [ opencount flush ]   [16384] (*1)
# dm table vg--data-test--resize  [ opencount flush securedata ]   [16384] (*1)
# Crypto backend (OpenSSL 1.1.1n  15 Mar 2022) initialized in cryptsetup library version 2.3.7.
# Detected kernel Linux 6.1.30-4 x86_64.
# Reloading LUKS2 header (repair disabled).
# Acquiring read lock for device /dev/mapper/vg--data-test--resize.
# Opening lock resource file /run/cryptsetup/L_254:0
# Verifying lock handle for /dev/mapper/vg--data-test--resize.
# Device /dev/mapper/vg--data-test--resize READ lock taken.
# Trying to read primary LUKS2 header at offset 0x0.
# Opening locked device /dev/mapper/vg--data-test--resize
# Veryfing locked device handle (bdev)
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:60af4ff804667ea245188ff933de6421e5e0f3c46ee83e14cb9fc27b73bcaf03 (on-disk)
# Checksum:60af4ff804667ea245188ff933de6421e5e0f3c46ee83e14cb9fc27b73bcaf03 (in-memory)
# Trying to read secondary LUKS2 header at offset 0x4000.
# Reusing open ro fd on device /dev/mapper/vg--data-test--resize
# LUKS2 header version 2 of size 16384 bytes, checksum sha256.
# Checksum:613a734c3d539f38c620935581981a08d88d9e2fd9dc5c78aac0bdf417a1d00c (on-disk)
# Checksum:613a734c3d539f38c620935581981a08d88d9e2fd9dc5c78aac0bdf417a1d00c (in-memory)
# Device size 432717955072, offset 16777216.
# Device /dev/mapper/vg--data-test--resize READ lock released.
# PBKDF argon2i, time_ms 2000 (iterations 0), max_memory_kb 1048576, parallel_threads 4.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm table test-resize_crypt  [ opencount flush securedata ]   [16384] (*1)
# dm status   (254:0) [ opencount noflush ]   [16384] (*1)
# Trying to open and read device /dev/mapper/vg--data-test--resize with direct-io.
# Checking volume passphrase using token -1.
# STDIN descriptor passphrase entry requested.
# Checking volume passphrase [keyslot -1] using passphrase.
# Keyslot 0 priority 1 != 2 (required), skipped.
# Trying to open LUKS2 keyslot 0.
# Reading keyslot area [0x8000].
# Acquiring read lock for device /dev/mapper/vg--data-test--resize.
# Opening lock resource file /run/cryptsetup/L_254:0
# Verifying lock handle for /dev/mapper/vg--data-test--resize.
# Device /dev/mapper/vg--data-test--resize READ lock taken.
# Reusing open ro fd on device /dev/mapper/vg--data-test--resize
# Device /dev/mapper/vg--data-test--resize READ lock released.
# Verifying key from keyslot 0, digest 0.
# Loading key (64 bytes, type logon) in thread keyring.
Key slot 0 unlocked.
# Resizing device /dev/mapper/test-resize_crypt to 0 sectors.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm table test-resize_crypt  [ opencount flush securedata ]   [16384] (*1)
# Calculated device size is 845119488 sectors (RW), offset 32768.
# dm versions   [ opencount flush ]   [16384] (*1)
# dm table test-resize_crypt  [ opencount flush securedata ]   [16384] (*1)
# dm status   (254:0) [ opencount noflush ]   [16384] (*1)
# Trying to open and read device /dev/mapper/vg--data-test--resize with direct-io.
# Calculated device size is 845119488 sectors (RW), offset 32768.
# dm reload test-resize_crypt  [ opencount flush securedata ]   [16384] (*1)
# Udev cookie 0xd4dfb68 (semid 32801) created
# Udev cookie 0xd4dfb68 (semid 32801) incremented to 1
# Udev cookie 0xd4dfb68 (semid 32801) incremented to 2
# Udev cookie 0xd4dfb68 (semid 32801) assigned to RESUME task(5) with flags DISABLE_LIBRARY_FALLBACK         (0x20)
# dm resume test-resize_crypt  [ opencount flush ]   [16384] (*1)


# test-resize_crypt: Stacking NODE_ADD (254,1) 0:6 0660 [trust_udev]
# Udev cookie 0xd4dfb68 (semid 32801) decremented to 1
# Udev cookie 0xd4dfb68 (semid 32801) waiting for zero
# Udev cookie 0xd4dfb68 (semid 32801) destroyed
# test-resize_crypt: Skipping NODE_ADD (254,1) 0:6 0660 [trust_udev]
# Releasing crypt device /dev/mapper/vg--data-test--resize context.
# Releasing device-mapper backend.
# Closing read only fd for /dev/mapper/vg--data-test--resize.
# Unlocking memory.
Command successful.
Edited by Ivan Shibitov