summaryrefslogtreecommitdiffstats
path: root/meta/lib/oeqa/utils/qemurunner.py
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/utils/qemurunner.py')
-rw-r--r--meta/lib/oeqa/utils/qemurunner.py54
1 files changed, 31 insertions, 23 deletions
diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index 4bede3421c..773cf588b1 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -22,9 +22,9 @@ import logging
22logger = logging.getLogger("BitBake.QemuRunner") 22logger = logging.getLogger("BitBake.QemuRunner")
23 23
24# Get Unicode non printable control chars 24# Get Unicode non printable control chars
25control_range = range(0,32)+range(127,160) 25control_range = list(range(0,32))+list(range(127,160))
26control_chars = [unichr(x) for x in control_range 26control_chars = [chr(x) for x in control_range
27 if unichr(x) not in string.printable] 27 if chr(x) not in string.printable]
28re_control_char = re.compile('[%s]' % re.escape("".join(control_chars))) 28re_control_char = re.compile('[%s]' % re.escape("".join(control_chars)))
29 29
30class QemuRunner: 30class QemuRunner:
@@ -71,7 +71,8 @@ class QemuRunner:
71 if self.logfile: 71 if self.logfile:
72 # It is needed to sanitize the data received from qemu 72 # It is needed to sanitize the data received from qemu
73 # because is possible to have control characters 73 # because is possible to have control characters
74 msg = re_control_char.sub('', unicode(msg, 'utf-8')) 74 msg = msg.decode("utf-8")
75 msg = re_control_char.sub('', msg)
75 with codecs.open(self.logfile, "a", encoding="utf-8") as f: 76 with codecs.open(self.logfile, "a", encoding="utf-8") as f:
76 f.write("%s" % msg) 77 f.write("%s" % msg)
77 78
@@ -79,7 +80,7 @@ class QemuRunner:
79 import fcntl 80 import fcntl
80 fl = fcntl.fcntl(o, fcntl.F_GETFL) 81 fl = fcntl.fcntl(o, fcntl.F_GETFL)
81 fcntl.fcntl(o, fcntl.F_SETFL, fl | os.O_NONBLOCK) 82 fcntl.fcntl(o, fcntl.F_SETFL, fl | os.O_NONBLOCK)
82 return os.read(o.fileno(), 1000000) 83 return os.read(o.fileno(), 1000000).decode("utf-8")
83 84
84 85
85 def handleSIGCHLD(self, signum, frame): 86 def handleSIGCHLD(self, signum, frame):
@@ -114,7 +115,7 @@ class QemuRunner:
114 try: 115 try:
115 threadsock, threadport = self.create_socket() 116 threadsock, threadport = self.create_socket()
116 self.server_socket, self.serverport = self.create_socket() 117 self.server_socket, self.serverport = self.create_socket()
117 except socket.error, msg: 118 except socket.error as msg:
118 logger.error("Failed to create listening socket: %s" % msg[1]) 119 logger.error("Failed to create listening socket: %s" % msg[1])
119 return False 120 return False
120 121
@@ -192,7 +193,7 @@ class QemuRunner:
192 else: 193 else:
193 self.ip = ips[0] 194 self.ip = ips[0]
194 self.server_ip = ips[1] 195 self.server_ip = ips[1]
195 except IndexError, ValueError: 196 except (IndexError, ValueError):
196 logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, self.getOutput(output))) 197 logger.info("Couldn't get ip from qemu process arguments! Here is the qemu command line used:\n%s\nand output from runqemu:\n%s" % (cmdline, self.getOutput(output)))
197 self._dump_host() 198 self._dump_host()
198 self.stop() 199 self.stop()
@@ -219,6 +220,7 @@ class QemuRunner:
219 stopread = False 220 stopread = False
220 qemusock = None 221 qemusock = None
221 bootlog = '' 222 bootlog = ''
223 data = b''
222 while time.time() < endtime and not stopread: 224 while time.time() < endtime and not stopread:
223 sread, swrite, serror = select.select(socklist, [], [], 5) 225 sread, swrite, serror = select.select(socklist, [], [], 5)
224 for sock in sread: 226 for sock in sread:
@@ -229,14 +231,19 @@ class QemuRunner:
229 socklist.remove(self.server_socket) 231 socklist.remove(self.server_socket)
230 logger.info("Connection from %s:%s" % addr) 232 logger.info("Connection from %s:%s" % addr)
231 else: 233 else:
232 data = sock.recv(1024) 234 data = data + sock.recv(1024)
233 if data: 235 if data:
234 bootlog += data 236 try:
235 if re.search(".* login:", bootlog): 237 data = data.decode("utf-8")
236 self.server_socket = qemusock 238 bootlog += data
237 stopread = True 239 data = b''
238 reachedlogin = True 240 if re.search(".* login:", bootlog):
239 logger.info("Reached login banner") 241 self.server_socket = qemusock
242 stopread = True
243 reachedlogin = True
244 logger.info("Reached login banner")
245 except UnicodeDecodeError:
246 continue
240 else: 247 else:
241 socklist.remove(sock) 248 socklist.remove(sock)
242 sock.close() 249 sock.close()
@@ -277,13 +284,14 @@ class QemuRunner:
277 if hasattr(self, "origchldhandler"): 284 if hasattr(self, "origchldhandler"):
278 signal.signal(signal.SIGCHLD, self.origchldhandler) 285 signal.signal(signal.SIGCHLD, self.origchldhandler)
279 if self.runqemu: 286 if self.runqemu:
280 os.kill(self.monitorpid, signal.SIGKILL) 287 if hasattr(self, "monitorpid"):
281 logger.info("Sending SIGTERM to runqemu") 288 os.kill(self.monitorpid, signal.SIGKILL)
282 try: 289 logger.info("Sending SIGTERM to runqemu")
283 os.killpg(os.getpgid(self.runqemu.pid), signal.SIGTERM) 290 try:
284 except OSError as e: 291 os.killpg(os.getpgid(self.runqemu.pid), signal.SIGTERM)
285 if e.errno != errno.ESRCH: 292 except OSError as e:
286 raise 293 if e.errno != errno.ESRCH:
294 raise
287 endtime = time.time() + self.runqemutime 295 endtime = time.time() + self.runqemutime
288 while self.runqemu.poll() is None and time.time() < endtime: 296 while self.runqemu.poll() is None and time.time() < endtime:
289 time.sleep(1) 297 time.sleep(1)
@@ -325,7 +333,7 @@ class QemuRunner:
325 # Walk the process tree from the process specified looking for a qemu-system. Return its [pid'cmd] 333 # Walk the process tree from the process specified looking for a qemu-system. Return its [pid'cmd]
326 # 334 #
327 ps = subprocess.Popen(['ps', 'axww', '-o', 'pid,ppid,command'], stdout=subprocess.PIPE).communicate()[0] 335 ps = subprocess.Popen(['ps', 'axww', '-o', 'pid,ppid,command'], stdout=subprocess.PIPE).communicate()[0]
328 processes = ps.split('\n') 336 processes = ps.decode("utf-8").split('\n')
329 nfields = len(processes[0].split()) - 1 337 nfields = len(processes[0].split()) - 1
330 pids = {} 338 pids = {}
331 commands = {} 339 commands = {}
@@ -442,7 +450,7 @@ class LoggingThread(threading.Thread):
442 def stop(self): 450 def stop(self):
443 self.logger.info("Stopping logging thread") 451 self.logger.info("Stopping logging thread")
444 if self.running: 452 if self.running:
445 os.write(self.writepipe, "stop") 453 os.write(self.writepipe, bytes("stop", "utf-8"))
446 454
447 def teardown(self): 455 def teardown(self):
448 self.logger.info("Tearing down logging thread") 456 self.logger.info("Tearing down logging thread")