blob: 5126074fe02034ef9984ba40443ef7037abe4417 [file] [log] [blame]
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Workaround for qemu-img bug on arm64 platforms with multiple cores.
Runs qemu-img command with timeout and retries the command if it hangs.
See: QEMU is out of date; current version of qemu-img
is unstable qemu-img hangs on
rcu_call_ready_event logic in Aarch64 when converting images
TODO( Remove this workaround when the bug is fixed.
import logging
import subprocess
import time
# qemu-img p99 run time on Cavium ThunderX2 servers is 26 seconds.
# Using 2x the p99 time as the timeout.
def _ExecQemuImgWithTimeout(command):
"""Execute qemu-img command in subprocess with timeout.
Returns: None if command timed out or return code if command completed.
"""'qemu-img starting')
p = subprocess.Popen(command)
start_sec = time.time()
while p.poll() is None and time.time() - start_sec < QEMU_IMG_TIMEOUT_SEC:
stop_sec = time.time()'qemu-img duration: %f' % float(stop_sec - start_sec))
if p.poll() is None:
return None
return p.returncode
def ExecQemuImgWithRetry(command):
""" Execute qemu-img command in subprocess with 2 retries.
Raises CalledProcessError if command does not complete successfully.
tries = 0
status = None
while status is None and tries <= 2:
tries += 1
status = _ExecQemuImgWithTimeout(command)
if status is None:
raise subprocess.CalledProcessError(-1, command)
if status:
raise subprocess.CalledProcessError(status, command)