[lxc-devel] [lxd/master] loop: retry on EBUSY

brauner on Github lxc-bot at linuxcontainers.org
Tue Nov 6 11:28:37 UTC 2018


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 487 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20181106/08fe721c/attachment.bin>
-------------- next part --------------
From 7d88564c6268dd89a8593a8b84ca64f6de749b03 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 6 Nov 2018 12:27:12 +0100
Subject: [PATCH] loop: retry on EBUSY

If a loop device gets stolen in between getting an fd for it and setting
it up let's retry for a bit.

Closes #5246.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_cgo.go | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/lxd/storage_cgo.go b/lxd/storage_cgo.go
index b0a3be5a17..50a322c631 100644
--- a/lxd/storage_cgo.go
+++ b/lxd/storage_cgo.go
@@ -191,7 +191,7 @@ on_error:
 	return fd_tmp;
 }
 
-int prepare_loop_dev(const char *source, char *loop_dev, int flags)
+static int prepare_loop_dev(const char *source, char *loop_dev, int flags)
 {
 	int ret;
 	struct loop_info64 lo64;
@@ -234,6 +234,19 @@ on_error:
 	return fd_loop;
 }
 
+static inline int prepare_loop_dev_retry(const char *source, char *loop_dev, int flags)
+{
+	int ret;
+	unsigned int idx = 0;
+
+	do {
+		ret = prepare_loop_dev(source, loop_dev, flags);
+		idx++;
+	} while (ret < 0 && errno == EBUSY && idx < 30);
+
+	return ret;
+}
+
 // Note that this does not guarantee to clear the loop device in time so that
 // find_associated_loop_device() will not report that there still is a
 // configured device (udev and so on...). So don't call
@@ -304,7 +317,7 @@ func prepareLoopDev(source string, flags int) (*os.File, error) {
 		return os.NewFile(uintptr(loopFd), C.GoString((*C.char)(cLoopDev))), nil
 	}
 
-	loopFd, err := C.prepare_loop_dev(cSource, (*C.char)(cLoopDev), C.int(flags))
+	loopFd, err := C.prepare_loop_dev_retry(cSource, (*C.char)(cLoopDev), C.int(flags))
 	if loopFd < 0 {
 		if err != nil {
 			return nil, fmt.Errorf("Failed to prepare loop device: %s", err)


More information about the lxc-devel mailing list