From c419b6f0cf6c29d886a4325c186bd3f821745abc Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Mon, 10 Aug 2020 11:19:22 +0100 Subject: [PATCH] dissect: wait for udev event if verity device not yet available The symlink /dev/mapper/dm_name is created by udev after a mapper device is set up. So libdevmapper/libcrypsetup might tell us that a verity device exists, but the symlink we use as the source for the mount operation might not be there yet. Instead of falling back to a new unique device set up, wait for the udev event matching on the expected devlink for at least 100ms (after which the benefits of sharing a device in terms of setup time start to disappear - on my production machines, opening a new verity device seems to take between 150ms and 300ms) --- src/shared/dissect-image.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 8cbf4828b8..48b98c4f2d 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1452,6 +1452,15 @@ static int verity_partition( if (!IN_SET(r, 0, -ENODEV, -ENOENT)) return log_debug_errno(r, "Checking whether existing verity device %s can be reused failed: %m", node); if (r == 0) { + /* devmapper might say that the device exists, but the devlink might not yet have been + * created. Check and wait for the udev event in that case. */ + r = device_wait_for_devlink(node, "block", 100 * USEC_PER_MSEC, NULL); + /* Fallback to activation with a unique device if it's taking too long */ + if (r == -ETIMEDOUT) + break; + if (r < 0) + return r; + if (cd) crypt_free(cd); cd = existing_cd; @@ -1461,10 +1470,6 @@ static int verity_partition( break; } - /* Sanity check: libdevmapper is known to report that the device already exists and is active, - * but it's actually not there, so the later filesystem probe or mount would fail. */ - if (r == 0) - r = access(node, F_OK); /* An existing verity device was reported by libcryptsetup/libdevmapper, but we can't use it at this time. * Fall back to activating it with a unique device name. */ if (r != 0 && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE))