From afbe20b7d4ed4c3aebbd1b3de00b9b7385dd0ae8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 30 May 2023 00:20:30 +0200 Subject: [PATCH] shared/loop-util: use longer delay when waiting for loop device The kernel may be syncing a file system or doing something else that requires more time. So make the delay a bit longer, but provide some feedback and also grow the delay exponentially (though with a long exponent). If the kernel is doing something else, no need to repeat so often. With 38 attempts, we get a total of slightly above 5000 ms. I wrote this when I thought that the the delay is not long enough. It turned out that we were blocking the file system on the loop device, so waiting longer wasn't helpful. But I think it's nicer to do it this way anyway. --- src/shared/loop-util.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index a85cff09142..5418871093d 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -817,16 +817,24 @@ static LoopDevice* loop_device_free(LoopDevice *d) { } /* Now that the block device is released, let's also try to remove it */ - if (control >= 0) - for (unsigned n_attempts = 0;;) { + if (control >= 0) { + useconds_t delay = 5 * USEC_PER_MSEC; + + for (unsigned attempt = 1;; attempt++) { if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0) break; - if (errno != EBUSY || ++n_attempts >= 64) { + if (errno != EBUSY || attempt > 38) { log_debug_errno(errno, "Failed to remove device %s: %m", strna(d->node)); break; } - (void) usleep(50 * USEC_PER_MSEC); + if (attempt % 5 == 0) { + log_debug("Device is still busy after %u attempts…", attempt); + delay *= 2; + } + + (void) usleep(delay); } + } free(d->node); sd_device_unref(d->dev); -- 2.47.3