From d48314d4264ace0dd8e92ee73c6716deeeba51fb Mon Sep 17 00:00:00 2001 From: Kai Lueke Date: Fri, 6 Aug 2021 13:06:56 +0200 Subject: [PATCH] platform/qemu: retry if OEM btrfs filesystem is in use The OEM partition can't be mounted more than once when it's a btrfs filesystem, because having the same UUID is reserved for RAID usage. When two kola instances run at the same time there is a possibility for a race when both shortly want to use the OEM partition. Use a conditional retry waiter to wait for exclusive access, giving up after 10 minutes. --- platform/qemu.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/qemu.go b/platform/qemu.go index 150357cde..61b84b29e 100644 --- a/platform/qemu.go +++ b/platform/qemu.go @@ -19,6 +19,7 @@ import ( "fmt" "io/ioutil" "os" + origExec "os/exec" "path/filepath" "regexp" "runtime" @@ -125,11 +126,20 @@ func MakeCLDiskTemplate(inputPath string) (output *os.File, result error) { return nil, fmt.Errorf("failed to get loop device %s: %v", oemdev, err) } - // mount OEM partition - err = util.Retry(10, 100*time.Millisecond, func() error { + // mount OEM partition, wait for exclusive access to the file system in case some other process also mounted an identical OEM btrfs filesystem + err = util.RetryConditional(600, 1000*time.Millisecond, func(err error) bool { + if exitCode, ok := err.(*origExec.ExitError); ok && exitCode.ProcessState.ExitCode() == 32 { + plog.Noticef("waiting for exclusive access to the OEM btrfs filesystem") + return true + } + return false + }, func() error { return exec.Command("mount", oemdev, tmpdir).Run() }) if err != nil { + if exitCode, ok := err.(*origExec.ExitError); ok && exitCode.ProcessState.ExitCode() == 32 { + return nil, fmt.Errorf("timed out waiting to mount the OEM btrfs filesystem exclusively from %s on %s: %v", oemdev, tmpdir, err) + } return nil, fmt.Errorf("mounting OEM partition %s on %s: %v", oemdev, tmpdir, err) } defer func() {