aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/runqemu
diff options
context:
space:
mode:
authorChen Qi <Qi.Chen@windriver.com>2018-06-07 15:52:46 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-06-18 10:59:33 +0100
commit02709d4709c56f9b9095e3555da35b659b03a8a3 (patch)
tree55deb9ea52d75d0193c407a21d01020f90de0e3f /scripts/runqemu
parent461c305078c40fca8b5382e393e3e8513d4abfa4 (diff)
downloadopenembedded-core-contrib-02709d4709c56f9b9095e3555da35b659b03a8a3.tar.gz
runqemu: add SIGTERM handler to make sure things are cleaned up
Add SIGTERM handler so that runqemu could clean things up correctly when receving such signal. This problem was originally observed when running testimage. On some hosts, after running testimage task, the user has to manually operate on the tap interface (e.g. `sudo ip link del tap0') in order for the next runqemu command to launch successfully. The problem is about runqemu, SIGTERM and network manager on the host. In testimage task, the runqemu process will receive SIGTERM. In such situation, its cleanup() function is not run, resulting in tap interface not cleaned up. On some hosts, the network manager will bring down the tap interface automatically, thus this problem. I saw this problem on Fedora21. I think we'd better just clean up the tap interface ourselves. So this patch adds to runqemu a SIGTERM handler, in which the actual qemu process is terminated and other things cleaned up. Signed-off-by: Chen Qi <Qi.Chen@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/runqemu')
-rwxr-xr-xscripts/runqemu23
1 files changed, 22 insertions, 1 deletions
diff --git a/scripts/runqemu b/scripts/runqemu
index d998494063a..de42d0f3231 100755
--- a/scripts/runqemu
+++ b/scripts/runqemu
@@ -27,6 +27,7 @@ import fcntl
import shutil
import glob
import configparser
+import signal
class RunQemuError(Exception):
"""Custom exception to raise on known errors."""
@@ -233,6 +234,10 @@ class BaseConfig(object):
# slirp qemus are running.
self.mac_tap = "52:54:00:12:34:"
self.mac_slirp = "52:54:00:12:35:"
+ # pid of the actual qemu process
+ self.qemupid = None
+ # avoid cleanup twice
+ self.cleaned = False
def acquire_lock(self, error=True):
logger.debug("Acquiring lockfile %s..." % self.lock)
@@ -1200,10 +1205,18 @@ class BaseConfig(object):
cmd = "%s %s" % (self.qemu_opt, kernel_opts)
logger.info('Running %s\n' % cmd)
process = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
+ self.qemupid = process.pid
if process.wait():
logger.error("Failed to run qemu: %s", process.stderr.read().decode())
def cleanup(self):
+ if self.cleaned:
+ return
+
+ # avoid dealing with SIGTERM when cleanup function is running
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+
+ logger.info("Cleaning up")
if self.cleantap:
cmd = 'sudo %s %s %s' % (self.qemuifdown, self.tap, self.bindir_native)
logger.debug('Running %s' % cmd)
@@ -1227,6 +1240,8 @@ class BaseConfig(object):
shutil.rmtree(self.rootfs)
shutil.rmtree('%s.pseudo_state' % self.rootfs)
+ self.cleaned = True
+
def load_bitbake_env(self, mach=None):
if self.bitbake_e:
return
@@ -1282,6 +1297,13 @@ def main():
return 0
try:
config = BaseConfig()
+
+ def sigterm_handler(signum, frame):
+ logger.info("SIGTERM received")
+ os.kill(config.qemupid, signal.SIGTERM)
+ config.cleanup()
+ signal.signal(signal.SIGTERM, sigterm_handler)
+
config.check_args()
config.read_qemuboot()
config.check_and_set()
@@ -1300,7 +1322,6 @@ def main():
traceback.print_exc()
return 1
finally:
- print("Cleanup")
config.cleanup()
if __name__ == "__main__":