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:
commit
8ca019b9c9
@ -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;
|
||||
|
@ -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
|
||||
-------------------------------------------------
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user