#!/usr/bin/env python """ Various helpers for spice2, they all get a qmp port and connect to it, and do various helpful things. """ import qmp import os import atexit import time import copy def kill_proc(pid): os.kill(pid, 3) time.sleep(0.01) try: os.kill(pid, 3) print("sleeping 1 second before terminating %s" % pid) time.sleep(1) os.kill(pid, 15) except OSError: # already dead pass def fork_and_handle(qmp_address, handlers): """ qemu doesn't like multiple clients to it's qmp handler, so just do with one """ print("connecting to %s" % repr(qmp_address)) pid = os.fork() if pid != 0: # parent atexit.register(kill_proc, pid) return pid q = qmp.QEMUMonitorProtocol(qmp_address) q.connect() while True: for e in q.get_events(): for handler in handlers: handler(q, e) q.clear_events() time.sleep(0.1) def reset_on_shutdown(): """ {u'seconds': 1316615017, u'microseconds': 145684}: "{u'event': u'SHUTDOWN'}" {u'seconds': 1316615017, u'microseconds': 157869}: "{u'event': u'STOP'}" """ class ResetOnShutdownHandler(object): def __init__(self): self.next = self.wait_for_shutdown def handler(self, q, event): self.next(q, event) def wait_for_shutdown(self, q, event): if event['event'] == 'SHUTDOWN': self.next = self.wait_for_stop def wait_for_stop(self, q, event): if event['event'] == 'STOP': print("RESET_ON_SHUTDOWN: resetting and continuing machine") q.cmd('system_reset') q.cmd('cont') return ResetOnShutdownHandler().handler def print_events(): def handler(q, orig_event, d={}): # we will mangle the event, so make a copy of it event = copy.deepcopy(orig_event) timestamp_sec, timestamp_usec = event['timestamp']['seconds'], event['timestamp']['microseconds'] if not 'base' in d: d['base'] = (timestamp_sec, timestamp_usec) event_type = event['event'] del event['timestamp'] del event['event'] data = {} if 'data' in event: data = event['data'] del event['data'] print("%4d.%04d: %s%s" % (timestamp_sec - d['base'][0], timestamp_usec / 1000, event_type, ' %r' % event if len(event) > 0 else '')) for k, v in data.items(): print(" %12s: %r" % (k, v)) return handler def test_print_events(qmp_address): print_events(qmp_address) try: while True: time.sleep(10) except: pass if __name__ == '__main__': import sys test_print_events(sys.argv[1])