summaryrefslogtreecommitdiffstats
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 11:07:58 +0100
commit27061a274f47c72a2290182f7b1da6d6ec309fc7 (patch)
tree8f16fdcafd6f8212ae21613ec0c8c009c0f2253f /scripts/runqemu
parentffeb85ab80fb2f15d31675a0e6deddb1bab4760e (diff)
downloadpoky-27061a274f47c72a2290182f7b1da6d6ec309fc7.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. (From OE-Core rev: 02709d4709c56f9b9095e3555da35b659b03a8a3) 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 d998494063..de42d0f323 100755
--- a/scripts/runqemu
+++ b/scripts/runqemu
@@ -27,6 +27,7 @@ import fcntl
27import shutil 27import shutil
28import glob 28import glob
29import configparser 29import configparser
30import signal
30 31
31class RunQemuError(Exception): 32class RunQemuError(Exception):
32 """Custom exception to raise on known errors.""" 33 """Custom exception to raise on known errors."""
@@ -233,6 +234,10 @@ class BaseConfig(object):
233 # slirp qemus are running. 234 # slirp qemus are running.
234 self.mac_tap = "52:54:00:12:34:" 235 self.mac_tap = "52:54:00:12:34:"
235 self.mac_slirp = "52:54:00:12:35:" 236 self.mac_slirp = "52:54:00:12:35:"
237 # pid of the actual qemu process
238 self.qemupid = None
239 # avoid cleanup twice
240 self.cleaned = False
236 241
237 def acquire_lock(self, error=True): 242 def acquire_lock(self, error=True):
238 logger.debug("Acquiring lockfile %s..." % self.lock) 243 logger.debug("Acquiring lockfile %s..." % self.lock)
@@ -1200,10 +1205,18 @@ class BaseConfig(object):
1200 cmd = "%s %s" % (self.qemu_opt, kernel_opts) 1205 cmd = "%s %s" % (self.qemu_opt, kernel_opts)
1201 logger.info('Running %s\n' % cmd) 1206 logger.info('Running %s\n' % cmd)
1202 process = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE) 1207 process = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE)
1208 self.qemupid = process.pid
1203 if process.wait(): 1209 if process.wait():
1204 logger.error("Failed to run qemu: %s", process.stderr.read().decode()) 1210 logger.error("Failed to run qemu: %s", process.stderr.read().decode())
1205 1211
1206 def cleanup(self): 1212 def cleanup(self):
1213 if self.cleaned:
1214 return
1215
1216 # avoid dealing with SIGTERM when cleanup function is running
1217 signal.signal(signal.SIGTERM, signal.SIG_IGN)
1218
1219 logger.info("Cleaning up")
1207 if self.cleantap: 1220 if self.cleantap:
1208 cmd = 'sudo %s %s %s' % (self.qemuifdown, self.tap, self.bindir_native) 1221 cmd = 'sudo %s %s %s' % (self.qemuifdown, self.tap, self.bindir_native)
1209 logger.debug('Running %s' % cmd) 1222 logger.debug('Running %s' % cmd)
@@ -1227,6 +1240,8 @@ class BaseConfig(object):
1227 shutil.rmtree(self.rootfs) 1240 shutil.rmtree(self.rootfs)
1228 shutil.rmtree('%s.pseudo_state' % self.rootfs) 1241 shutil.rmtree('%s.pseudo_state' % self.rootfs)
1229 1242
1243 self.cleaned = True
1244
1230 def load_bitbake_env(self, mach=None): 1245 def load_bitbake_env(self, mach=None):
1231 if self.bitbake_e: 1246 if self.bitbake_e:
1232 return 1247 return
@@ -1282,6 +1297,13 @@ def main():
1282 return 0 1297 return 0
1283 try: 1298 try:
1284 config = BaseConfig() 1299 config = BaseConfig()
1300
1301 def sigterm_handler(signum, frame):
1302 logger.info("SIGTERM received")
1303 os.kill(config.qemupid, signal.SIGTERM)
1304 config.cleanup()
1305 signal.signal(signal.SIGTERM, sigterm_handler)
1306
1285 config.check_args() 1307 config.check_args()
1286 config.read_qemuboot() 1308 config.read_qemuboot()
1287 config.check_and_set() 1309 config.check_and_set()
@@ -1300,7 +1322,6 @@ def main():
1300 traceback.print_exc() 1322 traceback.print_exc()
1301 return 1 1323 return 1
1302 finally: 1324 finally:
1303 print("Cleanup")
1304 config.cleanup() 1325 config.cleanup()
1305 1326
1306if __name__ == "__main__": 1327if __name__ == "__main__":