From: Yu Watanabe Date: Sat, 17 Sep 2022 00:01:46 +0000 (+0900) Subject: dissect-image: free crypt_device object before trying to activate with unique name X-Git-Tag: v252-rc1~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f75b0c589f6ad75dc9d669f60f3f7cf3e011c87;p=thirdparty%2Fsystemd.git dissect-image: free crypt_device object before trying to activate with unique name Otherwise we get error from libcryptsetup like the following: systemd[1234]: Cannot use device /dev/loop5 which is in use (already mapped or mounted). --- diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 5e4883a7a7c..ec7b5e95161 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -1979,7 +1979,7 @@ static int verity_partition( * Improvements in libcrypsetup can ensure this never happens: * https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/96 */ if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)) - return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d); + break; if (r < 0 && !IN_SET(r, -EEXIST, /* Volume is already open and ready to be used */ -EBUSY, /* Volume is being opened but not ready, crypt_init_by_name can fetch details */ @@ -2004,7 +2004,7 @@ static int verity_partition( r = verity_can_reuse(verity, name, &existing_cd); /* Same as above, -EINVAL can randomly happen when it actually means -EEXIST */ if (r == -EINVAL && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)) - return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d); + break; if (r < 0 && !IN_SET(r, -ENODEV, -ENOENT, -EBUSY)) return log_debug_errno(r, "Checking whether existing verity device %s can be reused failed: %m", node); if (r >= 0) { @@ -2012,7 +2012,7 @@ static int verity_partition( * created. Check and wait for the udev event in that case. */ r = device_wait_for_devlink(node, "block", verity_timeout(), NULL); /* Fallback to activation with a unique device if it's taking too long */ - if (r == -ETIMEDOUT) + if (r == -ETIMEDOUT && FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)) break; if (r < 0) return r; @@ -2027,9 +2027,18 @@ static int verity_partition( (void) usleep(2 * USEC_PER_MSEC); } - /* All trials failed. Let's try to activate with a unique name. */ - if (FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)) + /* All trials failed or a conflicting verity device exists. Let's try to activate with a unique name. */ + if (FLAGS_SET(flags, DISSECT_IMAGE_VERITY_SHARE)) { + /* Before trying to activate with unique name, we need to free crypt_device object. + * Otherwise, we get error from libcryptsetup like the following: + * ------ + * systemd[1234]: Cannot use device /dev/loop5 which is in use (already mapped or mounted). + * ------ + */ + sym_crypt_free(cd); + cd = NULL; return verity_partition(designator, m, v, verity, flags & ~DISSECT_IMAGE_VERITY_SHARE, d); + } return log_debug_errno(SYNTHETIC_ERRNO(EBUSY), "All attempts to activate verity device %s failed.", name);