提交 06b4f00d 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging

* remotes/qmp-unstable/queue/qmp: (38 commits)
  Revert "qapi: Clean up superfluous null check in qapi_dealloc_type_str()"
  qapi: Document optional arguments' backwards compatibility
  qmp: use valid JSON in transaction example
  qmp: Don't use error_is_set() to suppress additional errors
  dump: Drop pointless error_is_set(), DumpState member errp
  qemu-option: Clean up fragile use of error_is_set()
  qga: Drop superfluous error_is_set()
  qga: Clean up fragile use of error_is_set()
  qapi: Clean up fragile use of error_is_set()
  tests/qapi-schema: Drop superfluous error_is_set()
  qapi: Drop redundant, unclean error_is_set()
  hmp: Guard against misuse of hmp_handle_error()
  qga: Use return values instead of error_is_set(errp)
  error: Consistently name Error ** objects errp, and not err
  qmp: Consistently name Error ** objects errp, and not err
  qga: Consistently name Error ** objects errp, and not err
  qmp hmp: Consistently name Error * objects err, and not errp
  pci-assign: assigned_initfn(): set monitor error in common error handler
  pci-assign: propagate errors from assign_intx()
  pci-assign: propagate errors from assign_device()
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -238,23 +238,35 @@ qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
" GEN $@")
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
" GEN $@")
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
" GEN $@")
qapi-types.c qapi-types.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o "." -b -i $<, \
" GEN $@")
qapi-visit.c qapi-visit.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
$(gen-out-type) -o "." -b -i $<, \
" GEN $@")
qmp-commands.h qmp-marshal.c :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o "." -m -i $<, \
" GEN $@")
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
......
......@@ -40,6 +40,17 @@ enumeration types and union types.
Generally speaking, types definitions should always use CamelCase for the type
names. Command names should be all lower case with words separated by a hyphen.
=== Includes ===
The QAPI schema definitions can be modularized using the 'include' directive:
{ 'include': 'path/to/file.json'}
The directive is evaluated recursively, and include paths are relative to the
file using the directive.
=== Complex types ===
A complex type is a dictionary containing a single key whose value is a
......@@ -49,10 +60,34 @@ example of a complex type is:
{ 'type': 'MyType',
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
The use of '*' as a prefix to the name means the member is optional. Optional
members should always be added to the end of the dictionary to preserve
backwards compatibility.
The use of '*' as a prefix to the name means the member is optional.
The default initialization value of an optional argument should not be changed
between versions of QEMU unless the new default maintains backward
compatibility to the user-visible behavior of the old default.
With proper documentation, this policy still allows some flexibility; for
example, documenting that a default of 0 picks an optimal buffer size allows
one release to declare the optimal size at 512 while another release declares
the optimal size at 4096 - the user-visible behavior is not the bytes used by
the buffer, but the fact that the buffer was optimal size.
On input structures (only mentioned in the 'data' side of a command), changing
from mandatory to optional is safe (older clients will supply the option, and
newer clients can benefit from the default); changing from optional to
mandatory is backwards incompatible (older clients may be omitting the option,
and must continue to work).
On output structures (only mentioned in the 'returns' side of a command),
changing from mandatory to optional is in general unsafe (older clients may be
expecting the field, and could crash if it is missing), although it can be done
if the only way that the optional argument will be omitted is when it is
triggered by the presence of a new input flag to the command that older clients
don't know to send. Changing from optional to mandatory is safe.
A structure that is used in both input and output of various commands
must consider the backwards compatibility constraints of both directions
of use.
A complex type definition can specify another complex type as its base.
In this case, the fields of the base type are included as top-level fields
......@@ -221,7 +256,7 @@ created code.
Example:
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
--output-dir="qapi-generated" --prefix="example-" < example-schema.json
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
......@@ -291,7 +326,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
Example:
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
--output-dir="qapi-generated" --prefix="example-" < example-schema.json
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
......
......@@ -308,12 +308,12 @@ Here's the implementation of the "hello-world" HMP command:
void hmp_hello_world(Monitor *mon, const QDict *qdict)
{
const char *message = qdict_get_try_str(qdict, "message");
Error *errp = NULL;
Error *err = NULL;
qmp_hello_world(!!message, message, &errp);
if (errp) {
monitor_printf(mon, "%s\n", error_get_pretty(errp));
error_free(errp);
qmp_hello_world(!!message, message, &err);
if (err) {
monitor_printf(mon, "%s\n", error_get_pretty(err));
error_free(err);
return;
}
}
......@@ -328,7 +328,7 @@ There are three important points to be noticed:
2. hmp_hello_world() performs error checking. In this example we just print
the error description to the user, but we could do more, like taking
different actions depending on the error qmp_hello_world() returns
3. The "errp" variable must be initialized to NULL before performing the
3. The "err" variable must be initialized to NULL before performing the
QMP call
There's one last step to actually make the command available to monitor users,
......@@ -480,12 +480,12 @@ Here's the HMP counterpart of the query-alarm-clock command:
void hmp_info_alarm_clock(Monitor *mon)
{
QemuAlarmClock *clock;
Error *errp = NULL;
Error *err = NULL;
clock = qmp_query_alarm_clock(&errp);
if (errp) {
clock = qmp_query_alarm_clock(&err);
if (err) {
monitor_printf(mon, "Could not query alarm clock information\n");
error_free(errp);
error_free(err);
return;
}
......@@ -631,12 +631,12 @@ has to traverse the list, it's shown below for reference:
void hmp_info_alarm_methods(Monitor *mon)
{
TimerAlarmMethodList *method_list, *method;
Error *errp = NULL;
Error *err = NULL;
method_list = qmp_query_alarm_methods(&errp);
if (errp) {
method_list = qmp_query_alarm_methods(&err);
if (err) {
monitor_printf(mon, "Could not query alarm methods\n");
error_free(errp);
error_free(err);
return;
}
......
......@@ -86,7 +86,6 @@ typedef struct DumpState {
bool has_filter;
int64_t begin;
int64_t length;
Error **errp;
uint8_t *note_buf; /* buffer for notes */
size_t note_buf_offset; /* the writing place in note_buf */
......@@ -1570,7 +1569,6 @@ static int dump_init(DumpState *s, int fd, bool has_format,
nr_cpus++;
}
s->errp = errp;
s->fd = fd;
s->has_filter = has_filter;
s->begin = begin;
......@@ -1780,11 +1778,11 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
}
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
if (create_kdump_vmcore(s) < 0 && !error_is_set(s->errp)) {
if (create_kdump_vmcore(s) < 0) {
error_set(errp, QERR_IO_ERROR);
}
} else {
if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
if (create_vmcore(s) < 0) {
error_set(errp, QERR_IO_ERROR);
}
}
......
......@@ -28,7 +28,8 @@
static void hmp_handle_error(Monitor *mon, Error **errp)
{
if (error_is_set(errp)) {
assert(errp);
if (*errp) {
monitor_printf(mon, "%s\n", error_get_pretty(*errp));
error_free(*errp);
}
......@@ -754,10 +755,10 @@ void hmp_memsave(Monitor *mon, const QDict *qdict)
uint32_t size = qdict_get_int(qdict, "size");
const char *filename = qdict_get_str(qdict, "filename");
uint64_t addr = qdict_get_int(qdict, "val");
Error *errp = NULL;
Error *err = NULL;
qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &errp);
hmp_handle_error(mon, &errp);
qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &err);
hmp_handle_error(mon, &err);
}
void hmp_pmemsave(Monitor *mon, const QDict *qdict)
......@@ -765,21 +766,21 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
uint32_t size = qdict_get_int(qdict, "size");
const char *filename = qdict_get_str(qdict, "filename");
uint64_t addr = qdict_get_int(qdict, "val");
Error *errp = NULL;
Error *err = NULL;
qmp_pmemsave(addr, size, filename, &errp);
hmp_handle_error(mon, &errp);
qmp_pmemsave(addr, size, filename, &err);
hmp_handle_error(mon, &err);
}
void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
{
const char *chardev = qdict_get_str(qdict, "device");
const char *data = qdict_get_str(qdict, "data");
Error *errp = NULL;
Error *err = NULL;
qmp_ringbuf_write(chardev, data, false, 0, &errp);
qmp_ringbuf_write(chardev, data, false, 0, &err);
hmp_handle_error(mon, &errp);
hmp_handle_error(mon, &err);
}
void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
......@@ -787,13 +788,13 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
uint32_t size = qdict_get_int(qdict, "size");
const char *chardev = qdict_get_str(qdict, "device");
char *data;
Error *errp = NULL;
Error *err = NULL;
int i;
data = qmp_ringbuf_read(chardev, size, false, 0, &errp);
if (errp) {
monitor_printf(mon, "%s\n", error_get_pretty(errp));
error_free(errp);
data = qmp_ringbuf_read(chardev, size, false, 0, &err);
if (err) {
monitor_printf(mon, "%s\n", error_get_pretty(err));
error_free(err);
return;
}
......@@ -828,7 +829,7 @@ static bool key_is_missing(const BlockInfo *bdev)
void hmp_cont(Monitor *mon, const QDict *qdict)
{
BlockInfoList *bdev_list, *bdev;
Error *errp = NULL;
Error *err = NULL;
bdev_list = qmp_query_block(NULL);
for (bdev = bdev_list; bdev; bdev = bdev->next) {
......@@ -839,8 +840,8 @@ void hmp_cont(Monitor *mon, const QDict *qdict)
}
}
qmp_cont(&errp);
hmp_handle_error(mon, &errp);
qmp_cont(&err);
hmp_handle_error(mon, &err);
out:
qapi_free_BlockInfoList(bdev_list);
......@@ -853,41 +854,41 @@ void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
Error *err = NULL;
qmp_inject_nmi(&errp);
hmp_handle_error(mon, &errp);
qmp_inject_nmi(&err);
hmp_handle_error(mon, &err);
}
void hmp_set_link(Monitor *mon, const QDict *qdict)
{
const char *name = qdict_get_str(qdict, "name");
int up = qdict_get_bool(qdict, "up");
Error *errp = NULL;
Error *err = NULL;
qmp_set_link(name, up, &errp);
hmp_handle_error(mon, &errp);
qmp_set_link(name, up, &err);
hmp_handle_error(mon, &err);
}
void hmp_block_passwd(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
const char *password = qdict_get_str(qdict, "password");
Error *errp = NULL;
Error *err = NULL;
qmp_block_passwd(true, device, false, NULL, password, &errp);
hmp_handle_error(mon, &errp);
qmp_block_passwd(true, device, false, NULL, password, &err);
hmp_handle_error(mon, &err);
}
void hmp_balloon(Monitor *mon, const QDict *qdict)
{
int64_t value = qdict_get_int(qdict, "value");
Error *errp = NULL;
Error *err = NULL;
qmp_balloon(value, &errp);
if (errp) {
monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
error_free(errp);
qmp_balloon(value, &err);
if (err) {
monitor_printf(mon, "balloon: %s\n", error_get_pretty(err));
error_free(err);
}
}
......@@ -895,10 +896,10 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
int64_t size = qdict_get_int(qdict, "size");
Error *errp = NULL;
Error *err = NULL;
qmp_block_resize(true, device, false, NULL, size, &errp);
hmp_handle_error(mon, &errp);
qmp_block_resize(true, device, false, NULL, size, &err);
hmp_handle_error(mon, &err);
}
void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
......@@ -909,11 +910,11 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
int full = qdict_get_try_bool(qdict, "full", 0);
enum NewImageMode mode;
Error *errp = NULL;
Error *err = NULL;
if (!filename) {
error_set(&errp, QERR_MISSING_PARAMETER, "target");
hmp_handle_error(mon, &errp);
error_set(&err, QERR_MISSING_PARAMETER, "target");
hmp_handle_error(mon, &err);
return;
}
......@@ -926,8 +927,8 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
qmp_drive_mirror(device, filename, !!format, format,
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
true, mode, false, 0, false, 0, false, 0,
false, 0, false, 0, &errp);
hmp_handle_error(mon, &errp);
false, 0, false, 0, &err);
hmp_handle_error(mon, &err);
}
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
......@@ -938,11 +939,11 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
int full = qdict_get_try_bool(qdict, "full", 0);
enum NewImageMode mode;
Error *errp = NULL;
Error *err = NULL;
if (!filename) {
error_set(&errp, QERR_MISSING_PARAMETER, "target");
hmp_handle_error(mon, &errp);
error_set(&err, QERR_MISSING_PARAMETER, "target");
hmp_handle_error(mon, &err);
return;
}
......@@ -954,8 +955,8 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
qmp_drive_backup(device, filename, !!format, format,
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
true, mode, false, 0, false, 0, false, 0, &errp);
hmp_handle_error(mon, &errp);
true, mode, false, 0, false, 0, false, 0, &err);
hmp_handle_error(mon, &err);
}
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
......@@ -965,13 +966,13 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
const char *format = qdict_get_try_str(qdict, "format");
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
enum NewImageMode mode;
Error *errp = NULL;
Error *err = NULL;
if (!filename) {
/* In the future, if 'snapshot-file' is not specified, the snapshot
will be taken internally. Today it's actually required. */
error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
hmp_handle_error(mon, &errp);
error_set(&err, QERR_MISSING_PARAMETER, "snapshot-file");
hmp_handle_error(mon, &err);
return;
}
......@@ -979,18 +980,18 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
qmp_blockdev_snapshot_sync(true, device, false, NULL,
filename, false, NULL,
!!format, format,
true, mode, &errp);
hmp_handle_error(mon, &errp);
true, mode, &err);
hmp_handle_error(mon, &err);
}
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
const char *name = qdict_get_str(qdict, "name");
Error *errp = NULL;
Error *err = NULL;
qmp_blockdev_snapshot_internal_sync(device, name, &errp);
hmp_handle_error(mon, &errp);
qmp_blockdev_snapshot_internal_sync(device, name, &err);
hmp_handle_error(mon, &err);
}
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
......@@ -998,11 +999,11 @@ void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
const char *device = qdict_get_str(qdict, "device");
const char *name = qdict_get_str(qdict, "name");
const char *id = qdict_get_try_str(qdict, "id");
Error *errp = NULL;
Error *err = NULL;
qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
true, name, &errp);
hmp_handle_error(mon, &errp);
true, name, &err);
hmp_handle_error(mon, &err);
}
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
......@@ -1310,7 +1311,7 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
Error *err = NULL;
int paging = qdict_get_try_bool(qdict, "paging", 0);
int zlib = qdict_get_try_bool(qdict, "zlib", 0);
int lzo = qdict_get_try_bool(qdict, "lzo", 0);
......@@ -1324,8 +1325,8 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
char *prot;
if (zlib + lzo + snappy > 1) {
error_setg(&errp, "only one of '-z|-l|-s' can be set");
hmp_handle_error(mon, &errp);
error_setg(&err, "only one of '-z|-l|-s' can be set");
hmp_handle_error(mon, &err);
return;
}
......@@ -1351,8 +1352,8 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
prot = g_strconcat("file:", file, NULL);
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
true, dump_format, &errp);
hmp_handle_error(mon, &errp);
true, dump_format, &err);
hmp_handle_error(mon, &err);
g_free(prot);
}
......@@ -1444,19 +1445,19 @@ out:
void hmp_getfd(Monitor *mon, const QDict *qdict)
{
const char *fdname = qdict_get_str(qdict, "fdname");
Error *errp = NULL;
Error *err = NULL;
qmp_getfd(fdname, &errp);
hmp_handle_error(mon, &errp);
qmp_getfd(fdname, &err);
hmp_handle_error(mon, &err);
}
void hmp_closefd(Monitor *mon, const QDict *qdict)
{
const char *fdname = qdict_get_str(qdict, "fdname");
Error *errp = NULL;
Error *err = NULL;
qmp_closefd(fdname, &errp);
hmp_handle_error(mon, &errp);
qmp_closefd(fdname, &err);
hmp_handle_error(mon, &err);
}
void hmp_send_key(Monitor *mon, const QDict *qdict)
......@@ -1606,10 +1607,10 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
Error *err = NULL;
qmp_nbd_server_stop(&errp);
hmp_handle_error(mon, &errp);
qmp_nbd_server_stop(&err);
hmp_handle_error(mon, &err);
}
void hmp_cpu_add(Monitor *mon, const QDict *qdict)
......
此差异已折叠。
......@@ -2012,6 +2012,25 @@ static void pci_del_option_rom(PCIDevice *pdev)
* in pci config space */
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size)
{
int ret;
Error *local_err = NULL;
ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err);
if (local_err) {
assert(ret < 0);
error_report("%s", error_get_pretty(local_err));
error_free(local_err);
} else {
/* success implies a positive offset in config space */
assert(ret > 0);
}
return ret;
}
int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size,
Error **errp)
{
uint8_t *config;
int i, overlapping_cap;
......@@ -2019,6 +2038,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
if (!offset) {
offset = pci_find_space(pdev, size);
if (!offset) {
error_setg(errp, "out of PCI config space");
return -ENOSPC;
}
} else {
......@@ -2029,12 +2049,12 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
for (i = offset; i < offset + size; i++) {
overlapping_cap = pci_find_capability_at_offset(pdev, i);
if (overlapping_cap) {
fprintf(stderr, "ERROR: %s:%02x:%02x.%x "
"Attempt to add PCI capability %x at offset "
"%x overlaps existing capability %x at offset %x\n",
pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
cap_id, offset, overlapping_cap, i);
error_setg(errp, "%s:%02x:%02x.%x "
"Attempt to add PCI capability %x at offset "
"%x overlaps existing capability %x at offset %x",
pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
cap_id, offset, overlapping_cap, i);
return -EINVAL;
}
}
......
......@@ -6,6 +6,7 @@
#include "hw/qdev.h"
#include "exec/memory.h"
#include "sysemu/dma.h"
#include "qapi/error.h"
/* PCI includes legacy ISA access. */
#include "hw/isa/isa.h"
......@@ -308,6 +309,9 @@ pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size);
int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size,
Error **errp);
void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
......
......@@ -75,6 +75,7 @@ int monitor_read_block_device_key(Monitor *mon, const char *device,
int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp);
int monitor_handle_fd_param(Monitor *mon, const char *fdname);
int monitor_handle_fd_param2(Monitor *mon, const char *fdname, Error **errp);
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
......
......@@ -27,14 +27,16 @@ typedef struct Error Error;
* printf-style human message. This function is not meant to be used outside
* of QEMU.
*/
void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
GCC_FMT_ATTR(3, 4);
/**
* Set an indirect pointer to an error given a ErrorClass value and a
* printf-style human message, followed by a strerror() string if
* @os_error is not zero.
*/
void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
void error_set_errno(Error **errp, int os_error, ErrorClass err_class,
const char *fmt, ...) GCC_FMT_ATTR(4, 5);
#ifdef _WIN32
/**
......@@ -42,19 +44,22 @@ void error_set_errno(Error **err, int os_error, ErrorClass err_class, const char
* printf-style human message, followed by a g_win32_error_message() string if
* @win32_err is not zero.
*/
void error_set_win32(Error **err, int win32_err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_ATTR(4, 5);
void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,
const char *fmt, ...) GCC_FMT_ATTR(4, 5);
#endif
/**
* Same as error_set(), but sets a generic error
*/
#define error_setg(err, fmt, ...) \
error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#define error_setg_errno(err, os_error, fmt, ...) \
error_set_errno(err, os_error, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#define error_setg(errp, fmt, ...) \
error_set(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#define error_setg_errno(errp, os_error, fmt, ...) \
error_set_errno(errp, os_error, ERROR_CLASS_GENERIC_ERROR, \
fmt, ## __VA_ARGS__)
#ifdef _WIN32
#define error_setg_win32(err, win32_err, fmt, ...) \
error_set_win32(err, win32_err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
#define error_setg_win32(errp, win32_err, fmt, ...) \
error_set_win32(errp, win32_err, ERROR_CLASS_GENERIC_ERROR, \
fmt, ## __VA_ARGS__)
#endif
/**
......@@ -66,7 +71,7 @@ void error_setg_file_open(Error **errp, int os_errno, const char *filename);
* Returns true if an indirect pointer to an error is pointing to a valid
* error object.
*/
bool error_is_set(Error **err);
bool error_is_set(Error **errp);
/*
* Get the error class of an error object.
......@@ -88,7 +93,7 @@ const char *error_get_pretty(Error *err);
* always transfer ownership of the error reference and handles the case where
* dst_err is NULL correctly. Errors after the first are discarded.
*/
void error_propagate(Error **dst_err, Error *local_err);
void error_propagate(Error **dst_errp, Error *local_err);
/**
* Free an error object.
......
......@@ -50,7 +50,7 @@ void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
const char *qmp_command_name(const QmpCommand *cmd);
bool qmp_has_success_response(const QmpCommand *cmd);
QObject *qmp_build_error_object(Error *errp);
QObject *qmp_build_error_object(Error *err);
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
......
......@@ -2611,16 +2611,33 @@ int monitor_handle_fd_param(Monitor *mon, const char *fdname)
int fd;
Error *local_err = NULL;
if (!qemu_isdigit(fdname[0]) && mon) {
fd = monitor_handle_fd_param2(mon, fdname, &local_err);
if (local_err) {
qerror_report_err(local_err);
error_free(local_err);
}
return fd;
}
int monitor_handle_fd_param2(Monitor *mon, const char *fdname, Error **errp)
{
int fd;
Error *local_err = NULL;
if (!qemu_isdigit(fdname[0]) && mon) {
fd = monitor_get_fd(mon, fdname, &local_err);
} else {
fd = qemu_parse_fd(fdname);
if (fd == -1) {
qerror_report_err(local_err);
error_free(local_err);
return -1;
error_setg(&local_err, "Invalid file descriptor number '%s'",
fdname);
}
}
if (local_err) {
error_propagate(errp, local_err);
assert(fd == -1);
} else {
fd = qemu_parse_fd(fdname);
assert(fd != -1);
}
return fd;
......
......@@ -472,13 +472,14 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
val = strtosz_suffix(opt->str ? opt->str : "", &endptr,
STRTOSZ_DEFSUFFIX_B);
if (val != -1 && *endptr == '\0') {
*obj = val;
processed(ov, name);
if (val < 0 || *endptr) {
error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
return;
}
error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
"a size value representible as a non-negative int64");
*obj = val;
processed(ov, name);
}
......
......@@ -131,7 +131,9 @@ static void qapi_dealloc_end_list(Visitor *v, Error **errp)
static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name,
Error **errp)
{
g_free(*obj);
if (obj) {
g_free(*obj);
}
}
static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name,
......
......@@ -62,14 +62,14 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
static QObject *do_qmp_dispatch(QObject *request, Error **errp)
{
Error *local_err = NULL;
const char *command;
QDict *args, *dict;
QmpCommand *cmd;
QObject *ret = NULL;
dict = qmp_dispatch_check_obj(request, errp);
if (!dict || error_is_set(errp)) {
if (!dict) {
return NULL;
}
......@@ -94,13 +94,13 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
switch (cmd->type) {
case QCT_NORMAL:
cmd->fn(args, &ret, errp);
if (!error_is_set(errp)) {
if (cmd->options & QCO_NO_SUCCESS_RESP) {
g_assert(!ret);
} else if (!ret) {
ret = QOBJECT(qdict_new());
}
cmd->fn(args, &ret, &local_err);
if (local_err) {
error_propagate(errp, local_err);
} else if (cmd->options & QCO_NO_SUCCESS_RESP) {
g_assert(!ret);
} else if (!ret) {
ret = QOBJECT(qdict_new());
}
break;
}
......@@ -110,11 +110,11 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
return ret;
}
QObject *qmp_build_error_object(Error *errp)
QObject *qmp_build_error_object(Error *err)
{
return qobject_from_jsonf("{ 'class': %s, 'desc': %s }",
ErrorClass_lookup[error_get_class(errp)],
error_get_pretty(errp));
ErrorClass_lookup[error_get_class(err)],
error_get_pretty(err));
}
QObject *qmp_dispatch(QObject *request)
......
此差异已折叠。
......@@ -29,16 +29,12 @@
(365 * (1970 - 1601) + \
(1970 - 1601) / 4 - 3))
static void acquire_privilege(const char *name, Error **err)
static void acquire_privilege(const char *name, Error **errp)
{
HANDLE token;
TOKEN_PRIVILEGES priv;
Error *local_err = NULL;
if (error_is_set(err)) {
return;
}
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &token))
{
......@@ -65,27 +61,26 @@ static void acquire_privilege(const char *name, Error **err)
out:
if (local_err) {
error_propagate(err, local_err);
error_propagate(errp, local_err);
}
}
static void execute_async(DWORD WINAPI (*func)(LPVOID), LPVOID opaque, Error **err)
static void execute_async(DWORD WINAPI (*func)(LPVOID), LPVOID opaque,
Error **errp)
{
Error *local_err = NULL;
if (error_is_set(err)) {
return;
}
HANDLE thread = CreateThread(NULL, 0, func, opaque, 0, NULL);
if (!thread) {
error_set(&local_err, QERR_QGA_COMMAND_FAILED,
"failed to dispatch asynchronous command");
error_propagate(err, local_err);
error_propagate(errp, local_err);
}
}
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
{
Error *local_err = NULL;
UINT shutdown_flag = EWX_FORCE;
slog("guest-shutdown called, mode: %s", mode);
......@@ -97,68 +92,71 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **err)
} else if (strcmp(mode, "reboot") == 0) {
shutdown_flag |= EWX_REBOOT;
} else {
error_set(err, QERR_INVALID_PARAMETER_VALUE, "mode",
error_set(errp, QERR_INVALID_PARAMETER_VALUE, "mode",
"halt|powerdown|reboot");
return;
}
/* Request a shutdown privilege, but try to shut down the system
anyway. */
acquire_privilege(SE_SHUTDOWN_NAME, err);
if (error_is_set(err)) {
acquire_privilege(SE_SHUTDOWN_NAME, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
if (!ExitWindowsEx(shutdown_flag, SHTDN_REASON_FLAG_PLANNED)) {
slog("guest-shutdown failed: %lu", GetLastError());
error_set(err, QERR_UNDEFINED_ERROR);
error_set(errp, QERR_UNDEFINED_ERROR);
}
}
int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)
int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
void qmp_guest_file_close(int64_t handle, Error **err)
void qmp_guest_file_close(int64_t handle, Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
}
GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
int64_t count, Error **err)
int64_t count, Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
bool has_count, int64_t count, Error **err)
bool has_count, int64_t count,
Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
int64_t whence, Error **err)
int64_t whence, Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
void qmp_guest_file_flush(int64_t handle, Error **err)
void qmp_guest_file_flush(int64_t handle, Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
}
/*
* Return status of freeze/thaw
*/
GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
{
if (!vss_initialized()) {
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
......@@ -173,13 +171,13 @@ GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **err)
* Freeze local file systems using Volume Shadow-copy Service.
* The frozen state is limited for up to 10 seconds by VSS.
*/
int64_t qmp_guest_fsfreeze_freeze(Error **err)
int64_t qmp_guest_fsfreeze_freeze(Error **errp)
{
int i;
Error *local_err = NULL;
if (!vss_initialized()) {
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
......@@ -188,14 +186,16 @@ int64_t qmp_guest_fsfreeze_freeze(Error **err)
/* cannot risk guest agent blocking itself on a write in this state */
ga_set_frozen(ga_state);
qga_vss_fsfreeze(&i, err, true);
if (error_is_set(err)) {
qga_vss_fsfreeze(&i, &local_err, true);
if (local_err) {
error_propagate(errp, local_err);
goto error;
}
return i;
error:
local_err = NULL;
qmp_guest_fsfreeze_thaw(&local_err);
if (local_err) {
g_debug("cleanup thaw: %s", error_get_pretty(local_err));
......@@ -207,16 +207,16 @@ error:
/*
* Thaw local file systems using Volume Shadow-copy Service.
*/
int64_t qmp_guest_fsfreeze_thaw(Error **err)
int64_t qmp_guest_fsfreeze_thaw(Error **errp)
{
int i;
if (!vss_initialized()) {
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return 0;
}
qga_vss_fsfreeze(&i, err, false);
qga_vss_fsfreeze(&i, errp, false);
ga_unset_frozen(ga_state);
return i;
......@@ -246,9 +246,9 @@ static void guest_fsfreeze_cleanup(void)
* Walk list of mounted file systems in the guest, and discard unused
* areas.
*/
void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **err)
void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
}
typedef enum {
......@@ -256,14 +256,11 @@ typedef enum {
GUEST_SUSPEND_MODE_RAM
} GuestSuspendMode;
static void check_suspend_mode(GuestSuspendMode mode, Error **err)
static void check_suspend_mode(GuestSuspendMode mode, Error **errp)
{
SYSTEM_POWER_CAPABILITIES sys_pwr_caps;
Error *local_err = NULL;
if (error_is_set(err)) {
return;
}
ZeroMemory(&sys_pwr_caps, sizeof(sys_pwr_caps));
if (!GetPwrCapabilities(&sys_pwr_caps)) {
error_set(&local_err, QERR_QGA_COMMAND_FAILED,
......@@ -291,7 +288,7 @@ static void check_suspend_mode(GuestSuspendMode mode, Error **err)
out:
if (local_err) {
error_propagate(err, local_err);
error_propagate(errp, local_err);
}
}
......@@ -308,42 +305,46 @@ static DWORD WINAPI do_suspend(LPVOID opaque)
return ret;
}
void qmp_guest_suspend_disk(Error **err)
void qmp_guest_suspend_disk(Error **errp)
{
Error *local_err = NULL;
GuestSuspendMode *mode = g_malloc(sizeof(GuestSuspendMode));
*mode = GUEST_SUSPEND_MODE_DISK;
check_suspend_mode(*mode, err);
acquire_privilege(SE_SHUTDOWN_NAME, err);
execute_async(do_suspend, mode, err);
check_suspend_mode(*mode, &local_err);
acquire_privilege(SE_SHUTDOWN_NAME, &local_err);
execute_async(do_suspend, mode, &local_err);
if (error_is_set(err)) {
if (local_err) {
error_propagate(errp, local_err);
g_free(mode);
}
}
void qmp_guest_suspend_ram(Error **err)
void qmp_guest_suspend_ram(Error **errp)
{
Error *local_err = NULL;
GuestSuspendMode *mode = g_malloc(sizeof(GuestSuspendMode));
*mode = GUEST_SUSPEND_MODE_RAM;
check_suspend_mode(*mode, err);
acquire_privilege(SE_SHUTDOWN_NAME, err);
execute_async(do_suspend, mode, err);
check_suspend_mode(*mode, &local_err);
acquire_privilege(SE_SHUTDOWN_NAME, &local_err);
execute_async(do_suspend, mode, &local_err);
if (error_is_set(err)) {
if (local_err) {
error_propagate(errp, local_err);
g_free(mode);
}
}
void qmp_guest_suspend_hybrid(Error **err)
void qmp_guest_suspend_hybrid(Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
}
GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **err)
GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
{
error_set(err, QERR_UNSUPPORTED);
error_set(errp, QERR_UNSUPPORTED);
return NULL;
}
......@@ -372,6 +373,7 @@ int64_t qmp_guest_get_time(Error **errp)
void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
{
Error *local_err = NULL;
SYSTEMTIME ts;
FILETIME tf;
LONGLONG time;
......@@ -403,8 +405,9 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
}
}
acquire_privilege(SE_SYSTEMTIME_NAME, errp);
if (error_is_set(errp)) {
acquire_privilege(SE_SYSTEMTIME_NAME, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
......
......@@ -40,7 +40,7 @@ int64_t qmp_guest_sync(int64_t id, Error **errp)
return id;
}
void qmp_guest_ping(Error **err)
void qmp_guest_ping(Error **errp)
{
slog("guest-ping called");
}
......@@ -62,7 +62,7 @@ static void qmp_command_info(QmpCommand *cmd, void *opaque)
info->supported_commands = cmd_info_list;
}
struct GuestAgentInfo *qmp_guest_info(Error **err)
struct GuestAgentInfo *qmp_guest_info(Error **errp)
{
GuestAgentInfo *info = g_malloc0(sizeof(GuestAgentInfo));
......
......@@ -910,6 +910,7 @@ int64_t ga_get_fd_handle(GAState *s, Error **errp)
if (!write_persistent_state(&s->pstate, s->pstate_filepath)) {
error_setg(errp, "failed to commit persistent state to disk");
return -1;
}
return handle;
......
......@@ -145,19 +145,19 @@ void ga_uninstall_vss_provider(void)
}
/* Call VSS requester and freeze/thaw filesystems and applications */
void qga_vss_fsfreeze(int *nr_volume, Error **err, bool freeze)
void qga_vss_fsfreeze(int *nr_volume, Error **errp, bool freeze)
{
const char *func_name = freeze ? "requester_freeze" : "requester_thaw";
QGAVSSRequesterFunc func;
ErrorSet errset = {
.error_set = (ErrorSetFunc)error_set_win32,
.errp = (void **)err,
.errp = (void **)errp,
.err_class = ERROR_CLASS_GENERIC_ERROR
};
func = (QGAVSSRequesterFunc)GetProcAddress(provider_lib, func_name);
if (!func) {
error_setg_win32(err, GetLastError(), "failed to load %s from %s",
error_setg_win32(errp, GetLastError(), "failed to load %s from %s",
func_name, QGA_VSS_DLL);
return;
}
......
......@@ -22,6 +22,6 @@ bool vss_initialized(void);
int ga_install_vss_provider(void);
void ga_uninstall_vss_provider(void);
void qga_vss_fsfreeze(int *nr_volume, Error **err, bool freeze);
void qga_vss_fsfreeze(int *nr_volume, Error **errp, bool freeze);
#endif
......@@ -1165,19 +1165,19 @@ Example:
-> { "execute": "transaction",
"arguments": { "actions": [
{ 'type': 'blockdev-snapshot-sync', 'data' : { "device": "ide-hd0",
{ "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd0",
"snapshot-file": "/some/place/my-image",
"format": "qcow2" } },
{ 'type': 'blockdev-snapshot-sync', 'data' : { "node-name": "myfile",
{ "type": "blockdev-snapshot-sync", "data" : { "node-name": "myfile",
"snapshot-file": "/some/place/my-image2",
"snapshot-node-name": "node3432",
"mode": "existing",
"format": "qcow2" } },
{ 'type': 'blockdev-snapshot-sync', 'data' : { "device": "ide-hd1",
{ "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd1",
"snapshot-file": "/some/place/my-image2",
"mode": "existing",
"format": "qcow2" } },
{ 'type': 'blockdev-snapshot-internal-sync', 'data' : {
{ "type": "blockdev-snapshot-internal-sync", "data" : {
"device": "ide-hd2",
"name": "snapshot0" } } ] } }
<- { "return": {} }
......
......@@ -41,7 +41,7 @@ NameInfo *qmp_query_name(Error **errp)
return info;
}
VersionInfo *qmp_query_version(Error **err)
VersionInfo *qmp_query_version(Error **errp)
{
VersionInfo *info = g_malloc0(sizeof(*info));
const char *version = QEMU_VERSION;
......@@ -82,7 +82,7 @@ UuidInfo *qmp_query_uuid(Error **errp)
return info;
}
void qmp_quit(Error **err)
void qmp_quit(Error **errp)
{
no_shutdown = 0;
qemu_system_shutdown_request();
......@@ -146,24 +146,9 @@ SpiceInfo *qmp_query_spice(Error **errp)
};
#endif
static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs)
{
bdrv_iostatus_reset(bs);
}
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
{
Error **err = opaque;
if (!error_is_set(err) && bdrv_key_required(bs)) {
error_set(err, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
}
}
void qmp_cont(Error **errp)
{
Error *local_err = NULL;
BlockDriverState *bs;
if (runstate_needs_reset()) {
error_setg(errp, "Resetting the Virtual Machine is required");
......@@ -172,11 +157,16 @@ void qmp_cont(Error **errp)
return;
}
bdrv_iterate(iostatus_bdrv_it, NULL);
bdrv_iterate(encrypted_bdrv_it, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
bdrv_iostatus_reset(bs);
}
for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
if (bdrv_key_required(bs)) {
error_set(errp, QERR_DEVICE_ENCRYPTED,
bdrv_get_device_name(bs),
bdrv_get_encrypted_filename(bs));
return;
}
}
if (runstate_check(RUN_STATE_INMIGRATE)) {
......@@ -405,12 +395,12 @@ static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
#endif /* !CONFIG_VNC */
void qmp_change(const char *device, const char *target,
bool has_arg, const char *arg, Error **err)
bool has_arg, const char *arg, Error **errp)
{
if (strcmp(device, "vnc") == 0) {
qmp_change_vnc(target, has_arg, arg, err);
qmp_change_vnc(target, has_arg, arg, errp);
} else {
qmp_change_blockdev(device, target, arg, err);
qmp_change_blockdev(device, target, arg, errp);
}
}
......
......@@ -369,9 +369,10 @@ def gen_command_def_prologue(prefix="", proxy=False):
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:m",
["source", "header", "prefix=",
"output-dir=", "type=", "middle"])
"input-file=", "output-dir=",
"type=", "middle"])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
......@@ -389,6 +390,8 @@ do_h = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
elif o in ("-i", "--input-file"):
input_file = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-t", "--type"):
......@@ -420,7 +423,7 @@ except os.error, e:
if e.errno != errno.EEXIST:
raise
exprs = parse_schema(sys.stdin)
exprs = parse_schema(input_file)
commands = filter(lambda expr: expr.has_key('command'), exprs)
commands = filter(lambda expr: not expr.has_key('gen'), commands)
......
......@@ -279,14 +279,15 @@ void qapi_free_%(type)s(%(c_type)s obj)
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
["source", "header", "builtins",
"prefix=", "output-dir="])
"prefix=", "input-file=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
output_dir = ""
input_file = ""
prefix = ""
c_file = 'qapi-types.c'
h_file = 'qapi-types.h'
......@@ -298,6 +299,8 @@ do_builtins = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
elif o in ("-i", "--input-file"):
input_file = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-c", "--source"):
......@@ -378,7 +381,7 @@ fdecl.write(mcgen('''
''',
guard=guardname(h_file)))
exprs = parse_schema(sys.stdin)
exprs = parse_schema(input_file)
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
fdecl.write(guardstart("QAPI_TYPES_BUILTIN_STRUCT_DECL"))
......
......@@ -397,13 +397,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
name=name)
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:o:",
opts, args = getopt.gnu_getopt(sys.argv[1:], "chbp:i:o:",
["source", "header", "builtins", "prefix=",
"output-dir="])
"input-file=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
input_file = ""
output_dir = ""
prefix = ""
c_file = 'qapi-visit.c'
......@@ -416,6 +417,8 @@ do_builtins = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
elif o in ("-i", "--input-file"):
input_file = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-c", "--source"):
......@@ -494,7 +497,7 @@ fdecl.write(mcgen('''
''',
prefix=prefix, guard=guardname(h_file)))
exprs = parse_schema(sys.stdin)
exprs = parse_schema(input_file)
# to avoid header dependency hell, we always generate declarations
# for built-in types in our header files and simply guard them
......
......@@ -11,7 +11,9 @@
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
import re
from ordereddict import OrderedDict
import os
import sys
builtin_types = [
......@@ -35,9 +37,17 @@ builtin_type_qtypes = {
'uint64': 'QTYPE_QINT',
}
def error_path(parent):
res = ""
while parent:
res = ("In file included from %s:%d:\n" % (parent['file'],
parent['line'])) + res
parent = parent['parent']
return res
class QAPISchemaError(Exception):
def __init__(self, schema, msg):
self.fp = schema.fp
self.input_file = schema.input_file
self.msg = msg
self.col = 1
self.line = schema.line
......@@ -46,23 +56,31 @@ class QAPISchemaError(Exception):
self.col = (self.col + 7) % 8 + 1
else:
self.col += 1
self.info = schema.parent_info
def __str__(self):
return "%s:%s:%s: %s" % (self.fp.name, self.line, self.col, self.msg)
return error_path(self.info) + \
"%s:%d:%d: %s" % (self.input_file, self.line, self.col, self.msg)
class QAPIExprError(Exception):
def __init__(self, expr_info, msg):
self.fp = expr_info['fp']
self.line = expr_info['line']
self.info = expr_info
self.msg = msg
def __str__(self):
return "%s:%s: %s" % (self.fp.name, self.line, self.msg)
return error_path(self.info['parent']) + \
"%s:%d: %s" % (self.info['file'], self.info['line'], self.msg)
class QAPISchema:
def __init__(self, fp):
self.fp = fp
def __init__(self, fp, input_relname=None, include_hist=[], parent_info=None):
input_fname = os.path.abspath(fp.name)
if input_relname is None:
input_relname = fp.name
self.input_dir = os.path.dirname(input_fname)
self.input_file = input_relname
self.include_hist = include_hist + [(input_relname, input_fname)]
self.parent_info = parent_info
self.src = fp.read()
if self.src == '' or self.src[-1] != '\n':
self.src += '\n'
......@@ -73,10 +91,33 @@ class QAPISchema:
self.accept()
while self.tok != None:
expr_info = {'fp': fp, 'line': self.line}
expr_elem = {'expr': self.get_expr(False),
'info': expr_info}
self.exprs.append(expr_elem)
expr_info = {'file': input_relname, 'line': self.line, 'parent': self.parent_info}
expr = self.get_expr(False)
if isinstance(expr, dict) and "include" in expr:
if len(expr) != 1:
raise QAPIExprError(expr_info, "Invalid 'include' directive")
include = expr["include"]
if not isinstance(include, str):
raise QAPIExprError(expr_info,
'Expected a file name (string), got: %s'
% include)
include_path = os.path.join(self.input_dir, include)
if any(include_path == elem[1]
for elem in self.include_hist):
raise QAPIExprError(expr_info, "Inclusion loop for %s"
% include)
try:
fobj = open(include_path, 'r')
except IOError as e:
raise QAPIExprError(expr_info,
'%s: %s' % (e.strerror, include))
exprs_include = QAPISchema(fobj, include,
self.include_hist, expr_info)
self.exprs.extend(exprs_include.exprs)
else:
expr_elem = {'expr': expr,
'info': expr_info}
self.exprs.append(expr_elem)
def accept(self):
while True:
......@@ -263,10 +304,10 @@ def check_exprs(schema):
if expr.has_key('union'):
check_union(expr, expr_elem['info'])
def parse_schema(fp):
def parse_schema(input_file):
try:
schema = QAPISchema(fp)
except QAPISchemaError, e:
schema = QAPISchema(open(input_file, "r"))
except (QAPISchemaError, QAPIExprError), e:
print >>sys.stderr, e
exit(1)
......
......@@ -190,7 +190,10 @@ check-qapi-schema-y := $(addprefix tests/qapi-schema/, \
duplicate-key.json union-invalid-base.json flat-union-no-base.json \
flat-union-invalid-discriminator.json \
flat-union-invalid-branch-key.json flat-union-reverse-define.json \
flat-union-string-discriminator.json)
flat-union-string-discriminator.json \
include-simple.json include-relpath.json include-format-err.json \
include-non-file.json include-no-file.json include-before-err.json \
include-nested-err.json include-self-cycle.json include-cycle.json)
GENERATED_HEADERS += tests/test-qapi-types.h tests/test-qapi-visit.h tests/test-qmp-commands.h
......@@ -242,13 +245,19 @@ tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
tests/test-qapi-types.c tests/test-qapi-types.h :\
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
$(gen-out-type) -o tests -p "test-" -i $<, \
" GEN $@")
tests/test-qapi-visit.c tests/test-qapi-visit.h :\
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
$(gen-out-type) -o tests -p "test-" -i $<, \
" GEN $@")
tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o tests -p "test-" < $<, " GEN $@")
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
$(gen-out-type) -o tests -p "test-" -i $<, \
" GEN $@")
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
......@@ -400,9 +409,14 @@ check-tests/test-qapi.py: tests/test-qapi.py
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py <$^ >$*.test.out 2>$*.test.err; echo $$? >$*.test.exit, " TEST $*.out")
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
$(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
$^ >$*.test.out 2>$*.test.err; \
echo $$? >$*.test.exit, \
" TEST $*.out")
@diff -q $(SRC_PATH)/$*.out $*.test.out
@diff -q $(SRC_PATH)/$*.err $*.test.err
@# Sanitize error messages (make them independent of build directory)
@perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -q $(SRC_PATH)/$*.err -
@diff -q $(SRC_PATH)/$*.exit $*.test.exit
# Consolidated targets
......
<stdin>:2:10: Duplicate key "key"
tests/qapi-schema/duplicate-key.json:2:10: Duplicate key "key"
<stdin>:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
tests/qapi-schema/flat-union-invalid-branch-key.json:13: Discriminator value 'value_wrong' is not found in enum 'TestEnum'
<stdin>:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
tests/qapi-schema/flat-union-invalid-discriminator.json:13: Discriminator 'enum_wrong' is not a member of base type 'TestBase'
<stdin>:7: Flat union 'TestUnion' must have a base field
tests/qapi-schema/flat-union-no-base.json:7: Flat union 'TestUnion' must have a base field
<stdin>:13: Discriminator 'kind' must be of enumeration type
tests/qapi-schema/flat-union-string-discriminator.json:13: Discriminator 'kind' must be of enumeration type
<stdin>:2:36: Stray ";"
tests/qapi-schema/funny-char.json:2:36: Stray ";"
tests/qapi-schema/include-before-err.json:2:13: Expected ":"
{ 'include': 'include-simple-sub.json' }
{ 'command' 'missing-colon' }
{ 'include': 'include-cycle-c.json' }
{ 'include': 'include-cycle.json' }
In file included from tests/qapi-schema/include-cycle.json:1:
In file included from include-cycle-b.json:1:
include-cycle-c.json:1: Inclusion loop for include-cycle.json
{ 'include': 'include-cycle-b.json' }
tests/qapi-schema/include-format-err.json:1: Invalid 'include' directive
{ 'include': 'include-simple-sub.json',
'foo': 'bar' }
In file included from tests/qapi-schema/include-nested-err.json:1:
missing-colon.json:1:10: Expected ":"
{ 'include': 'missing-colon.json' }
tests/qapi-schema/include-no-file.json:1: No such file or directory: include-no-file-sub.json
{ 'include': 'include-no-file-sub.json' }
tests/qapi-schema/include-non-file.json:1: Expected a file name (string), got: ['foo', 'bar']
{ 'include': [ 'foo', 'bar' ] }
{ 'enum': 'Status',
'data': [ 'good', 'bad', 'ugly' ] }
{ 'include': 'include/relpath.json' }
[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
[]
tests/qapi-schema/include-self-cycle.json:1: Inclusion loop for include-self-cycle.json
{ 'include': 'include-self-cycle.json' }
{ 'enum': 'Status',
'data': [ 'good', 'bad', 'ugly' ] }
{ 'include': 'include-simple-sub.json' }
[OrderedDict([('enum', 'Status'), ('data', ['good', 'bad', 'ugly'])])]
[{'enum_name': 'Status', 'enum_values': ['good', 'bad', 'ugly']}]
[]
{ 'include': '../include-relpath-sub.json' }
<stdin>:1:10: Expected ":"
tests/qapi-schema/missing-colon.json:1:10: Expected ":"
<stdin>:2:20: Expected "," or "]"
tests/qapi-schema/missing-comma-list.json:2:20: Expected "," or "]"
<stdin>:2:3: Expected "," or "}"
tests/qapi-schema/missing-comma-object.json:2:3: Expected "," or "}"
<stdin>:1:1: Expected "{"
tests/qapi-schema/non-objects.json:1:1: Expected "{"
<stdin>:1:1: Expected "{"
tests/qapi-schema/quoted-structural-chars.json:1:1: Expected "{"
......@@ -12,15 +12,13 @@
from qapi import *
from pprint import pprint
import os
import sys
try:
exprs = parse_schema(sys.stdin)
exprs = parse_schema(sys.argv[1])
except SystemExit:
raise
except:
print >>sys.stderr, "Crashed:", sys.exc_info()[0]
exit(1)
pprint(exprs)
pprint(enum_types)
......
<stdin>:2:36: Expected "{", "[" or string
tests/qapi-schema/trailing-comma-list.json:2:36: Expected "{", "[" or string
<stdin>:2:38: Expected string
tests/qapi-schema/trailing-comma-object.json:2:38: Expected string
<stdin>:1:20: Expected "," or "]"
tests/qapi-schema/unclosed-list.json:1:20: Expected "," or "]"
<stdin>:1:21: Expected "," or "}"
tests/qapi-schema/unclosed-object.json:1:21: Expected "," or "}"
<stdin>:1:11: Missing terminating "'"
tests/qapi-schema/unclosed-string.json:1:11: Missing terminating "'"
<stdin>:7: Base 'TestBaseWrong' is not a valid type
tests/qapi-schema/union-invalid-base.json:7: Base 'TestBaseWrong' is not a valid type
......@@ -86,13 +86,13 @@ static void test_validate_struct(TestInputVisitorData *data,
const void *unused)
{
TestStruct *p = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
visit_type_TestStruct(v, &p, NULL, &errp);
g_assert(!errp);
visit_type_TestStruct(v, &p, NULL, &err);
g_assert(!err);
g_free(p->string);
g_free(p);
}
......@@ -101,13 +101,13 @@ static void test_validate_struct_nested(TestInputVisitorData *data,
const void *unused)
{
UserDefNested *udp = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
g_assert(!errp);
visit_type_UserDefNested(v, &udp, NULL, &err);
g_assert(!err);
qapi_free_UserDefNested(udp);
}
......@@ -115,13 +115,13 @@ static void test_validate_list(TestInputVisitorData *data,
const void *unused)
{
UserDefOneList *head = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
g_assert(!errp);
visit_type_UserDefOneList(v, &head, NULL, &err);
g_assert(!err);
qapi_free_UserDefOneList(head);
}
......@@ -130,12 +130,12 @@ static void test_validate_union(TestInputVisitorData *data,
{
UserDefUnion *tmp = NULL;
Visitor *v;
Error *errp = NULL;
Error *err = NULL;
v = validate_test_init(data, "{ 'type': 'b', 'integer': 41, 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
g_assert(!errp);
visit_type_UserDefUnion(v, &tmp, NULL, &err);
g_assert(!err);
qapi_free_UserDefUnion(tmp);
}
......@@ -144,7 +144,7 @@ static void test_validate_union_flat(TestInputVisitorData *data,
{
UserDefFlatUnion *tmp = NULL;
Visitor *v;
Error *errp = NULL;
Error *err = NULL;
v = validate_test_init(data,
"{ 'enum1': 'value1', "
......@@ -152,8 +152,8 @@ static void test_validate_union_flat(TestInputVisitorData *data,
"'boolean': true }");
/* TODO when generator bug is fixed, add 'integer': 41 */
visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
g_assert(!errp);
visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
g_assert(!err);
qapi_free_UserDefFlatUnion(tmp);
}
......@@ -162,12 +162,12 @@ static void test_validate_union_anon(TestInputVisitorData *data,
{
UserDefAnonUnion *tmp = NULL;
Visitor *v;
Error *errp = NULL;
Error *err = NULL;
v = validate_test_init(data, "42");
visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
g_assert(!errp);
visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
g_assert(!err);
qapi_free_UserDefAnonUnion(tmp);
}
......@@ -175,13 +175,13 @@ static void test_validate_fail_struct(TestInputVisitorData *data,
const void *unused)
{
TestStruct *p = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }");
visit_type_TestStruct(v, &p, NULL, &errp);
g_assert(errp);
visit_type_TestStruct(v, &p, NULL, &err);
g_assert(err);
if (p) {
g_free(p->string);
}
......@@ -192,13 +192,13 @@ static void test_validate_fail_struct_nested(TestInputVisitorData *data,
const void *unused)
{
UserDefNested *udp = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
g_assert(errp);
visit_type_UserDefNested(v, &udp, NULL, &err);
g_assert(err);
qapi_free_UserDefNested(udp);
}
......@@ -206,13 +206,13 @@ static void test_validate_fail_list(TestInputVisitorData *data,
const void *unused)
{
UserDefOneList *head = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
g_assert(errp);
visit_type_UserDefOneList(v, &head, NULL, &err);
g_assert(err);
qapi_free_UserDefOneList(head);
}
......@@ -220,13 +220,13 @@ static void test_validate_fail_union(TestInputVisitorData *data,
const void *unused)
{
UserDefUnion *tmp = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }");
visit_type_UserDefUnion(v, &tmp, NULL, &errp);
g_assert(errp);
visit_type_UserDefUnion(v, &tmp, NULL, &err);
g_assert(err);
qapi_free_UserDefUnion(tmp);
}
......@@ -234,13 +234,13 @@ static void test_validate_fail_union_flat(TestInputVisitorData *data,
const void *unused)
{
UserDefFlatUnion *tmp = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }");
visit_type_UserDefFlatUnion(v, &tmp, NULL, &errp);
g_assert(errp);
visit_type_UserDefFlatUnion(v, &tmp, NULL, &err);
g_assert(err);
qapi_free_UserDefFlatUnion(tmp);
}
......@@ -249,12 +249,12 @@ static void test_validate_fail_union_anon(TestInputVisitorData *data,
{
UserDefAnonUnion *tmp = NULL;
Visitor *v;
Error *errp = NULL;
Error *err = NULL;
v = validate_test_init(data, "3.14");
visit_type_UserDefAnonUnion(v, &tmp, NULL, &errp);
g_assert(errp);
visit_type_UserDefAnonUnion(v, &tmp, NULL, &err);
g_assert(err);
qapi_free_UserDefAnonUnion(tmp);
}
......
......@@ -90,13 +90,13 @@ static void test_visitor_in_int(TestInputVisitorData *data,
const void *unused)
{
int64_t res = 0, value = -42;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "%" PRId64, value);
visit_type_int(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_int(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
}
......@@ -104,7 +104,7 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
const void *unused)
{
int64_t res = 0;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
/* this will overflow a Qint/int64, so should be deserialized into
......@@ -113,22 +113,22 @@ static void test_visitor_in_int_overflow(TestInputVisitorData *data,
*/
v = visitor_input_test_init(data, "%f", DBL_MAX);
visit_type_int(v, &res, NULL, &errp);
g_assert(errp);
error_free(errp);
visit_type_int(v, &res, NULL, &err);
g_assert(err);
error_free(err);
}
static void test_visitor_in_bool(TestInputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
bool res = false;
Visitor *v;
v = visitor_input_test_init(data, "true");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, true);
}
......@@ -136,13 +136,13 @@ static void test_visitor_in_number(TestInputVisitorData *data,
const void *unused)
{
double res = 0, value = 3.14;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "%f", value);
visit_type_number(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_number(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpfloat(res, ==, value);
}
......@@ -150,13 +150,13 @@ static void test_visitor_in_string(TestInputVisitorData *data,
const void *unused)
{
char *res = NULL, *value = (char *) "Q E M U";
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "%s", value);
visit_type_str(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_str(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpstr(res, ==, value);
g_free(res);
......@@ -165,7 +165,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
static void test_visitor_in_enum(TestInputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
EnumOne i;
......@@ -174,8 +174,8 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
v = visitor_input_test_init(data, "%s", EnumOne_lookup[i]);
visit_type_EnumOne(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_EnumOne(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(i, ==, res);
visitor_input_teardown(data, NULL);
......@@ -196,34 +196,33 @@ static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
const char *name, Error **errp)
{
Error *err = NULL;
if (!error_is_set(errp)) {
visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
&err);
if (!err) {
visit_type_int(v, &(*obj)->integer, "integer", &err);
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
visit_type_str(v, &(*obj)->string, "string", &err);
/* Always call end_struct if start_struct succeeded. */
error_propagate(errp, err);
err = NULL;
visit_end_struct(v, &err);
}
visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
&err);
if (!err) {
visit_type_int(v, &(*obj)->integer, "integer", &err);
visit_type_bool(v, &(*obj)->boolean, "boolean", &err);
visit_type_str(v, &(*obj)->string, "string", &err);
/* Always call end_struct if start_struct succeeded. */
error_propagate(errp, err);
err = NULL;
visit_end_struct(v, &err);
}
error_propagate(errp, err);
}
static void test_visitor_in_struct(TestInputVisitorData *data,
const void *unused)
{
TestStruct *p = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");
visit_type_TestStruct(v, &p, NULL, &errp);
g_assert(!errp);
visit_type_TestStruct(v, &p, NULL, &err);
g_assert(!err);
g_assert_cmpint(p->integer, ==, -42);
g_assert(p->boolean == true);
g_assert_cmpstr(p->string, ==, "foo");
......@@ -242,13 +241,13 @@ static void test_visitor_in_struct_nested(TestInputVisitorData *data,
const void *unused)
{
UserDefNested *udp = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}");
visit_type_UserDefNested(v, &udp, NULL, &errp);
g_assert(!errp);
visit_type_UserDefNested(v, &udp, NULL, &err);
g_assert(!err);
check_and_free_str(udp->string0, "string0");
check_and_free_str(udp->dict1.string1, "string1");
......@@ -265,14 +264,14 @@ static void test_visitor_in_list(TestInputVisitorData *data,
const void *unused)
{
UserDefOneList *item, *head = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
int i;
v = visitor_input_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]");
visit_type_UserDefOneList(v, &head, NULL, &errp);
g_assert(!errp);
visit_type_UserDefOneList(v, &head, NULL, &err);
g_assert(!err);
g_assert(head != NULL);
for (i = 0, item = head; item; item = item->next, i++) {
......@@ -634,16 +633,16 @@ static void test_visitor_in_errors(TestInputVisitorData *data,
const void *unused)
{
TestStruct *p = NULL;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "{ 'integer': false, 'boolean': 'foo', 'string': -42 }");
visit_type_TestStruct(v, &p, NULL, &errp);
g_assert(errp);
visit_type_TestStruct(v, &p, NULL, &err);
g_assert(err);
g_assert(p->string == NULL);
error_free(errp);
error_free(err);
g_free(p->string);
g_free(p);
}
......
......@@ -45,11 +45,11 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
const void *unused)
{
int64_t value = -42;
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
visit_type_int(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_int(data->ov, &value, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -62,12 +62,12 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
static void test_visitor_out_bool(TestOutputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
bool value = true;
QObject *obj;
visit_type_bool(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_bool(data->ov, &value, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -81,11 +81,11 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
const void *unused)
{
double value = 3.14;
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
visit_type_number(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_number(data->ov, &value, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -99,11 +99,11 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
const void *unused)
{
char *string = (char *) "Q E M U";
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
visit_type_str(data->ov, &string, NULL, &errp);
g_assert(!errp);
visit_type_str(data->ov, &string, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -117,12 +117,12 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
const void *unused)
{
char *string = NULL;
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
/* A null string should return "" */
visit_type_str(data->ov, &string, NULL, &errp);
g_assert(!errp);
visit_type_str(data->ov, &string, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -135,13 +135,13 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
static void test_visitor_out_enum(TestOutputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
EnumOne i;
for (i = 0; i < ENUM_ONE_MAX; i++) {
visit_type_EnumOne(data->ov, &i, "unused", &errp);
g_assert(!errp);
visit_type_EnumOne(data->ov, &i, "unused", &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -156,13 +156,13 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
const void *unused)
{
EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
Error *errp;
Error *err;
for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
errp = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
g_assert(errp);
error_free(errp);
err = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &err);
g_assert(err);
error_free(err);
}
}
......@@ -193,12 +193,12 @@ static void test_visitor_out_struct(TestOutputVisitorData *data,
.boolean = false,
.string = (char *) "foo"};
TestStruct *p = &test_struct;
Error *errp = NULL;
Error *err = NULL;
QObject *obj;
QDict *qdict;
visit_type_TestStruct(data->ov, &p, NULL, &errp);
g_assert(!errp);
visit_type_TestStruct(data->ov, &p, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -217,7 +217,7 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
const void *unused)
{
int64_t value = 42;
Error *errp = NULL;
Error *err = NULL;
UserDefNested *ud2;
QObject *obj;
QDict *qdict, *dict1, *dict2, *dict3, *userdef;
......@@ -242,8 +242,8 @@ static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
ud2->dict1.dict3.userdef2->base->integer = value;
ud2->dict1.dict3.string3 = g_strdup(strings[3]);
visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
g_assert(!errp);
visit_type_UserDefNested(data->ov, &ud2, "unused", &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......@@ -283,16 +283,16 @@ static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
UserDefZero b;
UserDefOne u = { .base = &b }, *pu = &u;
Error *errp;
Error *err;
int i;
for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
errp = NULL;
err = NULL;
u.has_enum1 = true;
u.enum1 = bad_values[i];
visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
g_assert(errp);
error_free(errp);
visit_type_UserDefOne(data->ov, &pu, "unused", &err);
g_assert(err);
error_free(err);
}
}
......@@ -328,7 +328,7 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
const int max_items = 10;
bool value_bool = true;
int value_int = 10;
Error *errp = NULL;
Error *err = NULL;
QListEntry *entry;
QObject *obj;
QList *qlist;
......@@ -345,8 +345,8 @@ static void test_visitor_out_list(TestOutputVisitorData *data,
head = p;
}
visit_type_TestStructList(data->ov, &head, NULL, &errp);
g_assert(!errp);
visit_type_TestStructList(data->ov, &head, NULL, &err);
g_assert(!err);
obj = qmp_output_get_qobject(data->qov);
g_assert(obj != NULL);
......
......@@ -54,62 +54,62 @@ static void test_visitor_in_int(TestInputVisitorData *data,
const void *unused)
{
int64_t res = 0, value = -42;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "-42");
visit_type_int(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_int(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
}
static void test_visitor_in_bool(TestInputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
bool res = false;
Visitor *v;
v = visitor_input_test_init(data, "true");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "yes");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "on");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, true);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "false");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, false);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "no");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, false);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, "off");
visit_type_bool(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_bool(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(res, ==, false);
}
......@@ -117,13 +117,13 @@ static void test_visitor_in_number(TestInputVisitorData *data,
const void *unused)
{
double res = 0, value = 3.14;
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, "3.14");
visit_type_number(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_number(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpfloat(res, ==, value);
}
......@@ -131,13 +131,13 @@ static void test_visitor_in_string(TestInputVisitorData *data,
const void *unused)
{
char *res = NULL, *value = (char *) "Q E M U";
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, value);
visit_type_str(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_str(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpstr(res, ==, value);
g_free(res);
......@@ -146,7 +146,7 @@ static void test_visitor_in_string(TestInputVisitorData *data,
static void test_visitor_in_enum(TestInputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
Visitor *v;
EnumOne i;
......@@ -155,8 +155,8 @@ static void test_visitor_in_enum(TestInputVisitorData *data,
v = visitor_input_test_init(data, EnumOne_lookup[i]);
visit_type_EnumOne(v, &res, NULL, &errp);
g_assert(!errp);
visit_type_EnumOne(v, &res, NULL, &err);
g_assert(!err);
g_assert_cmpint(i, ==, res);
visitor_input_teardown(data, NULL);
......
......@@ -45,11 +45,11 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
const void *unused)
{
int64_t value = -42;
Error *errp = NULL;
Error *err = NULL;
char *str;
visit_type_int(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_int(data->ov, &value, NULL, &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -60,12 +60,12 @@ static void test_visitor_out_int(TestOutputVisitorData *data,
static void test_visitor_out_bool(TestOutputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
bool value = true;
char *str;
visit_type_bool(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_bool(data->ov, &value, NULL, &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -77,11 +77,11 @@ static void test_visitor_out_number(TestOutputVisitorData *data,
const void *unused)
{
double value = 3.14;
Error *errp = NULL;
Error *err = NULL;
char *str;
visit_type_number(data->ov, &value, NULL, &errp);
g_assert(!errp);
visit_type_number(data->ov, &value, NULL, &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -93,11 +93,11 @@ static void test_visitor_out_string(TestOutputVisitorData *data,
const void *unused)
{
char *string = (char *) "Q E M U";
Error *errp = NULL;
Error *err = NULL;
char *str;
visit_type_str(data->ov, &string, NULL, &errp);
g_assert(!errp);
visit_type_str(data->ov, &string, NULL, &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -109,12 +109,12 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
const void *unused)
{
char *string = NULL;
Error *errp = NULL;
Error *err = NULL;
char *str;
/* A null string should return "" */
visit_type_str(data->ov, &string, NULL, &errp);
g_assert(!errp);
visit_type_str(data->ov, &string, NULL, &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -125,13 +125,13 @@ static void test_visitor_out_no_string(TestOutputVisitorData *data,
static void test_visitor_out_enum(TestOutputVisitorData *data,
const void *unused)
{
Error *errp = NULL;
Error *err = NULL;
char *str;
EnumOne i;
for (i = 0; i < ENUM_ONE_MAX; i++) {
visit_type_EnumOne(data->ov, &i, "unused", &errp);
g_assert(!errp);
visit_type_EnumOne(data->ov, &i, "unused", &err);
g_assert(!err);
str = string_output_get_string(data->sov);
g_assert(str != NULL);
......@@ -144,13 +144,13 @@ static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
const void *unused)
{
EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
Error *errp;
Error *err;
for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
errp = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
g_assert(errp);
error_free(errp);
err = NULL;
visit_type_EnumOne(data->ov, &bad_values[i], "unused", &err);
g_assert(err);
error_free(err);
}
}
......
......@@ -24,6 +24,8 @@
#include "qemu-common.h"
#include "qemu/host-utils.h"
#include <math.h>
#include <limits.h>
#include <errno.h>
#include "qemu/sockets.h"
#include "qemu/iov.h"
......@@ -457,11 +459,16 @@ int parse_uint_full(const char *s, unsigned long long *value, int base)
int qemu_parse_fd(const char *param)
{
int fd;
char *endptr = NULL;
long fd;
char *endptr;
errno = 0;
fd = strtol(param, &endptr, 10);
if (*endptr || (fd == 0 && param == endptr)) {
if (param == endptr /* no conversion performed */ ||
errno != 0 /* not representable as long; possibly others */ ||
*endptr != '\0' /* final string not empty */ ||
fd < 0 /* invalid as file descriptor */ ||
fd > INT_MAX /* not representable as int */) {
return -1;
}
return fd;
......
......@@ -165,13 +165,13 @@ void error_free(Error *err)
}
}
void error_propagate(Error **dst_err, Error *local_err)
void error_propagate(Error **dst_errp, Error *local_err)
{
if (local_err && dst_err == &error_abort) {
if (local_err && dst_errp == &error_abort) {
error_report("%s", error_get_pretty(local_err));
abort();
} else if (dst_err && !*dst_err) {
*dst_err = local_err;
} else if (dst_errp && !*dst_errp) {
*dst_errp = local_err;
} else if (local_err) {
error_free(local_err);
}
......
......@@ -1036,7 +1036,7 @@ static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
const char *value;
int n;
if (!strcmp(key, "id") || error_is_set(state->errp)) {
if (!strcmp(key, "id") || *state->errp) {
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册