diff options
Diffstat (limited to 'meta/lib/oeqa/utils/qemurunner.py')
-rw-r--r-- | meta/lib/oeqa/utils/qemurunner.py | 54 |
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 | |||
22 | logger = logging.getLogger("BitBake.QemuRunner") | 22 | logger = logging.getLogger("BitBake.QemuRunner") |
23 | 23 | ||
24 | # Get Unicode non printable control chars | 24 | # Get Unicode non printable control chars |
25 | control_range = range(0,32)+range(127,160) | 25 | control_range = list(range(0,32))+list(range(127,160)) |
26 | control_chars = [unichr(x) for x in control_range | 26 | control_chars = [chr(x) for x in control_range |
27 | if unichr(x) not in string.printable] | 27 | if chr(x) not in string.printable] |
28 | re_control_char = re.compile('[%s]' % re.escape("".join(control_chars))) | 28 | re_control_char = re.compile('[%s]' % re.escape("".join(control_chars))) |
29 | 29 | ||
30 | class QemuRunner: | 30 | class 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") |