QAPI patches patches for 2020-09-03

-----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAl9QoqUSHGFybWJydUBy
 ZWRoYXQuY29tAAoJEDhwtADrkYZT2R0QAJJ4HVmHYAfbImC4EPiA26zesITxphaD
 323prQJqR0mKzNf+i4fS4HF36ngCTP1iqaBLU51zTmMt9W7ailQt+jrZhvL3mt25
 eURTTtP31gh3OPkp/jhLS6Ei4eKG1pel/eyNhlFyDgZaIwIs08tVZO9itlNRRnMZ
 xl+CVeCgyVhd5TdBs7HU2koY2lUCWL8SOQltGEFMYGxMRvW4sZZ9Rmckj/VR5iSM
 1xH7CD7xvVCwJcO93cHmqFx7aFaXGEZiBrwmkRSnfbT2xB8tiJrrhV1u6XXQglpS
 8lT+HbNH/2U6Ru9ci3sQGV+t8ZuJcsR/xjvBYYAZ6To5TOmD4S59TqnbG7YmRB7f
 Vqpg52Tm7JO4C4kKeMbYA4msDMb6n5azJURpFjFVg9oUms7tNdur+p7Gh4g2Ngr1
 tCZjXGbDTlbsjlF7xtF/73ff3sNJoxcnok4dptEKdVlwhOZ6McOMgt3s7tF4B/ca
 vAbnwepuUtILgXzqDBg15eViJdrsGvc2nl+sz4D3AxvPuNc2PloBUcrqWYpXX60+
 qxRJydE18T6ag2qCvjAHC5qZ2qOTr1bPZ3iCVwVZc3tSj/MR1FC76SjEe4JlN05x
 3FTZ+hVsn3VOrfZYd9ziwB05LXHp0uv04TVAWgw8dmzFv9mNMciVoY+EjAVYiDfW
 9cd6cV3W2tjx
 =HUiH
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2020-09-03' into staging

QAPI patches patches for 2020-09-03

# gpg: Signature made Thu 03 Sep 2020 09:00:37 BST
# gpg:                using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg:                issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-qapi-2020-09-03:
  docs/qdev-device-use: Don't suggest -drive and -net can do USB
  qapi: Document event VSERPORT_CHANGE is rate-limited
  docs/interop/qmp-spec: Point to the QEMU QMP reference manual
  scripts/qmp/qom-fuse: Fix getattr(), read() for files in /
  scripts/qmp/qom-fuse: Port to current Python module fuse
  scripts/qmp/qom-fuse: Unbreak import of QEMUMonitorProtocol
  qapi/block-core.json: Remove stale description of 'blockdev-add'
  qapi: enable use of g_autoptr with QAPI types

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-09-04 23:24:02 +01:00
commit 8ca019b9c9
9 changed files with 108 additions and 76 deletions

View File

@ -1321,6 +1321,7 @@ Example:
};
void qapi_free_UserDefOne(UserDefOne *obj);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UserDefOne, qapi_free_UserDefOne)
struct UserDefOneList {
UserDefOneList *next;
@ -1328,6 +1329,7 @@ Example:
};
void qapi_free_UserDefOneList(UserDefOneList *obj);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(UserDefOneList, qapi_free_UserDefOneList)
struct q_obj_my_command_arg {
UserDefOneList *arg1;

View File

@ -110,6 +110,9 @@ or
if provided. The "id" member can be any json-value. A json-number
incremented for each successive command works fine.
The actual commands are documented in the QEMU QMP reference manual
docs/interop/qemu-qmp-ref.{7,html,info,pdf,txt}.
2.3.1 Out-of-band execution
---------------------------
@ -207,13 +210,13 @@ The format of asynchronous events is:
there is a failure to retrieve host time, both members of the
timestamp will be set to -1.
For a listing of supported asynchronous events, please, refer to the
qmp-events.txt file.
The actual asynchronous events are documented in the QEMU QMP
reference manual docs/interop/qemu-qmp-ref.{7,html,info,pdf,txt}.
Some events are rate-limited to at most one per second. If additional
"similar" events arrive within one second, all but the last one are
dropped, and the last one is delayed. "Similar" normally means same
event type. See qmp-events.txt for details.
event type.
2.6 Forcing the JSON parser into known-good state
-------------------------------------------------

View File

@ -125,7 +125,14 @@ The -device argument differs in detail for each type of drive:
* if=pflash, if=mtd, if=sd, if=xen are not yet available with -device
For USB storage devices, you can use something like:
For USB devices, the old way was actually different:
-usbdevice disk:format=FMT:FILENAME
"Was" because "disk:" is gone since v2.12.0.
The old way provided much less control than -drive's OPTS... The new
way fixes that:
-device usb-storage,drive=DRIVE-ID,removable=RMB
@ -178,6 +185,9 @@ The appropriate DEVNAME depends on the machine type. For type "pc":
-device usb-braille,chardev=braille -chardev braille,id=braille
* -usbdevice serial::chardev is gone since v2.12.0. It became
-device usb-serial,chardev=dev.
LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows:
* null becomes -chardev null
@ -231,6 +241,12 @@ The old way to define the guest part looks like this:
-net nic,netdev=NET-ID,macaddr=MACADDR,model=MODEL,name=ID,addr=STR,vectors=V
Except for USB it looked like this:
-usbdevice net:netdev=NET-ID,macaddr=MACADDR,name=ID
"Looked" because "net:" is gone since v2.12.0.
The new way is -device:
-device DEVNAME,netdev=NET-ID,mac=MACADDR,DEV-OPTS...
@ -328,6 +344,13 @@ The new way is -device DEVNAME,DEV-OPTS... Details depend on DRIVER:
* u2f -device u2f-{emulated,passthru}
* braille See "Character Devices"
Until v2.12.0, we additionally had
* host:... See "Host Device Assignment"
* disk:... See "Block Devices"
* serial:... See "Character Devices"
* net:... See "Network Devices"
=== Watchdog Devices ===
Host and guest part of watchdog devices have always been separate.
@ -343,7 +366,14 @@ and host USB devices. PCI devices can only be assigned with -device:
-device vfio-pci,host=ADDR,id=ID
To assign a host USB device use:
The old way to assign a USB host device
-usbdevice host:auto:BUS.ADDR:VID:PRID
was removed in v2.12.0. Any of BUS, ADDR, VID, PRID could be the
wildcard *.
The new way is
-device usb-host,hostbus=BUS,hostaddr=ADDR,vendorid=VID,productid=PRID

View File

@ -311,7 +311,5 @@ uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block);
void qcrypto_block_free(QCryptoBlock *block);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlockCreateOptions,
qapi_free_QCryptoBlockCreateOptions)
#endif /* QCRYPTO_BLOCK_H */

View File

@ -4036,9 +4036,7 @@
##
# @blockdev-add:
#
# Creates a new block device. If the @id option is given at the top level, a
# BlockBackend will be created; otherwise, @node-name is mandatory at the top
# level and no BlockBackend will be created.
# Creates a new block device.
#
# Since: 2.9
#

View File

@ -562,6 +562,8 @@
#
# @open: true if the guest has opened the virtio-serial port
#
# Note: This event is rate-limited.
#
# Since: 2.1
#
# Example:

View File

@ -213,6 +213,7 @@ def gen_type_cleanup_decl(name):
ret = mcgen('''
void qapi_free_%(c_name)s(%(c_name)s *obj);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(%(c_name)s, qapi_free_%(c_name)s)
''',
c_name=c_name(name))
return ret

View File

@ -3,17 +3,19 @@
# QEMU Object Model test tools
#
# Copyright IBM, Corp. 2012
# Copyright (C) 2020 Red Hat, Inc.
#
# Authors:
# Anthony Liguori <aliguori@us.ibm.com>
# Markus Armbruster <armbru@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later. See
# the COPYING file in the top-level directory.
##
import fuse, stat
from fuse import Fuse
import os, posix
from fuse import FUSE, FuseOSError, Operations
import os, posix, sys
from errno import *
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
@ -21,9 +23,8 @@ from qemu.qmp import QEMUMonitorProtocol
fuse.fuse_python_api = (0, 2)
class QOMFS(Fuse):
def __init__(self, qmp, *args, **kwds):
Fuse.__init__(self, *args, **kwds)
class QOMFS(Operations):
def __init__(self, qmp):
self.qmp = qmp
self.qmp.connect()
self.ino_map = {}
@ -44,8 +45,10 @@ class QOMFS(Fuse):
return False
def is_property(self, path):
path, prop = path.rsplit('/', 1)
if path == '':
path = '/'
try:
path, prop = path.rsplit('/', 1)
for item in self.qmp.command('qom-list', path=path):
if item['name'] == prop:
return True
@ -54,8 +57,10 @@ class QOMFS(Fuse):
return False
def is_link(self, path):
path, prop = path.rsplit('/', 1)
if path == '':
path = '/'
try:
path, prop = path.rsplit('/', 1)
for item in self.qmp.command('qom-list', path=path):
if item['name'] == prop:
if item['type'].startswith('link<'):
@ -65,21 +70,23 @@ class QOMFS(Fuse):
except:
return False
def read(self, path, length, offset):
def read(self, path, length, offset, fh):
if not self.is_property(path):
return -ENOENT
path, prop = path.rsplit('/', 1)
if path == '':
path = '/'
try:
data = str(self.qmp.command('qom-get', path=path, property=prop))
data = self.qmp.command('qom-get', path=path, property=prop)
data += '\n' # make values shell friendly
except:
return -EPERM
raise FuseOSError(EPERM)
if offset > len(data):
return ''
return str(data[offset:][:length])
return bytes(data[offset:][:length], encoding='utf-8')
def readlink(self, path):
if not self.is_link(path):
@ -89,52 +96,52 @@ class QOMFS(Fuse):
return prefix + str(self.qmp.command('qom-get', path=path,
property=prop))
def getattr(self, path):
def getattr(self, path, fh=None):
if self.is_link(path):
value = posix.stat_result((0o755 | stat.S_IFLNK,
self.get_ino(path),
0,
2,
1000,
1000,
4096,
0,
0,
0))
value = { 'st_mode': 0o755 | stat.S_IFLNK,
'st_ino': self.get_ino(path),
'st_dev': 0,
'st_nlink': 2,
'st_uid': 1000,
'st_gid': 1000,
'st_size': 4096,
'st_atime': 0,
'st_mtime': 0,
'st_ctime': 0 }
elif self.is_object(path):
value = posix.stat_result((0o755 | stat.S_IFDIR,
self.get_ino(path),
0,
2,
1000,
1000,
4096,
0,
0,
0))
value = { 'st_mode': 0o755 | stat.S_IFDIR,
'st_ino': self.get_ino(path),
'st_dev': 0,
'st_nlink': 2,
'st_uid': 1000,
'st_gid': 1000,
'st_size': 4096,
'st_atime': 0,
'st_mtime': 0,
'st_ctime': 0 }
elif self.is_property(path):
value = posix.stat_result((0o644 | stat.S_IFREG,
self.get_ino(path),
0,
1,
1000,
1000,
4096,
0,
0,
0))
value = { 'st_mode': 0o644 | stat.S_IFREG,
'st_ino': self.get_ino(path),
'st_dev': 0,
'st_nlink': 1,
'st_uid': 1000,
'st_gid': 1000,
'st_size': 4096,
'st_atime': 0,
'st_mtime': 0,
'st_ctime': 0 }
else:
value = -ENOENT
raise FuseOSError(ENOENT)
return value
def readdir(self, path, offset):
yield fuse.Direntry('.')
yield fuse.Direntry('..')
def readdir(self, path, fh):
yield '.'
yield '..'
for item in self.qmp.command('qom-list', path=path):
yield fuse.Direntry(str(item['name']))
yield str(item['name'])
if __name__ == '__main__':
import sys, os
import os
fs = QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET']))
fs.main(sys.argv)
fuse = FUSE(QOMFS(QEMUMonitorProtocol(os.environ['QMP_SOCKET'])),
sys.argv[1], foreground=True)

View File

@ -417,7 +417,7 @@ static void test_visitor_in_struct(TestInputVisitorData *data,
static void test_visitor_in_struct_nested(TestInputVisitorData *data,
const void *unused)
{
UserDefTwo *udp = NULL;
g_autoptr(UserDefTwo) udp = NULL;
Visitor *v;
v = visitor_input_test_init(data, "{ 'string0': 'string0', "
@ -433,8 +433,6 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
g_assert_cmpstr(udp->dict1->dict2->userdef->string, ==, "string");
g_assert_cmpstr(udp->dict1->dict2->string, ==, "string2");
g_assert(udp->dict1->has_dict3 == false);
qapi_free_UserDefTwo(udp);
}
static void test_visitor_in_list(TestInputVisitorData *data,
@ -546,7 +544,7 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
const void *unused)
{
Visitor *v;
UserDefFlatUnion *tmp;
g_autoptr(UserDefFlatUnion) tmp = NULL;
UserDefUnionBase *base;
v = visitor_input_test_init(data,
@ -563,8 +561,6 @@ static void test_visitor_in_union_flat(TestInputVisitorData *data,
base = qapi_UserDefFlatUnion_base(tmp);
g_assert(&base->enum1 == &tmp->enum1);
qapi_free_UserDefFlatUnion(tmp);
}
static void test_visitor_in_alternate(TestInputVisitorData *data,
@ -690,7 +686,7 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,
const void *unused,
UserDefListUnionKind kind)
{
UserDefListUnion *cvalue = NULL;
g_autoptr(UserDefListUnion) cvalue = NULL;
Visitor *v;
GString *gstr_list = g_string_new("");
GString *gstr_union = g_string_new("");
@ -782,7 +778,6 @@ static void test_list_union_integer_helper(TestInputVisitorData *data,
g_string_free(gstr_union, true);
g_string_free(gstr_list, true);
qapi_free_UserDefListUnion(cvalue);
}
static void test_visitor_in_list_union_int(TestInputVisitorData *data,
@ -851,7 +846,7 @@ static void test_visitor_in_list_union_uint64(TestInputVisitorData *data,
static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
const void *unused)
{
UserDefListUnion *cvalue = NULL;
g_autoptr(UserDefListUnion) cvalue = NULL;
boolList *elem = NULL;
Visitor *v;
GString *gstr_list = g_string_new("");
@ -879,13 +874,12 @@ static void test_visitor_in_list_union_bool(TestInputVisitorData *data,
g_string_free(gstr_union, true);
g_string_free(gstr_list, true);
qapi_free_UserDefListUnion(cvalue);
}
static void test_visitor_in_list_union_string(TestInputVisitorData *data,
const void *unused)
{
UserDefListUnion *cvalue = NULL;
g_autoptr(UserDefListUnion) cvalue = NULL;
strList *elem = NULL;
Visitor *v;
GString *gstr_list = g_string_new("");
@ -914,7 +908,6 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data,
g_string_free(gstr_union, true);
g_string_free(gstr_list, true);
qapi_free_UserDefListUnion(cvalue);
}
#define DOUBLE_STR_MAX 16
@ -922,7 +915,7 @@ static void test_visitor_in_list_union_string(TestInputVisitorData *data,
static void test_visitor_in_list_union_number(TestInputVisitorData *data,
const void *unused)
{
UserDefListUnion *cvalue = NULL;
g_autoptr(UserDefListUnion) cvalue = NULL;
numberList *elem = NULL;
Visitor *v;
GString *gstr_list = g_string_new("");
@ -957,7 +950,6 @@ static void test_visitor_in_list_union_number(TestInputVisitorData *data,
g_string_free(gstr_union, true);
g_string_free(gstr_list, true);
qapi_free_UserDefListUnion(cvalue);
}
static void input_visitor_test_add(const char *testpath,
@ -1253,7 +1245,7 @@ static void test_visitor_in_fail_alternate(TestInputVisitorData *data,
static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
const QLitObject *qlit)
{
SchemaInfoList *schema = NULL;
g_autoptr(SchemaInfoList) schema = NULL;
QObject *obj = qobject_from_qlit(qlit);
Visitor *v;
@ -1262,7 +1254,6 @@ static void do_test_visitor_in_qmp_introspect(TestInputVisitorData *data,
visit_type_SchemaInfoList(v, NULL, &schema, &error_abort);
g_assert(schema);
qapi_free_SchemaInfoList(schema);
qobject_unref(obj);
visit_free(v);
}