Merge remote branch 'markus/qerror' into staging
This commit is contained in:
commit
4a39943bd1
@ -172,6 +172,7 @@ endif #CONFIG_BSD_USER
|
||||
ifdef CONFIG_SOFTMMU
|
||||
|
||||
obj-y = vl.o async.o monitor.o pci.o pci_host.o pcie_host.o machine.o gdbstub.o
|
||||
obj-y += qemu-error.o
|
||||
# virtio has to be here due to weird dependency between PCI and virtio-net.
|
||||
# need to fix this properly
|
||||
obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o virtio-serial-bus.o
|
||||
|
@ -330,10 +330,10 @@ void AUD_vlog (const char *cap, const char *fmt, va_list ap)
|
||||
{
|
||||
if (conf.log_to_monitor) {
|
||||
if (cap) {
|
||||
monitor_printf(cur_mon, "%s: ", cap);
|
||||
monitor_printf(default_mon, "%s: ", cap);
|
||||
}
|
||||
|
||||
monitor_vprintf(cur_mon, fmt, ap);
|
||||
monitor_vprintf(default_mon, fmt, ap);
|
||||
}
|
||||
else {
|
||||
if (cap) {
|
||||
|
35
hw/pc.c
35
hw/pc.c
@ -230,40 +230,40 @@ static int boot_device2nibble(char boot_device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy/pasted from cmos_init, should be made a general function
|
||||
and used there as well */
|
||||
static int pc_boot_set(void *opaque, const char *boot_device)
|
||||
static int set_boot_dev(RTCState *s, const char *boot_device, int fd_bootchk)
|
||||
{
|
||||
Monitor *mon = cur_mon;
|
||||
#define PC_MAX_BOOT_DEVICES 3
|
||||
RTCState *s = (RTCState *)opaque;
|
||||
int nbds, bds[3] = { 0, };
|
||||
int i;
|
||||
|
||||
nbds = strlen(boot_device);
|
||||
if (nbds > PC_MAX_BOOT_DEVICES) {
|
||||
monitor_printf(mon, "Too many boot devices for PC\n");
|
||||
error_report("Too many boot devices for PC");
|
||||
return(1);
|
||||
}
|
||||
for (i = 0; i < nbds; i++) {
|
||||
bds[i] = boot_device2nibble(boot_device[i]);
|
||||
if (bds[i] == 0) {
|
||||
monitor_printf(mon, "Invalid boot device for PC: '%c'\n",
|
||||
boot_device[i]);
|
||||
error_report("Invalid boot device for PC: '%c'",
|
||||
boot_device[i]);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
|
||||
rtc_set_memory(s, 0x38, (bds[2] << 4));
|
||||
rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int pc_boot_set(void *opaque, const char *boot_device)
|
||||
{
|
||||
return set_boot_dev(opaque, boot_device, 0);
|
||||
}
|
||||
|
||||
/* hd_table must contain 4 block drivers */
|
||||
static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
|
||||
const char *boot_device, DriveInfo **hd_table)
|
||||
{
|
||||
RTCState *s = rtc_state;
|
||||
int nbds, bds[3] = { 0, };
|
||||
int val;
|
||||
int fd0, fd1, nb;
|
||||
int i;
|
||||
@ -302,22 +302,9 @@ static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
|
||||
rtc_set_memory(s, 0x5f, smp_cpus - 1);
|
||||
|
||||
/* set boot devices, and disable floppy signature check if requested */
|
||||
#define PC_MAX_BOOT_DEVICES 3
|
||||
nbds = strlen(boot_device);
|
||||
if (nbds > PC_MAX_BOOT_DEVICES) {
|
||||
fprintf(stderr, "Too many boot devices for PC\n");
|
||||
if (set_boot_dev(s, boot_device, fd_bootchk)) {
|
||||
exit(1);
|
||||
}
|
||||
for (i = 0; i < nbds; i++) {
|
||||
bds[i] = boot_device2nibble(boot_device[i]);
|
||||
if (bds[i] == 0) {
|
||||
fprintf(stderr, "Invalid boot device for PC: '%c'\n",
|
||||
boot_device[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
rtc_set_memory(s, 0x3d, (bds[1] << 4) | bds[0]);
|
||||
rtc_set_memory(s, 0x38, (bds[2] << 4) | (fd_bootchk ? 0x0 : 0x1));
|
||||
|
||||
/* floppy type */
|
||||
|
||||
|
@ -54,7 +54,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
|
||||
opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", 0);
|
||||
if (!opts) {
|
||||
monitor_printf(mon, "parsing network options '%s' failed\n",
|
||||
opts_str ? opts_str : "");
|
||||
@ -73,14 +73,15 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
|
||||
return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
|
||||
}
|
||||
|
||||
static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
|
||||
static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
|
||||
DriveInfo *dinfo, int printinfo)
|
||||
{
|
||||
SCSIBus *scsibus;
|
||||
SCSIDevice *scsidev;
|
||||
|
||||
scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus));
|
||||
if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) {
|
||||
qemu_error("Device is not a SCSI adapter\n");
|
||||
error_report("Device is not a SCSI adapter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -97,7 +98,8 @@ static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
|
||||
dinfo->unit = scsidev->id;
|
||||
|
||||
if (printinfo)
|
||||
qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id);
|
||||
monitor_printf(mon, "OK bus %d, unit %d\n",
|
||||
scsibus->busnr, scsidev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -131,7 +133,7 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
|
||||
monitor_printf(mon, "no pci device with address %s\n", pci_addr);
|
||||
goto err;
|
||||
}
|
||||
if (scsi_hot_add(&dev->qdev, dinfo, 1) != 0) {
|
||||
if (scsi_hot_add(mon, &dev->qdev, dinfo, 1) != 0) {
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
@ -203,7 +205,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
|
||||
if (qdev_init(&dev->qdev) < 0)
|
||||
dev = NULL;
|
||||
if (dev && dinfo) {
|
||||
if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) {
|
||||
if (scsi_hot_add(mon, &dev->qdev, dinfo, 0) != 0) {
|
||||
qdev_unplug(&dev->qdev);
|
||||
dev = NULL;
|
||||
}
|
||||
|
14
hw/pci.c
14
hw/pci.c
@ -589,12 +589,12 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
|
||||
if (!bus->devices[devfn])
|
||||
goto found;
|
||||
}
|
||||
qemu_error("PCI: no devfn available for %s, all in use\n", name);
|
||||
error_report("PCI: no devfn available for %s, all in use", name);
|
||||
return NULL;
|
||||
found: ;
|
||||
} else if (bus->devices[devfn]) {
|
||||
qemu_error("PCI: devfn %d not available for %s, in use by %s\n", devfn,
|
||||
name, bus->devices[devfn]->name);
|
||||
error_report("PCI: devfn %d not available for %s, in use by %s",
|
||||
devfn, name, bus->devices[devfn]->name);
|
||||
return NULL;
|
||||
}
|
||||
pci_dev->bus = bus;
|
||||
@ -1476,8 +1476,8 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
|
||||
|
||||
bus = pci_get_bus_devfn(&devfn, devaddr);
|
||||
if (!bus) {
|
||||
qemu_error("Invalid PCI device address %s for device %s\n",
|
||||
devaddr, pci_nic_names[i]);
|
||||
error_report("Invalid PCI device address %s for device %s",
|
||||
devaddr, pci_nic_names[i]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1768,8 +1768,8 @@ static int pci_add_option_rom(PCIDevice *pdev)
|
||||
|
||||
size = get_image_size(path);
|
||||
if (size < 0) {
|
||||
qemu_error("%s: failed to find romfile \"%s\"\n", __FUNCTION__,
|
||||
pdev->romfile);
|
||||
error_report("%s: failed to find romfile \"%s\"",
|
||||
__FUNCTION__, pdev->romfile);
|
||||
return -1;
|
||||
}
|
||||
if (size & (size - 1)) {
|
||||
|
@ -402,17 +402,11 @@ PropertyInfo qdev_prop_vlan = {
|
||||
|
||||
/* --- pointer --- */
|
||||
|
||||
static int print_ptr(DeviceState *dev, Property *prop, char *dest, size_t len)
|
||||
{
|
||||
void **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
return snprintf(dest, len, "<%p>", *ptr);
|
||||
}
|
||||
|
||||
/* Not a proper property, just for dirty hacks. TODO Remove it! */
|
||||
PropertyInfo qdev_prop_ptr = {
|
||||
.name = "ptr",
|
||||
.type = PROP_TYPE_PTR,
|
||||
.size = sizeof(void*),
|
||||
.print = print_ptr,
|
||||
};
|
||||
|
||||
/* --- mac address --- */
|
||||
@ -547,31 +541,31 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value)
|
||||
int ret;
|
||||
|
||||
prop = qdev_prop_find(dev, name);
|
||||
if (!prop) {
|
||||
fprintf(stderr, "property \"%s.%s\" not found\n",
|
||||
dev->info->name, name);
|
||||
return -1;
|
||||
}
|
||||
if (!prop->info->parse) {
|
||||
fprintf(stderr, "property \"%s.%s\" has no parser\n",
|
||||
dev->info->name, name);
|
||||
/*
|
||||
* TODO Properties without a parse method are just for dirty
|
||||
* hacks. qdev_prop_ptr is the only such PropertyInfo. It's
|
||||
* marked for removal. The test !prop->info->parse should be
|
||||
* removed along with it.
|
||||
*/
|
||||
if (!prop || !prop->info->parse) {
|
||||
qerror_report(QERR_PROPERTY_NOT_FOUND, dev->info->name, name);
|
||||
return -1;
|
||||
}
|
||||
ret = prop->info->parse(dev, prop, value);
|
||||
if (ret < 0) {
|
||||
switch (ret) {
|
||||
case -EEXIST:
|
||||
fprintf(stderr, "property \"%s.%s\": \"%s\" is already in use\n",
|
||||
dev->info->name, name, value);
|
||||
qerror_report(QERR_PROPERTY_VALUE_IN_USE,
|
||||
dev->info->name, name, value);
|
||||
break;
|
||||
default:
|
||||
case -EINVAL:
|
||||
fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n",
|
||||
dev->info->name, name, value);
|
||||
qerror_report(QERR_PROPERTY_VALUE_BAD,
|
||||
dev->info->name, name, value);
|
||||
break;
|
||||
case -ENOENT:
|
||||
fprintf(stderr, "property \"%s.%s\": could not find \"%s\"\n",
|
||||
dev->info->name, name, value);
|
||||
qerror_report(QERR_PROPERTY_VALUE_NOT_FOUND,
|
||||
dev->info->name, name, value);
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
|
240
hw/qdev.c
240
hw/qdev.c
@ -29,7 +29,6 @@
|
||||
#include "qdev.h"
|
||||
#include "sysemu.h"
|
||||
#include "monitor.h"
|
||||
#include "qerror.h"
|
||||
|
||||
static int qdev_hotplug = 0;
|
||||
|
||||
@ -78,26 +77,11 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a new device. This only initializes the device state structure
|
||||
and allows properties to be set. qdev_init should be called to
|
||||
initialize the actual device emulation. */
|
||||
DeviceState *qdev_create(BusState *bus, const char *name)
|
||||
static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
|
||||
{
|
||||
DeviceInfo *info;
|
||||
DeviceState *dev;
|
||||
|
||||
if (!bus) {
|
||||
if (!main_system_bus) {
|
||||
main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
|
||||
}
|
||||
bus = main_system_bus;
|
||||
}
|
||||
|
||||
info = qdev_find_info(bus->info, name);
|
||||
if (!info) {
|
||||
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
|
||||
}
|
||||
|
||||
assert(bus->info == info->bus_info);
|
||||
dev = qemu_mallocz(info->size);
|
||||
dev->info = info;
|
||||
dev->parent_bus = bus;
|
||||
@ -113,27 +97,42 @@ DeviceState *qdev_create(BusState *bus, const char *name)
|
||||
return dev;
|
||||
}
|
||||
|
||||
static int qdev_print_devinfo(DeviceInfo *info, char *dest, int len)
|
||||
/* Create a new device. This only initializes the device state structure
|
||||
and allows properties to be set. qdev_init should be called to
|
||||
initialize the actual device emulation. */
|
||||
DeviceState *qdev_create(BusState *bus, const char *name)
|
||||
{
|
||||
int pos = 0;
|
||||
int ret;
|
||||
DeviceInfo *info;
|
||||
|
||||
ret = snprintf(dest+pos, len-pos, "name \"%s\", bus %s",
|
||||
info->name, info->bus_info->name);
|
||||
pos += MIN(len-pos,ret);
|
||||
if (!bus) {
|
||||
if (!main_system_bus) {
|
||||
main_system_bus = qbus_create(&system_bus_info, NULL, "main-system-bus");
|
||||
}
|
||||
bus = main_system_bus;
|
||||
}
|
||||
|
||||
info = qdev_find_info(bus->info, name);
|
||||
if (!info) {
|
||||
hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
|
||||
}
|
||||
|
||||
return qdev_create_from_info(bus, info);
|
||||
}
|
||||
|
||||
static void qdev_print_devinfo(DeviceInfo *info)
|
||||
{
|
||||
error_printf("name \"%s\", bus %s",
|
||||
info->name, info->bus_info->name);
|
||||
if (info->alias) {
|
||||
ret = snprintf(dest+pos, len-pos, ", alias \"%s\"", info->alias);
|
||||
pos += MIN(len-pos,ret);
|
||||
error_printf(", alias \"%s\"", info->alias);
|
||||
}
|
||||
if (info->desc) {
|
||||
ret = snprintf(dest+pos, len-pos, ", desc \"%s\"", info->desc);
|
||||
pos += MIN(len-pos,ret);
|
||||
error_printf(", desc \"%s\"", info->desc);
|
||||
}
|
||||
if (info->no_user) {
|
||||
ret = snprintf(dest+pos, len-pos, ", no-user");
|
||||
pos += MIN(len-pos,ret);
|
||||
error_printf(", no-user");
|
||||
}
|
||||
return pos;
|
||||
error_printf("\n");
|
||||
}
|
||||
|
||||
static int set_property(const char *name, const char *value, void *opaque)
|
||||
@ -146,8 +145,6 @@ static int set_property(const char *name, const char *value, void *opaque)
|
||||
return 0;
|
||||
|
||||
if (qdev_prop_parse(dev, name, value) == -1) {
|
||||
qemu_error("can't set property \"%s\" to \"%s\" for \"%s\"\n",
|
||||
name, value, dev->info->name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -157,14 +154,15 @@ int qdev_device_help(QemuOpts *opts)
|
||||
{
|
||||
const char *driver;
|
||||
DeviceInfo *info;
|
||||
char msg[256];
|
||||
Property *prop;
|
||||
|
||||
driver = qemu_opt_get(opts, "driver");
|
||||
if (driver && !strcmp(driver, "?")) {
|
||||
for (info = device_info_list; info != NULL; info = info->next) {
|
||||
qdev_print_devinfo(info, msg, sizeof(msg));
|
||||
qemu_error("%s\n", msg);
|
||||
if (info->no_user) {
|
||||
continue; /* not available, don't show */
|
||||
}
|
||||
qdev_print_devinfo(info);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -179,7 +177,16 @@ int qdev_device_help(QemuOpts *opts)
|
||||
}
|
||||
|
||||
for (prop = info->props; prop && prop->name; prop++) {
|
||||
qemu_error("%s.%s=%s\n", info->name, prop->name, prop->info->name);
|
||||
/*
|
||||
* TODO Properties without a parser are just for dirty hacks.
|
||||
* qdev_prop_ptr is the only such PropertyInfo. It's marked
|
||||
* for removal. This conditional should be removed along with
|
||||
* it.
|
||||
*/
|
||||
if (!prop->info->parse) {
|
||||
continue; /* no way to set it, don't show */
|
||||
}
|
||||
error_printf("%s.%s=%s\n", info->name, prop->name, prop->info->name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -193,19 +200,15 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
|
||||
driver = qemu_opt_get(opts, "driver");
|
||||
if (!driver) {
|
||||
qemu_error("-device: no driver specified\n");
|
||||
qerror_report(QERR_MISSING_PARAMETER, "driver");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find driver */
|
||||
info = qdev_find_info(NULL, driver);
|
||||
if (!info) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_FOUND, driver);
|
||||
return NULL;
|
||||
}
|
||||
if (info->no_user) {
|
||||
qemu_error("device \"%s\" can't be added via command line\n",
|
||||
info->name);
|
||||
if (!info || info->no_user) {
|
||||
qerror_report(QERR_INVALID_PARAMETER, "driver");
|
||||
error_printf_unless_qmp("Try with argument '?' for a list.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -213,22 +216,29 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
path = qemu_opt_get(opts, "bus");
|
||||
if (path != NULL) {
|
||||
bus = qbus_find(path);
|
||||
if (!bus) {
|
||||
return NULL;
|
||||
}
|
||||
if (bus->info != info->bus_info) {
|
||||
qerror_report(QERR_BAD_BUS_FOR_DEVICE,
|
||||
driver, bus->info->name);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
bus = qbus_find_recursive(main_system_bus, NULL, info->bus_info);
|
||||
}
|
||||
if (!bus) {
|
||||
qemu_error("Did not find %s bus for %s\n",
|
||||
path ? path : info->bus_info->name, info->name);
|
||||
return NULL;
|
||||
if (!bus) {
|
||||
qerror_report(QERR_NO_BUS_FOR_DEVICE,
|
||||
info->name, info->bus_info->name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (qdev_hotplug && !bus->allow_hotplug) {
|
||||
qemu_error("Bus %s does not support hotplugging\n",
|
||||
bus->name);
|
||||
qerror_report(QERR_BUS_NO_HOTPLUG, bus->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create device, set properties */
|
||||
qdev = qdev_create(bus, driver);
|
||||
qdev = qdev_create_from_info(bus, info);
|
||||
id = qemu_opts_id(opts);
|
||||
if (id) {
|
||||
qdev->id = id;
|
||||
@ -238,7 +248,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
|
||||
return NULL;
|
||||
}
|
||||
if (qdev_init(qdev) < 0) {
|
||||
qemu_error("Error initializing device %s\n", driver);
|
||||
qerror_report(QERR_DEVICE_INIT_FAILED, driver);
|
||||
return NULL;
|
||||
}
|
||||
qdev->opts = opts;
|
||||
@ -277,8 +287,8 @@ int qdev_init(DeviceState *dev)
|
||||
int qdev_unplug(DeviceState *dev)
|
||||
{
|
||||
if (!dev->parent_bus->allow_hotplug) {
|
||||
qemu_error("Bus %s does not support hotplugging\n",
|
||||
dev->parent_bus->name);
|
||||
error_report("Bus %s does not support hotplugging",
|
||||
dev->parent_bus->name);
|
||||
return -1;
|
||||
}
|
||||
assert(dev->info->unplug != NULL);
|
||||
@ -465,35 +475,33 @@ static DeviceState *qdev_find_recursive(BusState *bus, const char *id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void qbus_list_bus(DeviceState *dev, char *dest, int len)
|
||||
static void qbus_list_bus(DeviceState *dev)
|
||||
{
|
||||
BusState *child;
|
||||
const char *sep = " ";
|
||||
int pos = 0;
|
||||
|
||||
pos += snprintf(dest+pos, len-pos,"child busses at \"%s\":",
|
||||
dev->id ? dev->id : dev->info->name);
|
||||
error_printf("child busses at \"%s\":",
|
||||
dev->id ? dev->id : dev->info->name);
|
||||
QLIST_FOREACH(child, &dev->child_bus, sibling) {
|
||||
pos += snprintf(dest+pos, len-pos, "%s\"%s\"", sep, child->name);
|
||||
error_printf("%s\"%s\"", sep, child->name);
|
||||
sep = ", ";
|
||||
}
|
||||
error_printf("\n");
|
||||
}
|
||||
|
||||
static void qbus_list_dev(BusState *bus, char *dest, int len)
|
||||
static void qbus_list_dev(BusState *bus)
|
||||
{
|
||||
DeviceState *dev;
|
||||
const char *sep = " ";
|
||||
int pos = 0;
|
||||
|
||||
pos += snprintf(dest+pos, len-pos, "devices at \"%s\":",
|
||||
bus->name);
|
||||
error_printf("devices at \"%s\":", bus->name);
|
||||
QLIST_FOREACH(dev, &bus->children, sibling) {
|
||||
pos += snprintf(dest+pos, len-pos, "%s\"%s\"",
|
||||
sep, dev->info->name);
|
||||
error_printf("%s\"%s\"", sep, dev->info->name);
|
||||
if (dev->id)
|
||||
pos += snprintf(dest+pos, len-pos, "/\"%s\"", dev->id);
|
||||
error_printf("/\"%s\"", dev->id);
|
||||
sep = ", ";
|
||||
}
|
||||
error_printf("\n");
|
||||
}
|
||||
|
||||
static BusState *qbus_find_bus(DeviceState *dev, char *elem)
|
||||
@ -540,7 +548,7 @@ static BusState *qbus_find(const char *path)
|
||||
{
|
||||
DeviceState *dev;
|
||||
BusState *bus;
|
||||
char elem[128], msg[256];
|
||||
char elem[128];
|
||||
int pos, len;
|
||||
|
||||
/* find start element */
|
||||
@ -549,62 +557,75 @@ static BusState *qbus_find(const char *path)
|
||||
pos = 0;
|
||||
} else {
|
||||
if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {
|
||||
qemu_error("path parse error (\"%s\")\n", path);
|
||||
return NULL;
|
||||
assert(!path[0]);
|
||||
elem[0] = len = 0;
|
||||
}
|
||||
bus = qbus_find_recursive(main_system_bus, elem, NULL);
|
||||
if (!bus) {
|
||||
qemu_error("bus \"%s\" not found\n", elem);
|
||||
qerror_report(QERR_BUS_NOT_FOUND, elem);
|
||||
return NULL;
|
||||
}
|
||||
pos = len;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
assert(path[pos] == '/' || !path[pos]);
|
||||
while (path[pos] == '/') {
|
||||
pos++;
|
||||
}
|
||||
if (path[pos] == '\0') {
|
||||
/* we are done */
|
||||
return bus;
|
||||
}
|
||||
|
||||
/* find device */
|
||||
if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
|
||||
qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
|
||||
return NULL;
|
||||
if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
|
||||
assert(0);
|
||||
elem[0] = len = 0;
|
||||
}
|
||||
pos += len;
|
||||
dev = qbus_find_dev(bus, elem);
|
||||
if (!dev) {
|
||||
qbus_list_dev(bus, msg, sizeof(msg));
|
||||
qemu_error("device \"%s\" not found\n%s\n", elem, msg);
|
||||
qerror_report(QERR_DEVICE_NOT_FOUND, elem);
|
||||
if (!monitor_cur_is_qmp()) {
|
||||
qbus_list_dev(bus);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(path[pos] == '/' || !path[pos]);
|
||||
while (path[pos] == '/') {
|
||||
pos++;
|
||||
}
|
||||
if (path[pos] == '\0') {
|
||||
/* last specified element is a device. If it has exactly
|
||||
* one child bus accept it nevertheless */
|
||||
switch (dev->num_child_bus) {
|
||||
case 0:
|
||||
qemu_error("device has no child bus (%s)\n", path);
|
||||
qerror_report(QERR_DEVICE_NO_BUS, elem);
|
||||
return NULL;
|
||||
case 1:
|
||||
return QLIST_FIRST(&dev->child_bus);
|
||||
default:
|
||||
qbus_list_bus(dev, msg, sizeof(msg));
|
||||
qemu_error("device has multiple child busses (%s)\n%s\n",
|
||||
path, msg);
|
||||
qerror_report(QERR_DEVICE_MULTIPLE_BUSSES, elem);
|
||||
if (!monitor_cur_is_qmp()) {
|
||||
qbus_list_bus(dev);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* find bus */
|
||||
if (sscanf(path+pos, "/%127[^/]%n", elem, &len) != 1) {
|
||||
qemu_error("path parse error (\"%s\" pos %d)\n", path, pos);
|
||||
return NULL;
|
||||
if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {
|
||||
assert(0);
|
||||
elem[0] = len = 0;
|
||||
}
|
||||
pos += len;
|
||||
bus = qbus_find_bus(dev, elem);
|
||||
if (!bus) {
|
||||
qbus_list_bus(dev, msg, sizeof(msg));
|
||||
qemu_error("child bus \"%s\" not found\n%s\n", elem, msg);
|
||||
qerror_report(QERR_BUS_NOT_FOUND, elem);
|
||||
if (!monitor_cur_is_qmp()) {
|
||||
qbus_list_bus(dev);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -684,6 +705,12 @@ static void qdev_print_props(Monitor *mon, DeviceState *dev, Property *props,
|
||||
if (!props)
|
||||
return;
|
||||
while (props->name) {
|
||||
/*
|
||||
* TODO Properties without a print method are just for dirty
|
||||
* hacks. qdev_prop_ptr is the only such PropertyInfo. It's
|
||||
* marked for removal. The test props->info->print should be
|
||||
* removed along with it.
|
||||
*/
|
||||
if (props->info->print) {
|
||||
props->info->print(dev, props, buf, sizeof(buf));
|
||||
qdev_printf("%s-prop: %s = %s\n", prefix, props->name, buf);
|
||||
@ -735,25 +762,42 @@ void do_info_qtree(Monitor *mon)
|
||||
void do_info_qdm(Monitor *mon)
|
||||
{
|
||||
DeviceInfo *info;
|
||||
char msg[256];
|
||||
|
||||
for (info = device_info_list; info != NULL; info = info->next) {
|
||||
qdev_print_devinfo(info, msg, sizeof(msg));
|
||||
monitor_printf(mon, "%s\n", msg);
|
||||
qdev_print_devinfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
void do_device_add(Monitor *mon, const QDict *qdict)
|
||||
/**
|
||||
* do_device_add(): Add a device
|
||||
*
|
||||
* Argument qdict contains
|
||||
* - "driver": the name of the new device's driver
|
||||
* - "bus": the device's parent bus (device tree path)
|
||||
* - "id": the device's ID (must be unique)
|
||||
* - device properties
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* { "driver": "usb-net", "id": "eth1", "netdev": "netdev1" }
|
||||
*/
|
||||
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
{
|
||||
QemuOpts *opts;
|
||||
|
||||
opts = qemu_opts_parse(&qemu_device_opts,
|
||||
qdict_get_str(qdict, "config"), "driver");
|
||||
if (opts) {
|
||||
if (qdev_device_help(opts) || qdev_device_add(opts) == NULL) {
|
||||
qemu_opts_del(opts);
|
||||
}
|
||||
opts = qemu_opts_from_qdict(&qemu_device_opts, qdict);
|
||||
if (!opts) {
|
||||
return -1;
|
||||
}
|
||||
if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
|
||||
qemu_opts_del(opts);
|
||||
return 0;
|
||||
}
|
||||
if (!qdev_device_add(opts)) {
|
||||
qemu_opts_del(opts);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_device_del(Monitor *mon, const QDict *qdict)
|
||||
@ -763,7 +807,7 @@ void do_device_del(Monitor *mon, const QDict *qdict)
|
||||
|
||||
dev = qdev_find_recursive(main_system_bus, id);
|
||||
if (NULL == dev) {
|
||||
qemu_error("Device '%s' not found\n", id);
|
||||
error_report("Device '%s' not found", id);
|
||||
return;
|
||||
}
|
||||
qdev_unplug(dev);
|
||||
|
@ -175,7 +175,7 @@ void qbus_free(BusState *bus);
|
||||
|
||||
void do_info_qtree(Monitor *mon);
|
||||
void do_info_qdm(Monitor *mon);
|
||||
void do_device_add(Monitor *mon, const QDict *qdict);
|
||||
int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
|
||||
void do_device_del(Monitor *mon, const QDict *qdict);
|
||||
|
||||
/*** qdev-properties.c ***/
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "hw.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-error.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi-defs.h"
|
||||
#include "block.h"
|
||||
@ -41,7 +41,7 @@ static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||
}
|
||||
}
|
||||
if (dev->id >= bus->ndev) {
|
||||
qemu_error("bad scsi device id: %d\n", dev->id);
|
||||
error_report("bad scsi device id: %d", dev->id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,6 @@
|
||||
* the host adapter emulator.
|
||||
*/
|
||||
|
||||
#include <qemu-common.h>
|
||||
#include <sysemu.h>
|
||||
//#define DEBUG_SCSI
|
||||
|
||||
#ifdef DEBUG_SCSI
|
||||
@ -34,6 +32,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
|
||||
do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "block.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi-defs.h"
|
||||
@ -1026,13 +1025,13 @@ static int scsi_disk_initfn(SCSIDevice *dev)
|
||||
uint64_t nb_sectors;
|
||||
|
||||
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
|
||||
qemu_error("scsi-disk: drive property not set\n");
|
||||
error_report("scsi-disk: drive property not set");
|
||||
return -1;
|
||||
}
|
||||
s->bs = s->qdev.conf.dinfo->bdrv;
|
||||
|
||||
if (bdrv_is_sg(s->bs)) {
|
||||
qemu_error("scsi-disk: unwanted /dev/sg*\n");
|
||||
error_report("scsi-disk: unwanted /dev/sg*");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "block.h"
|
||||
#include "scsi.h"
|
||||
|
||||
@ -463,27 +464,27 @@ static int scsi_generic_initfn(SCSIDevice *dev)
|
||||
struct sg_scsi_id scsiid;
|
||||
|
||||
if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
|
||||
qemu_error("scsi-generic: drive property not set\n");
|
||||
error_report("scsi-generic: drive property not set");
|
||||
return -1;
|
||||
}
|
||||
s->bs = s->qdev.conf.dinfo->bdrv;
|
||||
|
||||
/* check we are really using a /dev/sg* file */
|
||||
if (!bdrv_is_sg(s->bs)) {
|
||||
qemu_error("scsi-generic: not /dev/sg*\n");
|
||||
error_report("scsi-generic: not /dev/sg*");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check we are using a driver managing SG_IO (version 3 and after */
|
||||
if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
|
||||
sg_version < 30000) {
|
||||
qemu_error("scsi-generic: scsi generic interface too old\n");
|
||||
error_report("scsi-generic: scsi generic interface too old");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get LUN of the /dev/sg? */
|
||||
if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
|
||||
qemu_error("scsi-generic: SG_GET_SCSI_ID ioctl failed\n");
|
||||
error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -291,14 +291,14 @@ USBDevice *usbdevice_create(const char *cmdline)
|
||||
if (info == NULL) {
|
||||
#if 0
|
||||
/* no error because some drivers are not converted (yet) */
|
||||
qemu_error("usbdevice %s not found\n", driver);
|
||||
error_report("usbdevice %s not found", driver);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!usb->usbdevice_init) {
|
||||
if (params) {
|
||||
qemu_error("usbdevice %s accepts no params\n", driver);
|
||||
error_report("usbdevice %s accepts no params", driver);
|
||||
return NULL;
|
||||
}
|
||||
return usb_create_simple(bus, usb->qdev.name);
|
||||
|
@ -524,7 +524,7 @@ static int usb_msd_initfn(USBDevice *dev)
|
||||
MSDState *s = DO_UPCAST(MSDState, dev, dev);
|
||||
|
||||
if (!s->conf.dinfo || !s->conf.dinfo->bdrv) {
|
||||
qemu_error("usb-msd: drive property not set\n");
|
||||
error_report("usb-msd: drive property not set");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -535,7 +535,7 @@ static int usb_msd_initfn(USBDevice *dev)
|
||||
usb_msd_handle_reset(dev);
|
||||
|
||||
if (bdrv_key_required(s->conf.dinfo->bdrv)) {
|
||||
if (s->dev.qdev.hotplugged) {
|
||||
if (cur_mon) {
|
||||
monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv,
|
||||
usb_msd_password_cb, s);
|
||||
s->dev.auto_attach = 0;
|
||||
|
@ -1478,7 +1478,7 @@ static USBDevice *usb_net_init(const char *cmdline)
|
||||
QemuOpts *opts;
|
||||
int idx;
|
||||
|
||||
opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL);
|
||||
opts = qemu_opts_parse(&qemu_net_opts, cmdline, 0);
|
||||
if (!opts) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "usb.h"
|
||||
#include "qemu-char.h"
|
||||
|
||||
@ -564,26 +565,26 @@ static USBDevice *usb_serial_init(const char *filename)
|
||||
if (strstart(filename, "vendorid=", &p)) {
|
||||
vendorid = strtol(p, &e, 16);
|
||||
if (e == p || (*e && *e != ',' && *e != ':')) {
|
||||
qemu_error("bogus vendor ID %s\n", p);
|
||||
error_report("bogus vendor ID %s", p);
|
||||
return NULL;
|
||||
}
|
||||
filename = e;
|
||||
} else if (strstart(filename, "productid=", &p)) {
|
||||
productid = strtol(p, &e, 16);
|
||||
if (e == p || (*e && *e != ',' && *e != ':')) {
|
||||
qemu_error("bogus product ID %s\n", p);
|
||||
error_report("bogus product ID %s", p);
|
||||
return NULL;
|
||||
}
|
||||
filename = e;
|
||||
} else {
|
||||
qemu_error("unrecognized serial USB option %s\n", filename);
|
||||
error_report("unrecognized serial USB option %s", filename);
|
||||
return NULL;
|
||||
}
|
||||
while(*filename == ',')
|
||||
filename++;
|
||||
}
|
||||
if (!*filename) {
|
||||
qemu_error("character device specification needed\n");
|
||||
error_report("character device specification needed");
|
||||
return NULL;
|
||||
}
|
||||
filename++;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "net.h"
|
||||
#include "net/checksum.h"
|
||||
#include "net/tap.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "virtio-net.h"
|
||||
|
||||
@ -764,7 +765,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
||||
|
||||
if (version_id >= 7) {
|
||||
if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
|
||||
qemu_error("virtio-net: saved image requires vnet_hdr=on\n");
|
||||
error_report("virtio-net: saved image requires vnet_hdr=on");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -793,7 +794,7 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
||||
|
||||
if (version_id >= 11) {
|
||||
if (qemu_get_byte(f) && !peer_has_ufo(n)) {
|
||||
qemu_error("virtio-net: saved image requires TUN_F_UFO support\n");
|
||||
error_report("virtio-net: saved image requires TUN_F_UFO support");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "virtio-blk.h"
|
||||
#include "virtio-net.h"
|
||||
#include "pci.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-error.h"
|
||||
#include "msix.h"
|
||||
#include "net.h"
|
||||
#include "block_int.h"
|
||||
@ -459,7 +459,7 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
|
||||
proxy->class_code = PCI_CLASS_STORAGE_SCSI;
|
||||
|
||||
if (!proxy->block.dinfo) {
|
||||
qemu_error("virtio-blk-pci: drive property not set\n");
|
||||
error_report("virtio-blk-pci: drive property not set");
|
||||
return -1;
|
||||
}
|
||||
vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
|
||||
|
@ -485,7 +485,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
|
||||
plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0);
|
||||
|
||||
if (port->vser->config.nr_ports == bus->max_nr_ports && !plugging_port0) {
|
||||
qemu_error("virtio-serial-bus: Maximum device limit reached\n");
|
||||
error_report("virtio-serial-bus: Maximum device limit reached");
|
||||
return -1;
|
||||
}
|
||||
dev->info = info;
|
||||
|
337
monitor.c
337
monitor.c
@ -67,6 +67,11 @@
|
||||
* 'F' filename
|
||||
* 'B' block device name
|
||||
* 's' string (accept optional quote)
|
||||
* 'O' option string of the form NAME=VALUE,...
|
||||
* parsed according to QemuOptsList given by its name
|
||||
* Example: 'device:O' uses qemu_device_opts.
|
||||
* Restriction: only lists with empty desc are supported
|
||||
* TODO lift the restriction
|
||||
* 'i' 32 bit integer
|
||||
* 'l' target long (32 or 64 bit)
|
||||
* 'M' just like 'l', except in user mode the value is
|
||||
@ -177,7 +182,8 @@ static QLIST_HEAD(mon_list, Monitor) mon_list;
|
||||
static const mon_cmd_t mon_cmds[];
|
||||
static const mon_cmd_t info_cmds[];
|
||||
|
||||
Monitor *cur_mon = NULL;
|
||||
Monitor *cur_mon;
|
||||
Monitor *default_mon;
|
||||
|
||||
static void monitor_command_cb(Monitor *mon, const char *cmdline,
|
||||
void *opaque);
|
||||
@ -193,6 +199,12 @@ static inline int monitor_ctrl_mode(const Monitor *mon)
|
||||
return (mon->flags & MONITOR_USE_CONTROL);
|
||||
}
|
||||
|
||||
/* Return non-zero iff we have a current monitor, and it is in QMP mode. */
|
||||
int monitor_cur_is_qmp(void)
|
||||
{
|
||||
return cur_mon && monitor_ctrl_mode(cur_mon);
|
||||
}
|
||||
|
||||
static void monitor_read_command(Monitor *mon, int show_prompt)
|
||||
{
|
||||
if (!mon->rs)
|
||||
@ -207,7 +219,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
|
||||
void *opaque)
|
||||
{
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
qemu_error_new(QERR_MISSING_PARAMETER, "password");
|
||||
qerror_report(QERR_MISSING_PARAMETER, "password");
|
||||
return -EINVAL;
|
||||
} else if (mon->rs) {
|
||||
readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
|
||||
@ -606,7 +618,7 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
|
||||
if (cmd->name == NULL) {
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
qemu_error_new(QERR_COMMAND_NOT_FOUND, item);
|
||||
qerror_report(QERR_COMMAND_NOT_FOUND, item);
|
||||
return -1;
|
||||
}
|
||||
goto help;
|
||||
@ -638,7 +650,7 @@ static int do_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
} else {
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
/* handler not converted yet */
|
||||
qemu_error_new(QERR_COMMAND_NOT_FOUND, item);
|
||||
qerror_report(QERR_COMMAND_NOT_FOUND, item);
|
||||
return -1;
|
||||
} else {
|
||||
cmd->mhandler.info(mon);
|
||||
@ -960,7 +972,7 @@ static int do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
{
|
||||
int index = qdict_get_int(qdict, "index");
|
||||
if (mon_set_cpu(index) < 0) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER, "index");
|
||||
qerror_report(QERR_INVALID_PARAMETER, "index");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -1013,12 +1025,12 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
|
||||
if (bdrv_is_inserted(bs)) {
|
||||
if (!force) {
|
||||
if (!bdrv_is_removable(bs)) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_REMOVABLE,
|
||||
qerror_report(QERR_DEVICE_NOT_REMOVABLE,
|
||||
bdrv_get_device_name(bs));
|
||||
return -1;
|
||||
}
|
||||
if (bdrv_is_locked(bs)) {
|
||||
qemu_error_new(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
|
||||
qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1035,7 +1047,7 @@ static int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
|
||||
bs = bdrv_find(filename);
|
||||
if (!bs) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_FOUND, filename);
|
||||
qerror_report(QERR_DEVICE_NOT_FOUND, filename);
|
||||
return -1;
|
||||
}
|
||||
return eject_device(mon, bs, force);
|
||||
@ -1048,12 +1060,12 @@ static int do_block_set_passwd(Monitor *mon, const QDict *qdict,
|
||||
|
||||
bs = bdrv_find(qdict_get_str(qdict, "device"));
|
||||
if (!bs) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
|
||||
qerror_report(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bdrv_set_key(bs, qdict_get_str(qdict, "password")) < 0) {
|
||||
qemu_error_new(QERR_INVALID_PASSWORD);
|
||||
qerror_report(QERR_INVALID_PASSWORD);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1068,13 +1080,13 @@ static int do_change_block(Monitor *mon, const char *device,
|
||||
|
||||
bs = bdrv_find(device);
|
||||
if (!bs) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_FOUND, device);
|
||||
qerror_report(QERR_DEVICE_NOT_FOUND, device);
|
||||
return -1;
|
||||
}
|
||||
if (fmt) {
|
||||
drv = bdrv_find_whitelisted_format(fmt);
|
||||
if (!drv) {
|
||||
qemu_error_new(QERR_INVALID_BLOCK_FORMAT, fmt);
|
||||
qerror_report(QERR_INVALID_BLOCK_FORMAT, fmt);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1090,7 +1102,7 @@ static int do_change_block(Monitor *mon, const char *device,
|
||||
static int change_vnc_password(const char *password)
|
||||
{
|
||||
if (vnc_display_password(NULL, password) < 0) {
|
||||
qemu_error_new(QERR_SET_PASSWD_FAILED);
|
||||
qerror_report(QERR_SET_PASSWD_FAILED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1118,7 +1130,7 @@ static int do_change_vnc(Monitor *mon, const char *target, const char *arg)
|
||||
}
|
||||
} else {
|
||||
if (vnc_display_open(NULL, target) < 0) {
|
||||
qemu_error_new(QERR_VNC_SERVER_FAILED, target);
|
||||
qerror_report(QERR_VNC_SERVER_FAILED, target);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1490,7 +1502,7 @@ static int do_memory_save(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
qemu_error_new(QERR_OPEN_FILE_FAILED, filename);
|
||||
qerror_report(QERR_OPEN_FILE_FAILED, filename);
|
||||
return -1;
|
||||
}
|
||||
while (size != 0) {
|
||||
@ -1526,7 +1538,7 @@ static int do_physical_memory_save(Monitor *mon, const QDict *qdict,
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
qemu_error_new(QERR_OPEN_FILE_FAILED, filename);
|
||||
qerror_report(QERR_OPEN_FILE_FAILED, filename);
|
||||
return -1;
|
||||
}
|
||||
while (size != 0) {
|
||||
@ -2300,13 +2312,13 @@ static int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
|
||||
int ret;
|
||||
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
|
||||
qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qemu_balloon_status(cb, opaque);
|
||||
if (!ret) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
|
||||
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2322,13 +2334,13 @@ static int do_balloon(Monitor *mon, const QDict *params,
|
||||
int ret;
|
||||
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
|
||||
qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);
|
||||
if (ret == 0) {
|
||||
qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon");
|
||||
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2469,21 +2481,21 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
|
||||
fd = qemu_chr_get_msgfd(mon->chr);
|
||||
if (fd == -1) {
|
||||
qemu_error_new(QERR_FD_NOT_SUPPLIED);
|
||||
qerror_report(QERR_FD_NOT_SUPPLIED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemu_isdigit(fdname[0])) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER, "fdname");
|
||||
qerror_report(QERR_INVALID_PARAMETER, "fdname");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = dup(fd);
|
||||
if (fd == -1) {
|
||||
if (errno == EMFILE)
|
||||
qemu_error_new(QERR_TOO_MANY_FILES);
|
||||
qerror_report(QERR_TOO_MANY_FILES);
|
||||
else
|
||||
qemu_error_new(QERR_UNDEFINED_ERROR);
|
||||
qerror_report(QERR_UNDEFINED_ERROR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2522,7 +2534,7 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
qemu_error_new(QERR_FD_NOT_FOUND, fdname);
|
||||
qerror_report(QERR_FD_NOT_FOUND, fdname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2533,7 +2545,7 @@ static void do_loadvm(Monitor *mon, const QDict *qdict)
|
||||
|
||||
vm_stop(0);
|
||||
|
||||
if (load_vmstate(mon, name) >= 0 && saved_vm_running)
|
||||
if (load_vmstate(name) >= 0 && saved_vm_running)
|
||||
vm_start();
|
||||
}
|
||||
|
||||
@ -3638,6 +3650,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
|
||||
qdict_put(qdict, key, qstring_from_str(buf));
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
{
|
||||
QemuOptsList *opts_list;
|
||||
QemuOpts *opts;
|
||||
|
||||
opts_list = qemu_find_opts(key);
|
||||
if (!opts_list || opts_list->desc->name) {
|
||||
goto bad_type;
|
||||
}
|
||||
while (qemu_isspace(*p)) {
|
||||
p++;
|
||||
}
|
||||
if (!*p)
|
||||
break;
|
||||
if (get_str(buf, sizeof(buf), &p) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
opts = qemu_opts_parse(opts_list, buf, 1);
|
||||
if (!opts) {
|
||||
goto fail;
|
||||
}
|
||||
qemu_opts_to_qdict(opts, qdict);
|
||||
qemu_opts_del(opts);
|
||||
}
|
||||
break;
|
||||
case '/':
|
||||
{
|
||||
int count, format, size;
|
||||
@ -3857,11 +3894,16 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void monitor_print_error(Monitor *mon)
|
||||
void monitor_set_error(Monitor *mon, QError *qerror)
|
||||
{
|
||||
qerror_print(mon->error);
|
||||
QDECREF(mon->error);
|
||||
mon->error = NULL;
|
||||
/* report only the first error */
|
||||
if (!mon->error) {
|
||||
mon->error = qerror;
|
||||
} else {
|
||||
MON_DEBUG("Additional error report at %s:%d\n",
|
||||
qerror->file, qerror->linenr);
|
||||
QDECREF(qerror);
|
||||
}
|
||||
}
|
||||
|
||||
static int is_async_return(const QObject *data)
|
||||
@ -3875,45 +3917,49 @@ static int is_async_return(const QObject *data)
|
||||
|
||||
static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)
|
||||
{
|
||||
if (ret && !monitor_has_error(mon)) {
|
||||
/*
|
||||
* If it returns failure, it must have passed on error.
|
||||
*
|
||||
* Action: Report an internal error to the client if in QMP.
|
||||
*/
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
qemu_error_new(QERR_UNDEFINED_ERROR);
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
if (ret && !monitor_has_error(mon)) {
|
||||
/*
|
||||
* If it returns failure, it must have passed on error.
|
||||
*
|
||||
* Action: Report an internal error to the client if in QMP.
|
||||
*/
|
||||
qerror_report(QERR_UNDEFINED_ERROR);
|
||||
MON_DEBUG("command '%s' returned failure but did not pass an error\n",
|
||||
cmd->name);
|
||||
}
|
||||
MON_DEBUG("command '%s' returned failure but did not pass an error\n",
|
||||
cmd->name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_MONITOR
|
||||
if (!ret && monitor_has_error(mon)) {
|
||||
/*
|
||||
* If it returns success, it must not have passed an error.
|
||||
*
|
||||
* Action: Report the passed error to the client.
|
||||
*/
|
||||
MON_DEBUG("command '%s' returned success but passed an error\n",
|
||||
cmd->name);
|
||||
}
|
||||
if (!ret && monitor_has_error(mon)) {
|
||||
/*
|
||||
* If it returns success, it must not have passed an error.
|
||||
*
|
||||
* Action: Report the passed error to the client.
|
||||
*/
|
||||
MON_DEBUG("command '%s' returned success but passed an error\n",
|
||||
cmd->name);
|
||||
}
|
||||
|
||||
if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {
|
||||
/*
|
||||
* Handlers should not call Monitor print functions.
|
||||
*
|
||||
* Action: Ignore them in QMP.
|
||||
*
|
||||
* (XXX: we don't check any 'info' or 'query' command here
|
||||
* because the user print function _is_ called by do_info(), hence
|
||||
* we will trigger this check. This problem will go away when we
|
||||
* make 'query' commands real and kill do_info())
|
||||
*/
|
||||
MON_DEBUG("command '%s' called print functions %d time(s)\n",
|
||||
cmd->name, mon_print_count_get(mon));
|
||||
}
|
||||
if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {
|
||||
/*
|
||||
* Handlers should not call Monitor print functions.
|
||||
*
|
||||
* Action: Ignore them in QMP.
|
||||
*
|
||||
* (XXX: we don't check any 'info' or 'query' command here
|
||||
* because the user print function _is_ called by do_info(), hence
|
||||
* we will trigger this check. This problem will go away when we
|
||||
* make 'query' commands real and kill do_info())
|
||||
*/
|
||||
MON_DEBUG("command '%s' called print functions %d time(s)\n",
|
||||
cmd->name, mon_print_count_get(mon));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
assert(!monitor_has_error(mon));
|
||||
QDECREF(mon->error);
|
||||
mon->error = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,
|
||||
@ -3958,8 +4004,6 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
|
||||
if (!cmd)
|
||||
goto out;
|
||||
|
||||
qemu_errors_to_mon(mon);
|
||||
|
||||
if (monitor_handler_is_async(cmd)) {
|
||||
user_async_cmd_handler(mon, cmd, qdict);
|
||||
} else if (monitor_handler_ported(cmd)) {
|
||||
@ -3968,11 +4012,6 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
|
||||
cmd->mhandler.cmd(mon, qdict);
|
||||
}
|
||||
|
||||
if (monitor_has_error(mon))
|
||||
monitor_print_error(mon);
|
||||
|
||||
qemu_errors_to_previous();
|
||||
|
||||
out:
|
||||
QDECREF(qdict);
|
||||
}
|
||||
@ -4209,7 +4248,7 @@ typedef struct CmdArgs {
|
||||
static int check_opt(const CmdArgs *cmd_args, const char *name, QDict *args)
|
||||
{
|
||||
if (!cmd_args->optional) {
|
||||
qemu_error_new(QERR_MISSING_PARAMETER, name);
|
||||
qerror_report(QERR_MISSING_PARAMETER, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -4242,7 +4281,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
|
||||
case 'B':
|
||||
case 's':
|
||||
if (qobject_type(value) != QTYPE_QSTRING) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "string");
|
||||
qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "string");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -4253,11 +4292,11 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
|
||||
for (i = 0; keys[i]; i++) {
|
||||
QObject *obj = qdict_get(args, keys[i]);
|
||||
if (!obj) {
|
||||
qemu_error_new(QERR_MISSING_PARAMETER, name);
|
||||
qerror_report(QERR_MISSING_PARAMETER, name);
|
||||
return -1;
|
||||
}
|
||||
if (qobject_type(obj) != QTYPE_QINT) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
|
||||
qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -4267,21 +4306,21 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
|
||||
case 'l':
|
||||
case 'M':
|
||||
if (qobject_type(value) != QTYPE_QINT) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int");
|
||||
qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
case 'T':
|
||||
if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QFLOAT) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "number");
|
||||
qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "number");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
if (qobject_type(value) != QTYPE_QINT &&
|
||||
qobject_type(value) != QTYPE_QBOOL) {
|
||||
qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "bool");
|
||||
qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool");
|
||||
return -1;
|
||||
}
|
||||
if (qobject_type(value) == QTYPE_QBOOL) {
|
||||
@ -4290,6 +4329,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args)
|
||||
qint_from_int(qbool_get_int(qobject_to_qbool(value))));
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
default:
|
||||
/* impossible */
|
||||
abort();
|
||||
@ -4304,6 +4344,12 @@ static void cmd_args_init(CmdArgs *cmd_args)
|
||||
cmd_args->type = cmd_args->flag = cmd_args->optional = 0;
|
||||
}
|
||||
|
||||
static int check_opts(QemuOptsList *opts_list, QDict *args)
|
||||
{
|
||||
assert(!opts_list->desc->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is not trivial, we have to parse Monitor command's argument
|
||||
* type syntax to be able to check the arguments provided by clients.
|
||||
@ -4316,6 +4362,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||
int err;
|
||||
const char *p;
|
||||
CmdArgs cmd_args;
|
||||
QemuOptsList *opts_list;
|
||||
|
||||
if (cmd->args_type == NULL) {
|
||||
return (qdict_size(args) == 0 ? 0 : -1);
|
||||
@ -4323,6 +4370,7 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||
|
||||
err = 0;
|
||||
cmd_args_init(&cmd_args);
|
||||
opts_list = NULL;
|
||||
|
||||
for (p = cmd->args_type;; p++) {
|
||||
if (*p == ':') {
|
||||
@ -4331,16 +4379,23 @@ static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args)
|
||||
if (cmd_args.type == '-') {
|
||||
cmd_args.flag = *p++;
|
||||
cmd_args.optional = 1;
|
||||
} else if (cmd_args.type == 'O') {
|
||||
opts_list = qemu_find_opts(qstring_get_str(cmd_args.name));
|
||||
assert(opts_list);
|
||||
} else if (*p == '?') {
|
||||
cmd_args.optional = 1;
|
||||
p++;
|
||||
}
|
||||
|
||||
assert(*p == ',' || *p == '\0');
|
||||
err = check_arg(&cmd_args, args);
|
||||
|
||||
QDECREF(cmd_args.name);
|
||||
cmd_args_init(&cmd_args);
|
||||
if (opts_list) {
|
||||
err = check_opts(opts_list, args);
|
||||
opts_list = NULL;
|
||||
} else {
|
||||
err = check_arg(&cmd_args, args);
|
||||
QDECREF(cmd_args.name);
|
||||
cmd_args_init(&cmd_args);
|
||||
}
|
||||
|
||||
if (err < 0) {
|
||||
break;
|
||||
@ -4374,15 +4429,14 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
|
||||
const char *cmd_name, *info_item;
|
||||
|
||||
args = NULL;
|
||||
qemu_errors_to_mon(mon);
|
||||
|
||||
obj = json_parser_parse(tokens, NULL);
|
||||
if (!obj) {
|
||||
// FIXME: should be triggered in json_parser_parse()
|
||||
qemu_error_new(QERR_JSON_PARSING);
|
||||
qerror_report(QERR_JSON_PARSING);
|
||||
goto err_out;
|
||||
} else if (qobject_type(obj) != QTYPE_QDICT) {
|
||||
qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "object");
|
||||
qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object");
|
||||
qobject_decref(obj);
|
||||
goto err_out;
|
||||
}
|
||||
@ -4394,17 +4448,17 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
|
||||
|
||||
obj = qdict_get(input, "execute");
|
||||
if (!obj) {
|
||||
qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "execute");
|
||||
qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute");
|
||||
goto err_input;
|
||||
} else if (qobject_type(obj) != QTYPE_QSTRING) {
|
||||
qemu_error_new(QERR_QMP_BAD_INPUT_OBJECT, "string");
|
||||
qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "string");
|
||||
goto err_input;
|
||||
}
|
||||
|
||||
cmd_name = qstring_get_str(qobject_to_qstring(obj));
|
||||
|
||||
if (invalid_qmp_mode(mon, cmd_name)) {
|
||||
qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
goto err_input;
|
||||
}
|
||||
|
||||
@ -4413,7 +4467,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
|
||||
* converted into 'query-' commands
|
||||
*/
|
||||
if (compare_cmd(cmd_name, "info")) {
|
||||
qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
goto err_input;
|
||||
} else if (strstart(cmd_name, "query-", &info_item)) {
|
||||
cmd = monitor_find_command("info");
|
||||
@ -4422,7 +4476,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
|
||||
} else {
|
||||
cmd = monitor_find_command(cmd_name);
|
||||
if (!cmd || !monitor_handler_ported(cmd)) {
|
||||
qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
|
||||
goto err_input;
|
||||
}
|
||||
}
|
||||
@ -4455,7 +4509,6 @@ err_out:
|
||||
monitor_protocol_emitter(mon, NULL);
|
||||
out:
|
||||
QDECREF(args);
|
||||
qemu_errors_to_previous();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4624,8 +4677,8 @@ void monitor_init(CharDriverState *chr, int flags)
|
||||
}
|
||||
|
||||
QLIST_INSERT_HEAD(&mon_list, mon, entry);
|
||||
if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
|
||||
cur_mon = mon;
|
||||
if (!default_mon || (flags & MONITOR_IS_DEFAULT))
|
||||
default_mon = mon;
|
||||
}
|
||||
|
||||
static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
|
||||
@ -4656,7 +4709,7 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
|
||||
}
|
||||
|
||||
if (monitor_ctrl_mode(mon)) {
|
||||
qemu_error_new(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
|
||||
qerror_report(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -4673,99 +4726,3 @@ int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef struct QemuErrorSink QemuErrorSink;
|
||||
struct QemuErrorSink {
|
||||
enum {
|
||||
ERR_SINK_FILE,
|
||||
ERR_SINK_MONITOR,
|
||||
} dest;
|
||||
union {
|
||||
FILE *fp;
|
||||
Monitor *mon;
|
||||
};
|
||||
QemuErrorSink *previous;
|
||||
};
|
||||
|
||||
static QemuErrorSink *qemu_error_sink;
|
||||
|
||||
void qemu_errors_to_file(FILE *fp)
|
||||
{
|
||||
QemuErrorSink *sink;
|
||||
|
||||
sink = qemu_mallocz(sizeof(*sink));
|
||||
sink->dest = ERR_SINK_FILE;
|
||||
sink->fp = fp;
|
||||
sink->previous = qemu_error_sink;
|
||||
qemu_error_sink = sink;
|
||||
}
|
||||
|
||||
void qemu_errors_to_mon(Monitor *mon)
|
||||
{
|
||||
QemuErrorSink *sink;
|
||||
|
||||
sink = qemu_mallocz(sizeof(*sink));
|
||||
sink->dest = ERR_SINK_MONITOR;
|
||||
sink->mon = mon;
|
||||
sink->previous = qemu_error_sink;
|
||||
qemu_error_sink = sink;
|
||||
}
|
||||
|
||||
void qemu_errors_to_previous(void)
|
||||
{
|
||||
QemuErrorSink *sink;
|
||||
|
||||
assert(qemu_error_sink != NULL);
|
||||
sink = qemu_error_sink;
|
||||
qemu_error_sink = sink->previous;
|
||||
qemu_free(sink);
|
||||
}
|
||||
|
||||
void qemu_error(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
assert(qemu_error_sink != NULL);
|
||||
switch (qemu_error_sink->dest) {
|
||||
case ERR_SINK_FILE:
|
||||
va_start(args, fmt);
|
||||
vfprintf(qemu_error_sink->fp, fmt, args);
|
||||
va_end(args);
|
||||
break;
|
||||
case ERR_SINK_MONITOR:
|
||||
va_start(args, fmt);
|
||||
monitor_vprintf(qemu_error_sink->mon, fmt, args);
|
||||
va_end(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_error_internal(const char *file, int linenr, const char *func,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
QError *qerror;
|
||||
|
||||
assert(qemu_error_sink != NULL);
|
||||
|
||||
va_start(va, fmt);
|
||||
qerror = qerror_from_info(file, linenr, func, fmt, &va);
|
||||
va_end(va);
|
||||
|
||||
switch (qemu_error_sink->dest) {
|
||||
case ERR_SINK_FILE:
|
||||
qerror_print(qerror);
|
||||
QDECREF(qerror);
|
||||
break;
|
||||
case ERR_SINK_MONITOR:
|
||||
/* report only the first error */
|
||||
if (!qemu_error_sink->mon->error) {
|
||||
qemu_error_sink->mon->error = qerror;
|
||||
} else {
|
||||
MON_DEBUG("Additional error report at %s:%d\n", qerror->file,
|
||||
qerror->linenr);
|
||||
QDECREF(qerror);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,13 @@
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qerror.h"
|
||||
#include "qdict.h"
|
||||
#include "block.h"
|
||||
|
||||
extern Monitor *cur_mon;
|
||||
extern Monitor *default_mon;
|
||||
|
||||
/* flags for monitor_init */
|
||||
#define MONITOR_IS_DEFAULT 0x01
|
||||
@ -28,6 +31,8 @@ typedef enum MonitorEvent {
|
||||
QEVENT_MAX,
|
||||
} MonitorEvent;
|
||||
|
||||
int monitor_cur_is_qmp(void);
|
||||
|
||||
void monitor_protocol_event(MonitorEvent event, QObject *data);
|
||||
void monitor_init(CharDriverState *chr, int flags);
|
||||
|
||||
@ -48,4 +53,6 @@ void monitor_flush(Monitor *mon);
|
||||
|
||||
typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
|
||||
|
||||
void monitor_set_error(Monitor *mon, QError *qerror);
|
||||
|
||||
#endif /* !MONITOR_H */
|
||||
|
32
net.c
32
net.c
@ -733,7 +733,7 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,
|
||||
return i;
|
||||
}
|
||||
|
||||
qemu_error("qemu: Unsupported NIC model: %s\n", nd->model);
|
||||
error_report("qemu: Unsupported NIC model: %s", nd->model);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -744,7 +744,7 @@ int net_handle_fd_param(Monitor *mon, const char *param)
|
||||
|
||||
fd = monitor_get_fd(mon, param);
|
||||
if (fd == -1) {
|
||||
qemu_error("No file descriptor named %s found", param);
|
||||
error_report("No file descriptor named %s found", param);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -765,7 +765,7 @@ static int net_init_nic(QemuOpts *opts,
|
||||
|
||||
idx = nic_get_free_idx();
|
||||
if (idx == -1 || nb_nics >= MAX_NICS) {
|
||||
qemu_error("Too Many NICs\n");
|
||||
error_report("Too Many NICs");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -776,7 +776,7 @@ static int net_init_nic(QemuOpts *opts,
|
||||
if ((netdev = qemu_opt_get(opts, "netdev"))) {
|
||||
nd->netdev = qemu_find_netdev(netdev);
|
||||
if (!nd->netdev) {
|
||||
qemu_error("netdev '%s' not found\n", netdev);
|
||||
error_report("netdev '%s' not found", netdev);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
@ -802,7 +802,7 @@ static int net_init_nic(QemuOpts *opts,
|
||||
|
||||
if (qemu_opt_get(opts, "macaddr") &&
|
||||
net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) {
|
||||
qemu_error("invalid syntax for ethernet address\n");
|
||||
error_report("invalid syntax for ethernet address");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -810,7 +810,7 @@ static int net_init_nic(QemuOpts *opts,
|
||||
DEV_NVECTORS_UNSPECIFIED);
|
||||
if (nd->nvectors != DEV_NVECTORS_UNSPECIFIED &&
|
||||
(nd->nvectors < 0 || nd->nvectors > 0x7ffffff)) {
|
||||
qemu_error("invalid # of vectors: %d\n", nd->nvectors);
|
||||
error_report("invalid # of vectors: %d", nd->nvectors);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1060,12 +1060,12 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
|
||||
|
||||
if (!is_netdev) {
|
||||
if (!type) {
|
||||
qemu_error("No type specified for -net\n");
|
||||
error_report("No type specified for -net");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!type) {
|
||||
qemu_error("No type specified for -netdev\n");
|
||||
error_report("No type specified for -netdev");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1077,21 +1077,21 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
|
||||
strcmp(type, "vde") != 0 &&
|
||||
#endif
|
||||
strcmp(type, "socket") != 0) {
|
||||
qemu_error("The '%s' network backend type is not valid with -netdev\n",
|
||||
type);
|
||||
error_report("The '%s' network backend type is not valid with -netdev",
|
||||
type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemu_opt_get(opts, "vlan")) {
|
||||
qemu_error("The 'vlan' parameter is not valid with -netdev\n");
|
||||
error_report("The 'vlan' parameter is not valid with -netdev");
|
||||
return -1;
|
||||
}
|
||||
if (qemu_opt_get(opts, "name")) {
|
||||
qemu_error("The 'name' parameter is not valid with -netdev\n");
|
||||
error_report("The 'name' parameter is not valid with -netdev");
|
||||
return -1;
|
||||
}
|
||||
if (!qemu_opts_id(opts)) {
|
||||
qemu_error("The id= parameter is required with -netdev\n");
|
||||
error_report("The id= parameter is required with -netdev");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1124,7 +1124,7 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
|
||||
}
|
||||
}
|
||||
|
||||
qemu_error("Invalid -net type '%s'\n", type);
|
||||
error_report("Invalid -net type '%s'", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1159,7 +1159,7 @@ void net_host_device_add(Monitor *mon, const QDict *qdict)
|
||||
return;
|
||||
}
|
||||
|
||||
opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL);
|
||||
opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", 0);
|
||||
if (!opts) {
|
||||
monitor_printf(mon, "parsing network options '%s' failed\n",
|
||||
opts_str ? opts_str : "");
|
||||
@ -1364,7 +1364,7 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!qemu_opts_parse(opts_list, optarg, "type")) {
|
||||
if (!qemu_opts_parse(opts_list, optarg, 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "dump.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu-log.h"
|
||||
|
||||
typedef struct DumpState {
|
||||
@ -107,7 +108,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
|
||||
|
||||
fd = open(filename, O_CREAT | O_WRONLY | O_BINARY, 0644);
|
||||
if (fd < 0) {
|
||||
qemu_error("-net dump: can't open %s\n", filename);
|
||||
error_report("-net dump: can't open %s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
|
||||
hdr.linktype = 1;
|
||||
|
||||
if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
|
||||
qemu_error("-net dump write error: %s\n", strerror(errno));
|
||||
error_report("-net dump write error: %s", strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
28
net/slirp.c
28
net/slirp.c
@ -413,14 +413,14 @@ static int slirp_hostfwd(SlirpState *s, const char *redir_str,
|
||||
|
||||
if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,
|
||||
guest_port) < 0) {
|
||||
qemu_error("could not set up host forwarding rule '%s'\n",
|
||||
redir_str);
|
||||
error_report("could not set up host forwarding rule '%s'",
|
||||
redir_str);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_syntax:
|
||||
qemu_error("invalid host forwarding rule '%s'\n", redir_str);
|
||||
error_report("invalid host forwarding rule '%s'", redir_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -473,10 +473,10 @@ static void slirp_smb_cleanup(SlirpState *s)
|
||||
snprintf(cmd, sizeof(cmd), "rm -rf %s", s->smb_dir);
|
||||
ret = system(cmd);
|
||||
if (ret == -1 || !WIFEXITED(ret)) {
|
||||
qemu_error("'%s' failed.\n", cmd);
|
||||
error_report("'%s' failed.", cmd);
|
||||
} else if (WEXITSTATUS(ret)) {
|
||||
qemu_error("'%s' failed. Error code: %d\n",
|
||||
cmd, WEXITSTATUS(ret));
|
||||
error_report("'%s' failed. Error code: %d",
|
||||
cmd, WEXITSTATUS(ret));
|
||||
}
|
||||
s->smb_dir[0] = '\0';
|
||||
}
|
||||
@ -493,7 +493,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
|
||||
snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d",
|
||||
(long)getpid(), instance++);
|
||||
if (mkdir(s->smb_dir, 0700) < 0) {
|
||||
qemu_error("could not create samba server dir '%s'\n", s->smb_dir);
|
||||
error_report("could not create samba server dir '%s'", s->smb_dir);
|
||||
return -1;
|
||||
}
|
||||
snprintf(smb_conf, sizeof(smb_conf), "%s/%s", s->smb_dir, "smb.conf");
|
||||
@ -501,8 +501,8 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
|
||||
f = fopen(smb_conf, "w");
|
||||
if (!f) {
|
||||
slirp_smb_cleanup(s);
|
||||
qemu_error("could not create samba server configuration file '%s'\n",
|
||||
smb_conf);
|
||||
error_report("could not create samba server configuration file '%s'",
|
||||
smb_conf);
|
||||
return -1;
|
||||
}
|
||||
fprintf(f,
|
||||
@ -533,7 +533,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
|
||||
|
||||
if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
|
||||
slirp_smb_cleanup(s);
|
||||
qemu_error("conflicting/invalid smbserver address\n");
|
||||
error_report("conflicting/invalid smbserver address");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -618,14 +618,14 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
|
||||
snprintf(buf, sizeof(buf), "guestfwd.tcp:%d", port);
|
||||
fwd->hd = qemu_chr_open(buf, p, NULL);
|
||||
if (!fwd->hd) {
|
||||
qemu_error("could not open guest forwarding device '%s'\n", buf);
|
||||
error_report("could not open guest forwarding device '%s'", buf);
|
||||
qemu_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
|
||||
qemu_error("conflicting/invalid host:port in guest forwarding "
|
||||
"rule '%s'\n", config_str);
|
||||
error_report("conflicting/invalid host:port in guest forwarding "
|
||||
"rule '%s'", config_str);
|
||||
qemu_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
@ -638,7 +638,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
|
||||
return 0;
|
||||
|
||||
fail_syntax:
|
||||
qemu_error("invalid guest forwarding rule '%s'\n", config_str);
|
||||
error_report("invalid guest forwarding rule '%s'", config_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
12
net/socket.c
12
net/socket.c
@ -28,9 +28,9 @@
|
||||
#include "net.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu-option.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "sysemu.h"
|
||||
|
||||
typedef struct NetSocketState {
|
||||
VLANClientState nc;
|
||||
@ -506,7 +506,7 @@ int net_init_socket(QemuOpts *opts,
|
||||
if (qemu_opt_get(opts, "listen") ||
|
||||
qemu_opt_get(opts, "connect") ||
|
||||
qemu_opt_get(opts, "mcast")) {
|
||||
qemu_error("listen=, connect= and mcast= is invalid with fd=\n");
|
||||
error_report("listen=, connect= and mcast= is invalid with fd=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -525,7 +525,7 @@ int net_init_socket(QemuOpts *opts,
|
||||
if (qemu_opt_get(opts, "fd") ||
|
||||
qemu_opt_get(opts, "connect") ||
|
||||
qemu_opt_get(opts, "mcast")) {
|
||||
qemu_error("fd=, connect= and mcast= is invalid with listen=\n");
|
||||
error_report("fd=, connect= and mcast= is invalid with listen=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -540,7 +540,7 @@ int net_init_socket(QemuOpts *opts,
|
||||
if (qemu_opt_get(opts, "fd") ||
|
||||
qemu_opt_get(opts, "listen") ||
|
||||
qemu_opt_get(opts, "mcast")) {
|
||||
qemu_error("fd=, listen= and mcast= is invalid with connect=\n");
|
||||
error_report("fd=, listen= and mcast= is invalid with connect=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -555,7 +555,7 @@ int net_init_socket(QemuOpts *opts,
|
||||
if (qemu_opt_get(opts, "fd") ||
|
||||
qemu_opt_get(opts, "connect") ||
|
||||
qemu_opt_get(opts, "listen")) {
|
||||
qemu_error("fd=, connect= and listen= is invalid with mcast=\n");
|
||||
error_report("fd=, connect= and listen= is invalid with mcast=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -565,7 +565,7 @@ int net_init_socket(QemuOpts *opts,
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
qemu_error("-socket requires fd=, listen=, connect= or mcast=\n");
|
||||
error_report("-socket requires fd=, listen=, connect= or mcast=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
|
||||
}
|
||||
}
|
||||
if (fd < 0) {
|
||||
qemu_error("warning: could not open %s (%s): no virtual network emulation\n", dname, strerror(errno));
|
||||
error_report("warning: could not open %s (%s): no virtual network emulation",
|
||||
dname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
@ -89,8 +90,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
|
||||
*vnet_hdr = 0;
|
||||
|
||||
if (vnet_hdr_required && !*vnet_hdr) {
|
||||
qemu_error("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
error_report("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "sysemu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
|
||||
int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required)
|
||||
{
|
||||
@ -57,8 +58,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
|
||||
}
|
||||
|
||||
if (vnet_hdr_required && !*vnet_hdr) {
|
||||
qemu_error("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
error_report("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
@ -96,7 +97,7 @@ int tap_set_sndbuf(int fd, QemuOpts *opts)
|
||||
}
|
||||
|
||||
if (ioctl(fd, TUNSETSNDBUF, &sndbuf) == -1 && qemu_opt_get(opts, "sndbuf")) {
|
||||
qemu_error("TUNSETSNDBUF ioctl failed: %s\n", strerror(errno));
|
||||
error_report("TUNSETSNDBUF ioctl failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -107,7 +108,7 @@ int tap_probe_vnet_hdr(int fd)
|
||||
struct ifreq ifr;
|
||||
|
||||
if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
|
||||
qemu_error("TUNGETIFF ioctl() failed: %s\n", strerror(errno));
|
||||
error_report("TUNGETIFF ioctl() failed: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,8 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required
|
||||
*vnet_hdr = 0;
|
||||
|
||||
if (vnet_hdr_required && !*vnet_hdr) {
|
||||
qemu_error("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
error_report("vnet_hdr=1 requested, but no kernel "
|
||||
"support for IFF_VNET_HDR available");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -706,7 +706,7 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
|
||||
ifname = qemu_opt_get(opts, "ifname");
|
||||
|
||||
if (!ifname) {
|
||||
qemu_error("tap: no interface name\n");
|
||||
error_report("tap: no interface name");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "sysemu.h"
|
||||
#include "qemu-char.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
|
||||
#include "net/tap-linux.h"
|
||||
|
||||
@ -393,7 +394,7 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
|
||||
qemu_opt_get(opts, "script") ||
|
||||
qemu_opt_get(opts, "downscript") ||
|
||||
qemu_opt_get(opts, "vnet_hdr")) {
|
||||
qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=\n");
|
||||
error_report("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu-option.h"
|
||||
#include "qemu-config.h"
|
||||
#include "sysemu.h"
|
||||
@ -85,6 +86,7 @@ QemuOptsList qemu_drive_opts = {
|
||||
|
||||
QemuOptsList qemu_chardev_opts = {
|
||||
.name = "chardev",
|
||||
.implied_opt_name = "backend",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_chardev_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
@ -151,6 +153,7 @@ QemuOptsList qemu_chardev_opts = {
|
||||
|
||||
QemuOptsList qemu_device_opts = {
|
||||
.name = "device",
|
||||
.implied_opt_name = "driver",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_device_opts.head),
|
||||
.desc = {
|
||||
/*
|
||||
@ -164,6 +167,7 @@ QemuOptsList qemu_device_opts = {
|
||||
|
||||
QemuOptsList qemu_netdev_opts = {
|
||||
.name = "netdev",
|
||||
.implied_opt_name = "type",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_netdev_opts.head),
|
||||
.desc = {
|
||||
/*
|
||||
@ -176,6 +180,7 @@ QemuOptsList qemu_netdev_opts = {
|
||||
|
||||
QemuOptsList qemu_net_opts = {
|
||||
.name = "net",
|
||||
.implied_opt_name = "type",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_net_opts.head),
|
||||
.desc = {
|
||||
/*
|
||||
@ -226,6 +231,7 @@ QemuOptsList qemu_global_opts = {
|
||||
|
||||
QemuOptsList qemu_mon_opts = {
|
||||
.name = "mon",
|
||||
.implied_opt_name = "chardev",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
@ -303,7 +309,7 @@ static QemuOptsList *lists[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static QemuOptsList *find_list(const char *group)
|
||||
QemuOptsList *qemu_find_opts(const char *group)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -312,7 +318,7 @@ static QemuOptsList *find_list(const char *group)
|
||||
break;
|
||||
}
|
||||
if (lists[i] == NULL) {
|
||||
qemu_error("there is no option group \"%s\"\n", group);
|
||||
error_report("there is no option group \"%s\"", group);
|
||||
}
|
||||
return lists[i];
|
||||
}
|
||||
@ -326,19 +332,19 @@ int qemu_set_option(const char *str)
|
||||
|
||||
rc = sscanf(str, "%63[^.].%63[^.].%63[^=]%n", group, id, arg, &offset);
|
||||
if (rc < 3 || str[offset] != '=') {
|
||||
qemu_error("can't parse: \"%s\"\n", str);
|
||||
error_report("can't parse: \"%s\"", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
list = find_list(group);
|
||||
list = qemu_find_opts(group);
|
||||
if (list == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
opts = qemu_opts_find(list, id);
|
||||
if (!opts) {
|
||||
qemu_error("there is no %s \"%s\" defined\n",
|
||||
list->name, id);
|
||||
error_report("there is no %s \"%s\" defined",
|
||||
list->name, id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -356,7 +362,7 @@ int qemu_global_option(const char *str)
|
||||
|
||||
rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset);
|
||||
if (rc < 2 || str[offset] != '=') {
|
||||
qemu_error("can't parse: \"%s\"\n", str);
|
||||
error_report("can't parse: \"%s\"", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -424,13 +430,17 @@ void qemu_config_write(FILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_config_parse(FILE *fp)
|
||||
int qemu_config_parse(FILE *fp, const char *fname)
|
||||
{
|
||||
char line[1024], group[64], id[64], arg[64], value[1024];
|
||||
Location loc;
|
||||
QemuOptsList *list = NULL;
|
||||
QemuOpts *opts = NULL;
|
||||
int res = -1, lno = 0;
|
||||
|
||||
loc_push_none(&loc);
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
loc_set_file(fname, ++lno);
|
||||
if (line[0] == '\n') {
|
||||
/* skip empty lines */
|
||||
continue;
|
||||
@ -441,35 +451,41 @@ int qemu_config_parse(FILE *fp)
|
||||
}
|
||||
if (sscanf(line, "[%63s \"%63[^\"]\"]", group, id) == 2) {
|
||||
/* group with id */
|
||||
list = find_list(group);
|
||||
list = qemu_find_opts(group);
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
goto out;
|
||||
opts = qemu_opts_create(list, id, 1);
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, "[%63[^]]]", group) == 1) {
|
||||
/* group without id */
|
||||
list = find_list(group);
|
||||
list = qemu_find_opts(group);
|
||||
if (list == NULL)
|
||||
return -1;
|
||||
goto out;
|
||||
opts = qemu_opts_create(list, NULL, 0);
|
||||
continue;
|
||||
}
|
||||
if (sscanf(line, " %63s = \"%1023[^\"]\"", arg, value) == 2) {
|
||||
/* arg = value */
|
||||
if (opts == NULL) {
|
||||
fprintf(stderr, "no group defined\n");
|
||||
return -1;
|
||||
error_report("no group defined");
|
||||
goto out;
|
||||
}
|
||||
if (qemu_opt_set(opts, arg, value) != 0) {
|
||||
fprintf(stderr, "failed to set \"%s\" for %s\n",
|
||||
arg, group);
|
||||
return -1;
|
||||
error_report("failed to set \"%s\" for %s", arg, group);
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "parse error: %s\n", line);
|
||||
return -1;
|
||||
error_report("parse error");
|
||||
goto out;
|
||||
}
|
||||
return 0;
|
||||
if (ferror(fp)) {
|
||||
error_report("error reading file");
|
||||
goto out;
|
||||
}
|
||||
res = 0;
|
||||
out:
|
||||
loc_pop(&loc);
|
||||
return res;
|
||||
}
|
||||
|
@ -11,11 +11,12 @@ extern QemuOptsList qemu_global_opts;
|
||||
extern QemuOptsList qemu_mon_opts;
|
||||
extern QemuOptsList qemu_cpudef_opts;
|
||||
|
||||
QemuOptsList *qemu_find_opts(const char *group);
|
||||
int qemu_set_option(const char *str);
|
||||
int qemu_global_option(const char *str);
|
||||
void qemu_add_globals(void);
|
||||
|
||||
void qemu_config_write(FILE *fp);
|
||||
int qemu_config_parse(FILE *fp);
|
||||
int qemu_config_parse(FILE *fp, const char *fname);
|
||||
|
||||
#endif /* QEMU_CONFIG_H */
|
||||
|
227
qemu-error.c
Normal file
227
qemu-error.c
Normal file
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Error reporting
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat Inc.
|
||||
*
|
||||
* Authors:
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "monitor.h"
|
||||
#include "sysemu.h"
|
||||
|
||||
/*
|
||||
* Print to current monitor if we have one, else to stderr.
|
||||
* TODO should return int, so callers can calculate width, but that
|
||||
* requires surgery to monitor_vprintf(). Left for another day.
|
||||
*/
|
||||
void error_vprintf(const char *fmt, va_list ap)
|
||||
{
|
||||
if (cur_mon) {
|
||||
monitor_vprintf(cur_mon, fmt, ap);
|
||||
} else {
|
||||
vfprintf(stderr, fmt, ap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print to current monitor if we have one, else to stderr.
|
||||
* TODO just like error_vprintf()
|
||||
*/
|
||||
void error_printf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
error_vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void error_printf_unless_qmp(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (!monitor_cur_is_qmp()) {
|
||||
va_start(ap, fmt);
|
||||
error_vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
static Location std_loc = {
|
||||
.kind = LOC_NONE
|
||||
};
|
||||
static Location *cur_loc = &std_loc;
|
||||
|
||||
/*
|
||||
* Push location saved in LOC onto the location stack, return it.
|
||||
* The top of that stack is the current location.
|
||||
* Needs a matching loc_pop().
|
||||
*/
|
||||
Location *loc_push_restore(Location *loc)
|
||||
{
|
||||
assert(!loc->prev);
|
||||
loc->prev = cur_loc;
|
||||
cur_loc = loc;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize *LOC to "nowhere", push it onto the location stack.
|
||||
* The top of that stack is the current location.
|
||||
* Needs a matching loc_pop().
|
||||
* Return LOC.
|
||||
*/
|
||||
Location *loc_push_none(Location *loc)
|
||||
{
|
||||
loc->kind = LOC_NONE;
|
||||
loc->prev = NULL;
|
||||
return loc_push_restore(loc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop the location stack.
|
||||
* LOC must be the current location, i.e. the top of the stack.
|
||||
*/
|
||||
Location *loc_pop(Location *loc)
|
||||
{
|
||||
assert(cur_loc == loc && loc->prev);
|
||||
cur_loc = loc->prev;
|
||||
loc->prev = NULL;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the current location in LOC, return LOC.
|
||||
*/
|
||||
Location *loc_save(Location *loc)
|
||||
{
|
||||
*loc = *cur_loc;
|
||||
loc->prev = NULL;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the current location to the one saved in LOC.
|
||||
*/
|
||||
void loc_restore(Location *loc)
|
||||
{
|
||||
Location *prev = cur_loc->prev;
|
||||
assert(!loc->prev);
|
||||
*cur_loc = *loc;
|
||||
cur_loc->prev = prev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the current location to "nowhere in particular".
|
||||
*/
|
||||
void loc_set_none(void)
|
||||
{
|
||||
cur_loc->kind = LOC_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the current location to argument ARGV[IDX..IDX+CNT-1].
|
||||
*/
|
||||
void loc_set_cmdline(char **argv, int idx, int cnt)
|
||||
{
|
||||
cur_loc->kind = LOC_CMDLINE;
|
||||
cur_loc->num = cnt;
|
||||
cur_loc->ptr = argv + idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the current location to file FNAME, line LNO.
|
||||
*/
|
||||
void loc_set_file(const char *fname, int lno)
|
||||
{
|
||||
assert (fname || cur_loc->kind == LOC_FILE);
|
||||
cur_loc->kind = LOC_FILE;
|
||||
cur_loc->num = lno;
|
||||
if (fname) {
|
||||
cur_loc->ptr = fname;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *progname;
|
||||
|
||||
/*
|
||||
* Set the program name for error_print_loc().
|
||||
*/
|
||||
void error_set_progname(const char *argv0)
|
||||
{
|
||||
const char *p = strrchr(argv0, '/');
|
||||
progname = p ? p + 1 : argv0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print current location to current monitor if we have one, else to stderr.
|
||||
*/
|
||||
void error_print_loc(void)
|
||||
{
|
||||
const char *sep = "";
|
||||
int i;
|
||||
const char *const *argp;
|
||||
|
||||
if (!cur_mon) {
|
||||
fprintf(stderr, "%s:", progname);
|
||||
sep = " ";
|
||||
}
|
||||
switch (cur_loc->kind) {
|
||||
case LOC_CMDLINE:
|
||||
argp = cur_loc->ptr;
|
||||
for (i = 0; i < cur_loc->num; i++) {
|
||||
error_printf("%s%s", sep, argp[i]);
|
||||
sep = " ";
|
||||
}
|
||||
error_printf(": ");
|
||||
break;
|
||||
case LOC_FILE:
|
||||
error_printf("%s:", (const char *)cur_loc->ptr);
|
||||
if (cur_loc->num) {
|
||||
error_printf("%d:", cur_loc->num);
|
||||
}
|
||||
error_printf(" ");
|
||||
break;
|
||||
default:
|
||||
error_printf(sep);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print an error message to current monitor if we have one, else to stderr.
|
||||
* Prepend the current location and append a newline.
|
||||
* It's wrong to call this in a QMP monitor. Use qerror_report() there.
|
||||
*/
|
||||
void error_report(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
error_print_loc();
|
||||
va_start(ap, fmt);
|
||||
error_vprintf(fmt, ap);
|
||||
va_end(ap);
|
||||
error_printf("\n");
|
||||
}
|
||||
|
||||
void qerror_report_internal(const char *file, int linenr, const char *func,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
QError *qerror;
|
||||
|
||||
va_start(va, fmt);
|
||||
qerror = qerror_from_info(file, linenr, func, fmt, &va);
|
||||
va_end(va);
|
||||
|
||||
if (monitor_cur_is_qmp()) {
|
||||
monitor_set_error(cur_mon, qerror);
|
||||
} else {
|
||||
qerror_print(qerror);
|
||||
QDECREF(qerror);
|
||||
}
|
||||
}
|
47
qemu-error.h
Normal file
47
qemu-error.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Error reporting
|
||||
*
|
||||
* Copyright (C) 2010 Red Hat Inc.
|
||||
*
|
||||
* Authors:
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_ERROR_H
|
||||
#define QEMU_ERROR_H
|
||||
|
||||
typedef struct Location {
|
||||
/* all members are private to qemu-error.c */
|
||||
enum { LOC_NONE, LOC_CMDLINE, LOC_FILE } kind;
|
||||
int num;
|
||||
const void *ptr;
|
||||
struct Location *prev;
|
||||
} Location;
|
||||
|
||||
Location *loc_push_restore(Location *loc);
|
||||
Location *loc_push_none(Location *loc);
|
||||
Location *loc_pop(Location *loc);
|
||||
Location *loc_save(Location *loc);
|
||||
void loc_restore(Location *loc);
|
||||
void loc_set_none(void);
|
||||
void loc_set_cmdline(char **argv, int idx, int cnt);
|
||||
void loc_set_file(const char *fname, int lno);
|
||||
|
||||
void error_vprintf(const char *fmt, va_list ap);
|
||||
void error_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
|
||||
void error_printf_unless_qmp(const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 1, 2)));
|
||||
void error_print_loc(void);
|
||||
void error_set_progname(const char *argv0);
|
||||
void error_report(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
|
||||
void qerror_report_internal(const char *file, int linenr, const char *func,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 4, 5)));
|
||||
|
||||
#define qerror_report(fmt, ...) \
|
||||
qerror_report_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
|
||||
|
||||
#endif
|
@ -570,10 +570,11 @@ ETEXI
|
||||
|
||||
{
|
||||
.name = "device_add",
|
||||
.args_type = "config:s",
|
||||
.params = "device",
|
||||
.args_type = "device:O",
|
||||
.params = "driver[,prop=value][,...]",
|
||||
.help = "add device, like -device on the command line",
|
||||
.mhandler.cmd = do_device_add,
|
||||
.user_print = monitor_user_noop,
|
||||
.mhandler.cmd_new = do_device_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
#include "qemu-objects.h"
|
||||
#include "qemu-option.h"
|
||||
|
||||
/*
|
||||
@ -483,6 +485,7 @@ struct QemuOpt {
|
||||
struct QemuOpts {
|
||||
char *id;
|
||||
QemuOptsList *list;
|
||||
Location loc;
|
||||
QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
|
||||
QTAILQ_ENTRY(QemuOpts) next;
|
||||
};
|
||||
@ -653,6 +656,7 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exist
|
||||
opts->id = qemu_strdup(id);
|
||||
}
|
||||
opts->list = list;
|
||||
loc_save(&opts->loc);
|
||||
QTAILQ_INIT(&opts->head);
|
||||
QTAILQ_INSERT_TAIL(&list->head, opts, next);
|
||||
return opts;
|
||||
@ -749,12 +753,17 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname
|
||||
return 0;
|
||||
}
|
||||
|
||||
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname)
|
||||
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
|
||||
int permit_abbrev)
|
||||
{
|
||||
const char *firstname;
|
||||
char value[1024], *id = NULL;
|
||||
const char *p;
|
||||
QemuOpts *opts;
|
||||
|
||||
assert(!permit_abbrev || list->implied_opt_name);
|
||||
firstname = permit_abbrev ? list->implied_opt_name : NULL;
|
||||
|
||||
if (strncmp(params, "id=", 3) == 0) {
|
||||
get_opt_value(value, sizeof(value), params+3);
|
||||
id = qemu_strdup(value);
|
||||
@ -774,6 +783,84 @@ QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *fi
|
||||
return opts;
|
||||
}
|
||||
|
||||
static void qemu_opts_from_qdict_1(const char *key, QObject *obj, void *opaque)
|
||||
{
|
||||
char buf[32];
|
||||
const char *value;
|
||||
int n;
|
||||
|
||||
if (!strcmp(key, "id")) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (qobject_type(obj)) {
|
||||
case QTYPE_QSTRING:
|
||||
value = qstring_get_str(qobject_to_qstring(obj));
|
||||
break;
|
||||
case QTYPE_QINT:
|
||||
n = snprintf(buf, sizeof(buf), "%" PRId64,
|
||||
qint_get_int(qobject_to_qint(obj)));
|
||||
assert(n < sizeof(buf));
|
||||
value = buf;
|
||||
break;
|
||||
case QTYPE_QFLOAT:
|
||||
n = snprintf(buf, sizeof(buf), "%.17g",
|
||||
qfloat_get_double(qobject_to_qfloat(obj)));
|
||||
assert(n < sizeof(buf));
|
||||
value = buf;
|
||||
break;
|
||||
case QTYPE_QBOOL:
|
||||
strcpy(buf, qbool_get_int(qobject_to_qbool(obj)) ? "on" : "off");
|
||||
value = buf;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
qemu_opt_set(opaque, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create QemuOpts from a QDict.
|
||||
* Use value of key "id" as ID if it exists and is a QString.
|
||||
* Only QStrings, QInts, QFloats and QBools are copied. Entries with
|
||||
* other types are silently ignored.
|
||||
*/
|
||||
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict)
|
||||
{
|
||||
QemuOpts *opts;
|
||||
|
||||
opts = qemu_opts_create(list, qdict_get_try_str(qdict, "id"), 1);
|
||||
if (opts == NULL)
|
||||
return NULL;
|
||||
|
||||
qdict_iter(qdict, qemu_opts_from_qdict_1, opts);
|
||||
return opts;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from QemuOpts to QDict.
|
||||
* The QDict values are of type QString.
|
||||
* TODO We'll want to use types appropriate for opt->desc->type, but
|
||||
* this is enough for now.
|
||||
*/
|
||||
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict)
|
||||
{
|
||||
QemuOpt *opt;
|
||||
QObject *val;
|
||||
|
||||
if (!qdict) {
|
||||
qdict = qdict_new();
|
||||
}
|
||||
if (opts->id) {
|
||||
qdict_put(qdict, "id", qstring_from_str(opts->id));
|
||||
}
|
||||
QTAILQ_FOREACH(opt, &opts->head, next) {
|
||||
val = QOBJECT(qstring_from_str(opt->str));
|
||||
qdict_put_obj(qdict, opt->name, val);
|
||||
}
|
||||
return qdict;
|
||||
}
|
||||
|
||||
/* Validate parsed opts against descriptions where no
|
||||
* descriptions were provided in the QemuOptsList.
|
||||
*/
|
||||
@ -810,13 +897,17 @@ int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
|
||||
int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
|
||||
int abort_on_failure)
|
||||
{
|
||||
Location loc;
|
||||
QemuOpts *opts;
|
||||
int rc = 0;
|
||||
|
||||
loc_push_none(&loc);
|
||||
QTAILQ_FOREACH(opts, &list->head, next) {
|
||||
loc_restore(&opts->loc);
|
||||
rc |= func(opts, opaque);
|
||||
if (abort_on_failure && rc != 0)
|
||||
break;
|
||||
}
|
||||
loc_pop(&loc);
|
||||
return rc;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "qemu-queue.h"
|
||||
#include "qdict.h"
|
||||
|
||||
enum QEMUOptionParType {
|
||||
OPT_FLAG,
|
||||
@ -96,6 +97,7 @@ typedef struct QemuOptDesc {
|
||||
|
||||
struct QemuOptsList {
|
||||
const char *name;
|
||||
const char *implied_opt_name;
|
||||
QTAILQ_HEAD(, QemuOpts) head;
|
||||
QemuOptDesc desc[];
|
||||
};
|
||||
@ -117,7 +119,9 @@ const char *qemu_opts_id(QemuOpts *opts);
|
||||
void qemu_opts_del(QemuOpts *opts);
|
||||
int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
|
||||
int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
|
||||
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname);
|
||||
QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
|
||||
QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
|
||||
QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
|
||||
|
||||
typedef int (*qemu_opts_loopfunc)(QemuOpts *opts, void *opaque);
|
||||
int qemu_opts_print(QemuOpts *opts, void *dummy);
|
||||
|
30
qemu-tool.c
30
qemu-tool.c
@ -13,9 +13,9 @@
|
||||
|
||||
#include "qemu-common.h"
|
||||
#include "monitor.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "qemu-log.h"
|
||||
#include "qemu-error.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
@ -33,8 +33,6 @@ void qemu_service_io(void)
|
||||
{
|
||||
}
|
||||
|
||||
Monitor *cur_mon;
|
||||
|
||||
void monitor_printf(Monitor *mon, const char *fmt, ...)
|
||||
{
|
||||
}
|
||||
@ -106,7 +104,31 @@ int64_t qemu_get_clock(QEMUClock *clock)
|
||||
return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
|
||||
}
|
||||
|
||||
void qemu_error(const char *fmt, ...)
|
||||
Location *loc_push_restore(Location *loc)
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
Location *loc_push_none(Location *loc)
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
Location *loc_pop(Location *loc)
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
Location *loc_save(Location *loc)
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
void loc_restore(Location *loc)
|
||||
{
|
||||
}
|
||||
|
||||
void error_report(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
83
qerror.c
83
qerror.c
@ -12,8 +12,8 @@
|
||||
#include "qjson.h"
|
||||
#include "qerror.h"
|
||||
#include "qstring.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu-error.h"
|
||||
|
||||
static void qerror_destroy_obj(QObject *obj);
|
||||
|
||||
@ -40,49 +40,69 @@ static const QType qerror_type = {
|
||||
* "running out of foo: %(foo)%%"
|
||||
*/
|
||||
static const QErrorStringTable qerror_table[] = {
|
||||
{
|
||||
.error_fmt = QERR_BAD_BUS_FOR_DEVICE,
|
||||
.desc = "Device '%(device)' can't go on a %(bad_bus_type) bus",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_BUS_NOT_FOUND,
|
||||
.desc = "Bus '%(bus)' not found",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_BUS_NO_HOTPLUG,
|
||||
.desc = "Bus '%(bus)' does not support hotplugging",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_COMMAND_NOT_FOUND,
|
||||
.desc = "The command %(name) has not been found",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_ENCRYPTED,
|
||||
.desc = "The %(device) is encrypted",
|
||||
.desc = "Device '%(device)' is encrypted",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_INIT_FAILED,
|
||||
.desc = "Device '%(device)' could not be initialized",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_LOCKED,
|
||||
.desc = "Device %(device) is locked",
|
||||
.desc = "Device '%(device)' is locked",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_MULTIPLE_BUSSES,
|
||||
.desc = "Device '%(device)' has multiple child busses",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_NOT_ACTIVE,
|
||||
.desc = "The %(device) device has not been activated by the guest",
|
||||
.desc = "Device '%(device)' has not been activated by the guest",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_NOT_FOUND,
|
||||
.desc = "The %(device) device has not been found",
|
||||
.desc = "Device '%(device)' not found",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_NOT_REMOVABLE,
|
||||
.desc = "Device %(device) is not removable",
|
||||
.desc = "Device '%(device)' is not removable",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_DEVICE_NO_BUS,
|
||||
.desc = "Device '%(device)' has no child bus",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_FD_NOT_FOUND,
|
||||
.desc = "Failed to find file descriptor named %(name)",
|
||||
.desc = "File descriptor named '%(name)' not found",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_FD_NOT_SUPPLIED,
|
||||
.desc = "No file descriptor supplied via SCM_RIGHTS",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_OPEN_FILE_FAILED,
|
||||
.desc = "Could not open '%(filename)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_INVALID_BLOCK_FORMAT,
|
||||
.desc = "Invalid block format %(name)",
|
||||
.desc = "Invalid block format '%(name)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_INVALID_PARAMETER,
|
||||
.desc = "Invalid parameter %(name)",
|
||||
.desc = "Invalid parameter '%(name)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_INVALID_PARAMETER_TYPE,
|
||||
@ -90,7 +110,7 @@ static const QErrorStringTable qerror_table[] = {
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_INVALID_PASSWORD,
|
||||
.desc = "The entered password is invalid",
|
||||
.desc = "Password incorrect",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_JSON_PARSING,
|
||||
@ -102,7 +122,31 @@ static const QErrorStringTable qerror_table[] = {
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_MISSING_PARAMETER,
|
||||
.desc = "Parameter %(name) is missing",
|
||||
.desc = "Parameter '%(name)' is missing",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_NO_BUS_FOR_DEVICE,
|
||||
.desc = "No '%(bus)' bus found for device '%(device)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_OPEN_FILE_FAILED,
|
||||
.desc = "Could not open '%(filename)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_PROPERTY_NOT_FOUND,
|
||||
.desc = "Property '%(device).%(property)' not found",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_PROPERTY_VALUE_BAD,
|
||||
.desc = "Property '%(device).%(property)' doesn't take value '%(value)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_PROPERTY_VALUE_IN_USE,
|
||||
.desc = "Property '%(device).%(property)' can't take value '%(value)', it's in use",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_PROPERTY_VALUE_NOT_FOUND,
|
||||
.desc = "Property '%(device).%(property)' can't find value '%(value)'",
|
||||
},
|
||||
{
|
||||
.error_fmt = QERR_QMP_BAD_INPUT_OBJECT,
|
||||
@ -224,6 +268,7 @@ QError *qerror_from_info(const char *file, int linenr, const char *func,
|
||||
QError *qerr;
|
||||
|
||||
qerr = qerror_new();
|
||||
loc_save(&qerr->loc);
|
||||
qerr->linenr = linenr;
|
||||
qerr->file = file;
|
||||
qerr->func = func;
|
||||
@ -318,13 +363,15 @@ QString *qerror_human(const QError *qerror)
|
||||
* qerror_print(): Print QError data
|
||||
*
|
||||
* This function will print the member 'desc' of the specified QError object,
|
||||
* it uses qemu_error() for this, so that the output is routed to the right
|
||||
* it uses error_report() for this, so that the output is routed to the right
|
||||
* place (ie. stderr or Monitor's device).
|
||||
*/
|
||||
void qerror_print(const QError *qerror)
|
||||
void qerror_print(QError *qerror)
|
||||
{
|
||||
QString *qstring = qerror_human(qerror);
|
||||
qemu_error("%s\n", qstring_get_str(qstring));
|
||||
loc_push_restore(&qerror->loc);
|
||||
error_report("%s", qstring_get_str(qstring));
|
||||
loc_pop(&qerror->loc);
|
||||
QDECREF(qstring);
|
||||
}
|
||||
|
||||
|
51
qerror.h
51
qerror.h
@ -14,6 +14,7 @@
|
||||
|
||||
#include "qdict.h"
|
||||
#include "qstring.h"
|
||||
#include "qemu-error.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct QErrorStringTable {
|
||||
@ -24,6 +25,7 @@ typedef struct QErrorStringTable {
|
||||
typedef struct QError {
|
||||
QObject_HEAD;
|
||||
QDict *error;
|
||||
Location loc;
|
||||
int linenr;
|
||||
const char *file;
|
||||
const char *func;
|
||||
@ -34,21 +36,36 @@ QError *qerror_new(void);
|
||||
QError *qerror_from_info(const char *file, int linenr, const char *func,
|
||||
const char *fmt, va_list *va);
|
||||
QString *qerror_human(const QError *qerror);
|
||||
void qerror_print(const QError *qerror);
|
||||
void qerror_print(QError *qerror);
|
||||
QError *qobject_to_qerror(const QObject *obj);
|
||||
|
||||
/*
|
||||
* QError class list
|
||||
*/
|
||||
#define QERR_BAD_BUS_FOR_DEVICE \
|
||||
"{ 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s } }"
|
||||
|
||||
#define QERR_BUS_NOT_FOUND \
|
||||
"{ 'class': 'BusNotFound', 'data': { 'bus': %s } }"
|
||||
|
||||
#define QERR_BUS_NO_HOTPLUG \
|
||||
"{ 'class': 'BusNoHotplug', 'data': { 'bus': %s } }"
|
||||
|
||||
#define QERR_COMMAND_NOT_FOUND \
|
||||
"{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
|
||||
|
||||
#define QERR_DEVICE_ENCRYPTED \
|
||||
"{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_DEVICE_LOCKED \
|
||||
#define QERR_DEVICE_INIT_FAILED \
|
||||
"{ 'class': 'DeviceInitFailed', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_DEVICE_LOCKED \
|
||||
"{ 'class': 'DeviceLocked', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_DEVICE_MULTIPLE_BUSSES \
|
||||
"{ 'class': 'DeviceMultipleBusses', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_DEVICE_NOT_ACTIVE \
|
||||
"{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }"
|
||||
|
||||
@ -58,15 +75,15 @@ QError *qobject_to_qerror(const QObject *obj);
|
||||
#define QERR_DEVICE_NOT_REMOVABLE \
|
||||
"{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_DEVICE_NO_BUS \
|
||||
"{ 'class': 'DeviceNoBus', 'data': { 'device': %s } }"
|
||||
|
||||
#define QERR_FD_NOT_FOUND \
|
||||
"{ 'class': 'FdNotFound', 'data': { 'name': %s } }"
|
||||
|
||||
#define QERR_FD_NOT_SUPPLIED \
|
||||
"{ 'class': 'FdNotSupplied', 'data': {} }"
|
||||
|
||||
#define QERR_OPEN_FILE_FAILED \
|
||||
"{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
|
||||
|
||||
#define QERR_INVALID_BLOCK_FORMAT \
|
||||
"{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }"
|
||||
|
||||
@ -88,18 +105,36 @@ QError *qobject_to_qerror(const QObject *obj);
|
||||
#define QERR_MISSING_PARAMETER \
|
||||
"{ 'class': 'MissingParameter', 'data': { 'name': %s } }"
|
||||
|
||||
#define QERR_NO_BUS_FOR_DEVICE \
|
||||
"{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }"
|
||||
|
||||
#define QERR_OPEN_FILE_FAILED \
|
||||
"{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }"
|
||||
|
||||
#define QERR_PROPERTY_NOT_FOUND \
|
||||
"{ 'class': 'PropertyNotFound', 'data': { 'device': %s, 'property': %s } }"
|
||||
|
||||
#define QERR_PROPERTY_VALUE_BAD \
|
||||
"{ 'class': 'PropertyValueBad', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
|
||||
|
||||
#define QERR_PROPERTY_VALUE_IN_USE \
|
||||
"{ 'class': 'PropertyValueInUse', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
|
||||
|
||||
#define QERR_PROPERTY_VALUE_NOT_FOUND \
|
||||
"{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
|
||||
|
||||
#define QERR_QMP_BAD_INPUT_OBJECT \
|
||||
"{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }"
|
||||
|
||||
#define QERR_SET_PASSWD_FAILED \
|
||||
"{ 'class': 'SetPasswdFailed', 'data': {} }"
|
||||
|
||||
#define QERR_UNDEFINED_ERROR \
|
||||
"{ 'class': 'UndefinedError', 'data': {} }"
|
||||
|
||||
#define QERR_TOO_MANY_FILES \
|
||||
"{ 'class': 'TooManyFiles', 'data': {} }"
|
||||
|
||||
#define QERR_UNDEFINED_ERROR \
|
||||
"{ 'class': 'UndefinedError', 'data': {} }"
|
||||
|
||||
#define QERR_VNC_SERVER_FAILED \
|
||||
"{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
|
||||
|
||||
|
27
savevm.c
27
savevm.c
@ -1737,7 +1737,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
|
||||
vm_start();
|
||||
}
|
||||
|
||||
int load_vmstate(Monitor *mon, const char *name)
|
||||
int load_vmstate(const char *name)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
BlockDriverState *bs, *bs1;
|
||||
@ -1747,7 +1747,7 @@ int load_vmstate(Monitor *mon, const char *name)
|
||||
|
||||
bs = get_bs_snapshots();
|
||||
if (!bs) {
|
||||
monitor_printf(mon, "No block device supports snapshots\n");
|
||||
error_report("No block device supports snapshots");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1759,22 +1759,21 @@ int load_vmstate(Monitor *mon, const char *name)
|
||||
if (bdrv_has_snapshot(bs1)) {
|
||||
ret = bdrv_snapshot_goto(bs1, name);
|
||||
if (ret < 0) {
|
||||
if (bs != bs1)
|
||||
monitor_printf(mon, "Warning: ");
|
||||
switch(ret) {
|
||||
case -ENOTSUP:
|
||||
monitor_printf(mon,
|
||||
"Snapshots not supported on device '%s'\n",
|
||||
bdrv_get_device_name(bs1));
|
||||
error_report("%sSnapshots not supported on device '%s'",
|
||||
bs != bs1 ? "Warning: " : "",
|
||||
bdrv_get_device_name(bs1));
|
||||
break;
|
||||
case -ENOENT:
|
||||
monitor_printf(mon, "Could not find snapshot '%s' on "
|
||||
"device '%s'\n",
|
||||
name, bdrv_get_device_name(bs1));
|
||||
error_report("%sCould not find snapshot '%s' on device '%s'",
|
||||
bs != bs1 ? "Warning: " : "",
|
||||
name, bdrv_get_device_name(bs1));
|
||||
break;
|
||||
default:
|
||||
monitor_printf(mon, "Error %d while activating snapshot on"
|
||||
" '%s'\n", ret, bdrv_get_device_name(bs1));
|
||||
error_report("%sError %d while activating snapshot on '%s'",
|
||||
bs != bs1 ? "Warning: " : "",
|
||||
ret, bdrv_get_device_name(bs1));
|
||||
break;
|
||||
}
|
||||
/* fatal on snapshot block device */
|
||||
@ -1792,13 +1791,13 @@ int load_vmstate(Monitor *mon, const char *name)
|
||||
/* restore the VM state */
|
||||
f = qemu_fopen_bdrv(bs, 0);
|
||||
if (!f) {
|
||||
monitor_printf(mon, "Could not open VM state file\n");
|
||||
error_report("Could not open VM state file");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = qemu_loadvm_state(f);
|
||||
qemu_fclose(f);
|
||||
if (ret < 0) {
|
||||
monitor_printf(mon, "Error %d while loading VM state\n", ret);
|
||||
error_report("Error %d while loading VM state", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
|
@ -260,7 +260,7 @@ void lprint(const char *format, ...)
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
monitor_vprintf(cur_mon, format, args);
|
||||
monitor_vprintf(default_mon, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
13
sysemu.h
13
sysemu.h
@ -54,7 +54,7 @@ extern qemu_irq qemu_system_powerdown;
|
||||
void qemu_system_reset(void);
|
||||
|
||||
void do_savevm(Monitor *mon, const QDict *qdict);
|
||||
int load_vmstate(Monitor *mon, const char *name);
|
||||
int load_vmstate(const char *name);
|
||||
void do_delvm(Monitor *mon, const QDict *qdict);
|
||||
void do_info_snapshots(Monitor *mon);
|
||||
|
||||
@ -73,17 +73,6 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f);
|
||||
void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f);
|
||||
int qemu_loadvm_state(QEMUFile *f);
|
||||
|
||||
void qemu_errors_to_file(FILE *fp);
|
||||
void qemu_errors_to_mon(Monitor *mon);
|
||||
void qemu_errors_to_previous(void);
|
||||
void qemu_error(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
|
||||
void qemu_error_internal(const char *file, int linenr, const char *func,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((format(printf, 4, 5)));
|
||||
|
||||
#define qemu_error_new(fmt, ...) \
|
||||
qemu_error_internal(__FILE__, __LINE__, __func__, fmt, ## __VA_ARGS__)
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Polling handling */
|
||||
|
||||
|
@ -1188,9 +1188,6 @@ static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
|
||||
*/
|
||||
static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name)
|
||||
{
|
||||
#if 0
|
||||
Monitor *mon = cur_mon;
|
||||
#endif
|
||||
FILE *f;
|
||||
int ret = 0;
|
||||
char filename[PATH_MAX];
|
||||
@ -1201,11 +1198,6 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f
|
||||
if (f) {
|
||||
ret = fgets(line, line_size, f) != NULL;
|
||||
fclose(f);
|
||||
#if 0
|
||||
} else {
|
||||
if (mon)
|
||||
monitor_printf(mon, "husb: could not open %s\n", filename);
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
44
vl.c
44
vl.c
@ -1813,7 +1813,7 @@ QemuOpts *drive_add(const char *file, const char *fmt, ...)
|
||||
vsnprintf(optstr, sizeof(optstr), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
opts = qemu_opts_parse(&qemu_drive_opts, optstr, NULL);
|
||||
opts = qemu_opts_parse(&qemu_drive_opts, optstr, 0);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "%s: huh? duplicate? (%s)\n",
|
||||
__FUNCTION__, optstr);
|
||||
@ -2539,7 +2539,7 @@ void do_usb_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *devname = qdict_get_str(qdict, "devname");
|
||||
if (usb_device_add(devname, 1) < 0) {
|
||||
qemu_error("could not add USB device '%s'\n", devname);
|
||||
error_report("could not add USB device '%s'", devname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2547,7 +2547,7 @@ void do_usb_del(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *devname = qdict_get_str(qdict, "devname");
|
||||
if (usb_device_del(devname) < 0) {
|
||||
qemu_error("could not delete USB device '%s'\n", devname);
|
||||
error_report("could not delete USB device '%s'", devname);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4370,7 +4370,7 @@ static int balloon_parse(const char *arg)
|
||||
if (!strncmp(arg, "virtio", 6)) {
|
||||
if (arg[6] == ',') {
|
||||
/* have params -> parse them */
|
||||
opts = qemu_opts_parse(&qemu_device_opts, arg+7, NULL);
|
||||
opts = qemu_opts_parse(&qemu_device_opts, arg+7, 0);
|
||||
if (!opts)
|
||||
return -1;
|
||||
} else {
|
||||
@ -4796,6 +4796,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
||||
char *r = argv[optind];
|
||||
const char *optarg;
|
||||
|
||||
loc_set_cmdline(argv, optind, 1);
|
||||
optind++;
|
||||
/* Treat --foo the same as -foo. */
|
||||
if (r[1] == '-')
|
||||
@ -4803,8 +4804,7 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
||||
popt = qemu_options;
|
||||
for(;;) {
|
||||
if (!popt->name) {
|
||||
fprintf(stderr, "%s: invalid option -- '%s'\n",
|
||||
argv[0], r);
|
||||
error_report("invalid option");
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(popt->name, r + 1))
|
||||
@ -4813,11 +4813,11 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
|
||||
}
|
||||
if (popt->flags & HAS_ARG) {
|
||||
if (optind >= argc) {
|
||||
fprintf(stderr, "%s: option '%s' requires an argument\n",
|
||||
argv[0], r);
|
||||
error_report("requires an argument");
|
||||
exit(1);
|
||||
}
|
||||
optarg = argv[optind++];
|
||||
loc_set_cmdline(argv, optind - 2, 2);
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
@ -4862,9 +4862,10 @@ int main(int argc, char **argv, char **envp)
|
||||
int show_vnc_port = 0;
|
||||
int defconfig = 1;
|
||||
|
||||
error_set_progname(argv[0]);
|
||||
|
||||
init_clocks();
|
||||
|
||||
qemu_errors_to_file(stderr);
|
||||
qemu_cache_utils_init(envp);
|
||||
|
||||
QLIST_INIT (&vm_change_state_head);
|
||||
@ -4940,18 +4941,22 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
|
||||
if (defconfig) {
|
||||
const char *fname;
|
||||
FILE *fp;
|
||||
fp = fopen(CONFIG_QEMU_CONFDIR "/qemu.conf", "r");
|
||||
|
||||
fname = CONFIG_QEMU_CONFDIR "/qemu.conf";
|
||||
fp = fopen(fname, "r");
|
||||
if (fp) {
|
||||
if (qemu_config_parse(fp) != 0) {
|
||||
if (qemu_config_parse(fp, fname) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
fp = fopen(CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf", "r");
|
||||
fname = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf";
|
||||
fp = fopen(fname, "r");
|
||||
if (fp) {
|
||||
if (qemu_config_parse(fp) != 0) {
|
||||
if (qemu_config_parse(fp, fname) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
fclose(fp);
|
||||
@ -5360,7 +5365,7 @@ int main(int argc, char **argv, char **envp)
|
||||
default_monitor = 0;
|
||||
break;
|
||||
case QEMU_OPTION_mon:
|
||||
opts = qemu_opts_parse(&qemu_mon_opts, optarg, "chardev");
|
||||
opts = qemu_opts_parse(&qemu_mon_opts, optarg, 1);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
@ -5368,7 +5373,7 @@ int main(int argc, char **argv, char **envp)
|
||||
default_monitor = 0;
|
||||
break;
|
||||
case QEMU_OPTION_chardev:
|
||||
opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
|
||||
opts = qemu_opts_parse(&qemu_chardev_opts, optarg, 1);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
@ -5471,7 +5476,7 @@ int main(int argc, char **argv, char **envp)
|
||||
add_device_config(DEV_USB, optarg);
|
||||
break;
|
||||
case QEMU_OPTION_device:
|
||||
if (!qemu_opts_parse(&qemu_device_opts, optarg, "driver")) {
|
||||
if (!qemu_opts_parse(&qemu_device_opts, optarg, 1)) {
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
@ -5580,7 +5585,7 @@ int main(int argc, char **argv, char **envp)
|
||||
configure_rtc_date_offset(optarg, 1);
|
||||
break;
|
||||
case QEMU_OPTION_rtc:
|
||||
opts = qemu_opts_parse(&qemu_rtc_opts, optarg, NULL);
|
||||
opts = qemu_opts_parse(&qemu_rtc_opts, optarg, 0);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
@ -5641,7 +5646,7 @@ int main(int argc, char **argv, char **envp)
|
||||
fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (qemu_config_parse(fp) != 0) {
|
||||
if (qemu_config_parse(fp, optarg) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
fclose(fp);
|
||||
@ -5666,6 +5671,7 @@ int main(int argc, char **argv, char **envp)
|
||||
}
|
||||
}
|
||||
}
|
||||
loc_set_none();
|
||||
|
||||
/* If no data_dir is specified then try to find it relative to the
|
||||
executable path. */
|
||||
@ -6081,7 +6087,7 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
qemu_system_reset();
|
||||
if (loadvm) {
|
||||
if (load_vmstate(cur_mon, loadvm) < 0) {
|
||||
if (load_vmstate(loadvm) < 0) {
|
||||
autostart = 0;
|
||||
}
|
||||
}
|
||||
|
5
vnc.c
5
vnc.c
@ -1046,11 +1046,10 @@ static void audio_capture(void *opaque, void *buf, int size)
|
||||
|
||||
static void audio_add(VncState *vs)
|
||||
{
|
||||
Monitor *mon = cur_mon;
|
||||
struct audio_capture_ops ops;
|
||||
|
||||
if (vs->audio_cap) {
|
||||
monitor_printf(mon, "audio already running\n");
|
||||
monitor_printf(default_mon, "audio already running\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1060,7 +1059,7 @@ static void audio_add(VncState *vs)
|
||||
|
||||
vs->audio_cap = AUD_add_capture(&vs->as, &ops, vs);
|
||||
if (!vs->audio_cap) {
|
||||
monitor_printf(mon, "Failed to add audio capture\n");
|
||||
monitor_printf(default_mon, "Failed to add audio capture\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user