diff --git a/lib/utils_device.c b/lib/utils_device.c index 860c8930..839f219f 100644 --- a/lib/utils_device.c +++ b/lib/utils_device.c @@ -178,6 +178,7 @@ static int device_ready(struct crypt_device *cd, struct device *device) int devfd = -1, r = 0; struct stat st; size_t tmp_size; + const char *dm_name; if (!device) return -EINVAL; @@ -188,7 +189,12 @@ static int device_ready(struct crypt_device *cd, struct device *device) device->o_direct = 0; devfd = open(device_path(device), O_RDONLY | O_DIRECT); if (devfd >= 0) { - if (device_read_test(devfd) == 0) { + /* skip check for suspended DM devices */ + dm_name = device_dm_name(device); + if (dm_name && dm_status_suspended(cd, dm_name)) { + close(devfd); + devfd = -1; + } else if (device_read_test(devfd) == 0) { device->o_direct = 1; } else { close(devfd); diff --git a/tests/compat-test2 b/tests/compat-test2 index aca2aeaf..7a770aee 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -1423,5 +1423,19 @@ if [ "$HAVE_BLKID" -gt 0 ]; then echo $PWD1 | $CRYPTSETUP -q --debug --disable-blkid luksFormat $FAST_PBKDF_OPT --type luks2 $HEADER_LUKS2_PV 2>&1 | grep -q "LVM2_member" && fail fi +prepare "[46] Init from suspended device" wipe +dmsetup create $DEV_NAME --table "0 39998 linear $LOOPDEV 2" || fail +echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 --header $HEADER_IMG /dev/mapper/$DEV_NAME || fail +echo $PWD1 | $CRYPTSETUP -q luksOpen --header $HEADER_IMG /dev/mapper/$DEV_NAME $DEV_NAME2 || fail +# underlying device now returns error but node is still present +dmsetup load $DEV_NAME --table "0 40000 error" || fail +dmsetup resume $DEV_NAME || fail +dmsetup suspend $DEV_NAME || fail +# status must print data even if data device is suspended +$CRYPTSETUP -q status --debug --header $HEADER_IMG $DEV_NAME2 | grep "type:" | grep -q "LUKS2" || fail +dmsetup resume $DEV_NAME || fail +$CRYPTSETUP -q luksClose $DEV_NAME2 || fail +dmsetup remove --retry $DEV_NAME || fail + remove_mapping exit 0