summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/qapi.py43
-rwxr-xr-xscripts/qapi2texi.py11
-rw-r--r--scripts/qemu.py94
-rw-r--r--scripts/signrom.py4
4 files changed, 96 insertions, 56 deletions
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 43a54bf40f..58f995b07f 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -11,13 +11,21 @@
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
+from __future__ import print_function
import errno
import getopt
import os
import re
import string
import sys
-from ordereddict import OrderedDict
+try:
+ from collections import OrderedDict
+except:
+ from ordereddict import OrderedDict
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
builtin_types = {
'null': 'QTYPE_QNULL',
@@ -244,7 +252,7 @@ class QAPIDoc(object):
"'Returns:' is only valid for commands")
def check(self):
- bogus = [name for name, section in self.args.iteritems()
+ bogus = [name for name, section in self.args.items()
if not section.member]
if bogus:
raise QAPISemError(
@@ -299,7 +307,7 @@ class QAPISchemaParser(object):
if not isinstance(pragma, dict):
raise QAPISemError(
info, "Value of 'pragma' must be a dictionary")
- for name, value in pragma.iteritems():
+ for name, value in pragma.items():
self._pragma(name, value, info)
else:
expr_elem = {'expr': expr,
@@ -1467,7 +1475,7 @@ class QAPISchema(object):
self._def_exprs()
self.check()
except QAPIError as err:
- print >>sys.stderr, err
+ print(err, file=sys.stderr)
exit(1)
def _def_entity(self, ent):
@@ -1565,7 +1573,7 @@ class QAPISchema(object):
def _make_members(self, data, info):
return [self._make_member(key, value, info)
- for (key, value) in data.iteritems()]
+ for (key, value) in data.items()]
def _def_struct_type(self, expr, info, doc):
name = expr['struct']
@@ -1597,11 +1605,11 @@ class QAPISchema(object):
name, info, doc, 'base', self._make_members(base, info)))
if tag_name:
variants = [self._make_variant(key, value)
- for (key, value) in data.iteritems()]
+ for (key, value) in data.items()]
members = []
else:
variants = [self._make_simple_variant(key, value, info)
- for (key, value) in data.iteritems()]
+ for (key, value) in data.items()]
typ = self._make_implicit_enum_type(name, info,
[v.name for v in variants])
tag_member = QAPISchemaObjectTypeMember('type', typ, False)
@@ -1616,7 +1624,7 @@ class QAPISchema(object):
name = expr['alternate']
data = expr['data']
variants = [self._make_variant(key, value)
- for (key, value) in data.iteritems()]
+ for (key, value) in data.items()]
tag_member = QAPISchemaObjectTypeMember('type', 'QType', False)
self._def_entity(
QAPISchemaAlternateType(name, info, doc,
@@ -1670,7 +1678,7 @@ class QAPISchema(object):
assert False
def check(self):
- for ent in self._entity_dict.values():
+ for (name, ent) in sorted(self._entity_dict.items()):
ent.check(self)
def visit(self, visitor):
@@ -1726,7 +1734,10 @@ def c_enum_const(type_name, const_name, prefix=None):
type_name = prefix
return camel_to_upper(type_name) + '_' + c_name(const_name, False).upper()
-c_name_trans = string.maketrans('.-', '__')
+if hasattr(str, 'maketrans'):
+ c_name_trans = str.maketrans('.-', '__')
+else:
+ c_name_trans = string.maketrans('.-', '__')
# Map @name to a valid C identifier.
@@ -1931,7 +1942,7 @@ def parse_command_line(extra_options='', extra_long_options=[]):
['source', 'header', 'prefix=',
'output-dir='] + extra_long_options)
except getopt.GetoptError as err:
- print >>sys.stderr, "%s: %s" % (sys.argv[0], str(err))
+ print("%s: %s" % (sys.argv[0], str(err)), file=sys.stderr)
sys.exit(1)
output_dir = ''
@@ -1945,9 +1956,8 @@ def parse_command_line(extra_options='', extra_long_options=[]):
if o in ('-p', '--prefix'):
match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', a)
if match.end() != len(a):
- print >>sys.stderr, \
- "%s: 'funny character '%s' in argument of --prefix" \
- % (sys.argv[0], a[match.end()])
+ print("%s: 'funny character '%s' in argument of --prefix" \
+ % (sys.argv[0], a[match.end()]), file=sys.stderr)
sys.exit(1)
prefix = a
elif o in ('-o', '--output-dir'):
@@ -1964,7 +1974,7 @@ def parse_command_line(extra_options='', extra_long_options=[]):
do_h = True
if len(args) != 1:
- print >>sys.stderr, "%s: need exactly one argument" % sys.argv[0]
+ print("%s: need exactly one argument" % sys.argv[0], file=sys.stderr)
sys.exit(1)
fname = args[0]
@@ -1992,8 +2002,7 @@ def open_output(output_dir, do_c, do_h, prefix, c_file, h_file,
if really:
return open(name, opt)
else:
- import StringIO
- return StringIO.StringIO()
+ return StringIO()
fdef = maybe_open(do_c, c_file, 'w')
fdecl = maybe_open(do_h, h_file, 'w')
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 92e2af2cd6..bf1c57b2e2 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -4,6 +4,7 @@
# This work is licensed under the terms of the GNU LGPL, version 2+.
# See the COPYING file in the top-level directory.
"""This script produces the documentation of a qapi schema in texinfo format"""
+from __future__ import print_function
import re
import sys
@@ -145,7 +146,7 @@ def texi_member(member, suffix=''):
def texi_members(doc, what, base, variants, member_func):
"""Format the table of members"""
items = ''
- for section in doc.args.itervalues():
+ for section in doc.args.values():
# TODO Drop fallbacks when undocumented members are outlawed
if section.text:
desc = texi_format(section.text)
@@ -274,15 +275,15 @@ def texi_schema(schema):
def main(argv):
"""Takes schema argument, prints result to stdout"""
if len(argv) != 2:
- print >>sys.stderr, "%s: need exactly 1 argument: SCHEMA" % argv[0]
+ print("%s: need exactly 1 argument: SCHEMA" % argv[0], file=sys.stderr)
sys.exit(1)
schema = qapi.QAPISchema(argv[1])
if not qapi.doc_required:
- print >>sys.stderr, ("%s: need pragma 'doc-required' "
- "to generate documentation" % argv[0])
+ print("%s: need pragma 'doc-required' "
+ "to generate documentation" % argv[0], file=sys.stderr)
sys.exit(1)
- print texi_schema(schema)
+ print(texi_schema(schema))
if __name__ == '__main__':
diff --git a/scripts/qemu.py b/scripts/qemu.py
index 9bfdf6d37d..305a946562 100644
--- a/scripts/qemu.py
+++ b/scripts/qemu.py
@@ -15,9 +15,10 @@
import errno
import logging
import os
-import sys
import subprocess
import qmp.qmp
+import shutil
+import tempfile
LOG = logging.getLogger(__name__)
@@ -73,10 +74,11 @@ class QEMUMachine(object):
wrapper = []
if name is None:
name = "qemu-%d" % os.getpid()
- if monitor_address is None:
- monitor_address = os.path.join(test_dir, name + "-monitor.sock")
+ self._name = name
self._monitor_address = monitor_address
- self._qemu_log_path = os.path.join(test_dir, name + ".log")
+ self._vm_monitor = None
+ self._qemu_log_path = None
+ self._qemu_log_file = None
self._popen = None
self._binary = binary
self._args = list(args) # Force copy args in case we modify them
@@ -86,6 +88,9 @@ class QEMUMachine(object):
self._socket_scm_helper = socket_scm_helper
self._qmp = None
self._qemu_full_args = None
+ self._test_dir = test_dir
+ self._temp_dir = None
+ self._launched = False
# just in case logging wasn't configured by the main script:
logging.basicConfig()
@@ -146,12 +151,12 @@ class QEMUMachine(object):
raise
def is_running(self):
- return self._popen is not None and self._popen.returncode is None
+ return self._popen is not None and self._popen.poll() is None
def exitcode(self):
if self._popen is None:
return None
- return self._popen.returncode
+ return self._popen.poll()
def get_pid(self):
if not self.is_running():
@@ -159,8 +164,9 @@ class QEMUMachine(object):
return self._popen.pid
def _load_io_log(self):
- with open(self._qemu_log_path, "r") as iolog:
- self._iolog = iolog.read()
+ if self._qemu_log_path is not None:
+ with open(self._qemu_log_path, "r") as iolog:
+ self._iolog = iolog.read()
def _base_args(self):
if isinstance(self._monitor_address, tuple):
@@ -168,45 +174,54 @@ class QEMUMachine(object):
self._monitor_address[0],
self._monitor_address[1])
else:
- moncdev = 'socket,id=mon,path=%s' % self._monitor_address
+ moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
return ['-chardev', moncdev,
'-mon', 'chardev=mon,mode=control',
'-display', 'none', '-vga', 'none']
def _pre_launch(self):
- self._qmp = qmp.qmp.QEMUMonitorProtocol(self._monitor_address,
+ self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
+ if self._monitor_address is not None:
+ self._vm_monitor = self._monitor_address
+ else:
+ self._vm_monitor = os.path.join(self._temp_dir,
+ self._name + "-monitor.sock")
+ self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log")
+ self._qemu_log_file = open(self._qemu_log_path, 'wb')
+
+ self._qmp = qmp.qmp.QEMUMonitorProtocol(self._vm_monitor,
server=True)
def _post_launch(self):
self._qmp.accept()
def _post_shutdown(self):
- if not isinstance(self._monitor_address, tuple):
- self._remove_if_exists(self._monitor_address)
- self._remove_if_exists(self._qemu_log_path)
+ if self._qemu_log_file is not None:
+ self._qemu_log_file.close()
+ self._qemu_log_file = None
+
+ self._qemu_log_path = None
+
+ if self._temp_dir is not None:
+ shutil.rmtree(self._temp_dir)
+ self._temp_dir = None
def launch(self):
- '''Launch the VM and establish a QMP connection'''
+ """
+ Launch the VM and make sure we cleanup and expose the
+ command line/output in case of exception
+ """
+
+ if self._launched:
+ raise QEMUMachineError('VM already launched')
+
self._iolog = None
self._qemu_full_args = None
- devnull = open(os.path.devnull, 'rb')
- qemulog = open(self._qemu_log_path, 'wb')
try:
- self._pre_launch()
- self._qemu_full_args = (self._wrapper + [self._binary] +
- self._base_args() + self._args)
- self._popen = subprocess.Popen(self._qemu_full_args,
- stdin=devnull,
- stdout=qemulog,
- stderr=subprocess.STDOUT,
- shell=False)
- self._post_launch()
+ self._launch()
+ self._launched = True
except:
- if self.is_running():
- self._popen.kill()
- self._popen.wait()
- self._load_io_log()
- self._post_shutdown()
+ self.shutdown()
LOG.debug('Error launching VM')
if self._qemu_full_args:
@@ -215,6 +230,19 @@ class QEMUMachine(object):
LOG.debug('Output: %r', self._iolog)
raise
+ def _launch(self):
+ '''Launch the VM and establish a QMP connection'''
+ devnull = open(os.path.devnull, 'rb')
+ self._pre_launch()
+ self._qemu_full_args = (self._wrapper + [self._binary] +
+ self._base_args() + self._args)
+ self._popen = subprocess.Popen(self._qemu_full_args,
+ stdin=devnull,
+ stdout=self._qemu_log_file,
+ stderr=subprocess.STDOUT,
+ shell=False)
+ self._post_launch()
+
def wait(self):
'''Wait for the VM to power off'''
self._popen.wait()
@@ -232,8 +260,8 @@ class QEMUMachine(object):
self._popen.kill()
self._popen.wait()
- self._load_io_log()
- self._post_shutdown()
+ self._load_io_log()
+ self._post_shutdown()
exitcode = self.exitcode()
if exitcode is not None and exitcode < 0:
@@ -244,6 +272,8 @@ class QEMUMachine(object):
command = ''
LOG.warn(msg, exitcode, command)
+ self._launched = False
+
def qmp(self, cmd, conv_keys=True, **args):
'''Invoke a QMP command and return the response dict'''
qmp_args = dict()
diff --git a/scripts/signrom.py b/scripts/signrom.py
index d1dabe0240..0497a1c32e 100644
--- a/scripts/signrom.py
+++ b/scripts/signrom.py
@@ -18,7 +18,7 @@ fin = open(sys.argv[1], 'rb')
fout = open(sys.argv[2], 'wb')
magic = fin.read(2)
-if magic != '\x55\xaa':
+if magic != b'\x55\xaa':
sys.exit("%s: option ROM does not begin with magic 55 aa" % sys.argv[1])
size_byte = ord(fin.read(1))
@@ -33,7 +33,7 @@ elif len(data) < size:
# Add padding if necessary, rounding the whole input to a multiple of
# 512 bytes according to the third byte of the input.
# size-1 because a final byte is added below to store the checksum.
- data = data.ljust(size-1, '\0')
+ data = data.ljust(size-1, b'\0')
else:
if ord(data[-1:]) != 0:
sys.stderr.write('WARNING: ROM includes nonzero checksum\n')