Skip to content

Commit

Permalink
shared/loop-util: use longer delay when waiting for loop device
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
keszybz committed May 30, 2023
1 parent 5097077 commit afbe20b
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/shared/loop-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit afbe20b

Please sign in to comment.