[libvirt] Keep qemu capability data for each VM from startup

Currently, whenever we require QEMU capabilities data, we rerun QEMU to extract the info. This isn't desirable because it is inefficient and the QEMU binary may have changed since we started the guest. This series makes us keep a copy of the capability data around for lifetime of the VM process

To cope with the QEMU binary being changed while a VM is running, it is neccessary to persist the original qemu capabilities at the time the VM is booted. * src/qemu/qemu_capabilities.c, src/qemu/qemu_capabilities.h: Add an enum for a string rep of every capability * src/qemu/qemu_domain.c, src/qemu/qemu_domain.h: Support for storing capabilities in the domain status XML * src/qemu/qemu_process.c: Populate & free QEMU capabilities at domain startup --- src/qemu/qemu_capabilities.c | 78 ++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_domain.c | 45 ++++++++++++++++++++++++ src/qemu/qemu_domain.h | 3 ++ src/qemu/qemu_process.c | 42 +++++++++++----------- 5 files changed, 148 insertions(+), 21 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 63486cc..620143e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -43,6 +43,84 @@ #define VIR_FROM_THIS VIR_FROM_QEMU +/* While not public, these strings must not change. They + * are used in domain status files which are read on + * daemon restarts + */ +VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, + "kqemu", /* 0 */ + "vnc-colon", + "no-reboot", + "drive", + "drive-boot", + + "name", /* 5 */ + "uuid", + "domid", + "vnet-hdr", + "migrate-kvm-stdio", + + "migrate-qemu-tcp", /* 10 */ + "migrate-qemu-exec", + "drive-cache-v2", + "kvm", + "drive-format", + + "vga", /* 15 */ + "0.10", + "pci-device", + "mem-path", + "drive-serial", + + "xen-domid", /* 20 */ + "migrate-qemu-unix", + "chardev", + "enable-kvm", + "monitor-json", + + "balloon", /* 25 */ + "device", + "sdl", + "smp-topology", + "netdev", + + "rtc", /* 30 */ + "vnet-host", + "rtc-td-hack", + "no-hpet", + "no-kvm-pit", + + "tdf", /* 35 */ + "pci-configfd", + "nodefconfig", + "boot-menu", + "enable-kqemu", + + "fsdev", /* 40 */ + "nesting", + "name-process", + "drive-readonly", + "smbios-type", + + "vga-qxl", /* 45 */ + "spice", + "vga-none", + "migrate-qemu-fd", + "boot-index", + + "hda-duplex", /* 50 */ + "drive-aio", + "pci-multibus", + "pci-bootindex", + "ccid-emulated", + + "ccid-passthru", /* 55 */ + "chardev-spicevmc", + "device-spicevmc", + "virtio-tx-alg", + "device-qxl-vga", + ); + struct qemu_feature_flags { const char *name; const int default_on; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 68c5958..ab47f22 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -141,5 +141,6 @@ int qemuCapsParseHelpStr(const char *qemu, int qemuCapsParseDeviceStr(const char *str, virBitmapPtr qemuCaps); +VIR_ENUM_DECL(qemuCaps); #endif /* __QEMU_CAPABILITIES_H__*/ diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a947b4e..3033ff5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -25,6 +25,7 @@ #include "qemu_domain.h" #include "qemu_command.h" +#include "qemu_capabilities.h" #include "memory.h" #include "logging.h" #include "virterror_internal.h" @@ -113,6 +114,8 @@ static void qemuDomainObjPrivateFree(void *data) { qemuDomainObjPrivatePtr priv = data; + qemuCapsFree(priv->qemuCaps); + qemuDomainPCIAddressSetFree(priv->pciaddrs); virDomainChrSourceDefFree(priv->monConfig); VIR_FREE(priv->vcpupids); @@ -160,6 +163,18 @@ static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) virBufferAddLit(buf, " </vcpus>\n"); } + if (priv->qemuCaps) { + int i; + virBufferAddLit(buf, " <qemuCaps>\n"); + for (i = 0 ; i < QEMU_CAPS_LAST ; i++) { + if (qemuCapsGet(priv->qemuCaps, i)) { + virBufferVSprintf(buf, " <flag name='%s'/>\n", + qemuCapsTypeToString(i)); + } + } + virBufferAddLit(buf, " </qemuCaps>\n"); + } + return 0; } @@ -170,6 +185,7 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) char *tmp; int n, i; xmlNodePtr *nodes = NULL; + virBitmapPtr qemuCaps = NULL; if (VIR_ALLOC(priv->monConfig) < 0) { virReportOOMError(); @@ -235,12 +251,41 @@ static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) VIR_FREE(nodes); } + if ((n = virXPathNodeSet("./qemuCaps/flag", ctxt, &nodes)) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("failed to parse qemu capabilities flags")); + goto error; + } + if (n > 0) { + if (!(qemuCaps = qemuCapsNew())) + goto error; + + for (i = 0 ; i < n ; i++) { + char *str = virXMLPropString(nodes[i], "name"); + if (str) { + int flag = qemuCapsTypeFromString(str); + VIR_FREE(str); + if (flag < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown qemu capabilities flag %s"), str); + goto error; + } + qemuCapsSet(qemuCaps, flag); + } + } + + priv->qemuCaps = qemuCaps; + } + VIR_FREE(nodes); + + return 0; error: virDomainChrSourceDefFree(priv->monConfig); priv->monConfig = NULL; VIR_FREE(nodes); + qemuCapsFree(qemuCaps); return -1; } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 8258900..b0ecc5a 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -28,6 +28,7 @@ # include "domain_conf.h" # include "qemu_monitor.h" # include "qemu_conf.h" +# include "bitmap.h" /* Only 1 job is allowed at any time * A job includes *all* monitor commands, even those just querying @@ -77,6 +78,8 @@ struct _qemuDomainObjPrivate { qemuDomainPCIAddressSetPtr pciaddrs; int persistentAddrs; + + virBitmapPtr qemuCaps; }; struct qemuDomainWatchdogEvent diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 7691cbe..eb2050d 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1288,8 +1288,7 @@ qemuProcessSetVcpuAffinites(virConnectPtr conn, static int qemuProcessInitPasswords(virConnectPtr conn, struct qemud_driver *driver, - virDomainObjPtr vm, - virBitmapPtr qemuCaps) + virDomainObjPtr vm) { int ret = 0; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -1311,7 +1310,7 @@ qemuProcessInitPasswords(virConnectPtr conn, if (ret < 0) goto cleanup; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { int i; for (i = 0 ; i < vm->def->ndisks ; i++) { @@ -1965,7 +1964,6 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa struct qemuProcessReconnectData *data = opaque; struct qemud_driver *driver = data->driver; qemuDomainObjPrivatePtr priv; - virBitmapPtr qemuCaps = NULL; virConnectPtr conn = data->conn; virDomainObjLock(obj); @@ -1986,13 +1984,16 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa goto error; } - /* XXX we should be persisting the original flags in the XML - * not re-detecting them, since the binary may have changed - * since launch time */ - if (qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch, + /* If upgrading from old QEMU we won't have found any + * caps in the domain status, so re-query them + */ + if (!priv->qemuCaps && + qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch, NULL, - &qemuCaps) >= 0 && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + &priv->qemuCaps) < 0) + goto error; + + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { priv->persistentAddrs = 1; if (!(priv->pciaddrs = qemuDomainPCIAddressSetCreate(obj->def)) || @@ -2012,11 +2013,9 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa if (virDomainObjUnref(obj) > 0) virDomainObjUnlock(obj); - qemuCapsFree(qemuCaps); return; error: - qemuCapsFree(qemuCaps); if (!virDomainObjIsActive(obj)) { if (virDomainObjUnref(obj) > 0) virDomainObjUnlock(obj); @@ -2058,7 +2057,6 @@ int qemuProcessStart(virConnectPtr conn, enum virVMOperationType vmop) { int ret; - virBitmapPtr qemuCaps = NULL; off_t pos = -1; char ebuf[1024]; char *pidfile = NULL; @@ -2204,9 +2202,11 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; VIR_DEBUG0("Determining emulator version"); + qemuCapsFree(priv->qemuCaps); + priv->qemuCaps = NULL; if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, NULL, - &qemuCaps) < 0) + &priv->qemuCaps) < 0) goto cleanup; VIR_DEBUG0("Setting up domain cgroup (if required)"); @@ -2223,7 +2223,7 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; #if HAVE_YAJL - if (qemuCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON)) priv->monJSON = 1; else #endif @@ -2252,7 +2252,7 @@ int qemuProcessStart(virConnectPtr conn, * we also need to populate the PCi address set cache for later * use in hotplug */ - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { VIR_DEBUG0("Assigning domain PCI addresses"); /* Populate cache with current addresses */ if (priv->pciaddrs) { @@ -2274,7 +2274,7 @@ int qemuProcessStart(virConnectPtr conn, VIR_DEBUG0("Building emulator command line"); if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig, - priv->monJSON != 0, qemuCaps, + priv->monJSON != 0, priv->qemuCaps, migrateFrom, stdin_fd, vm->current_snapshot, vmop))) goto cleanup; @@ -2385,12 +2385,12 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; VIR_DEBUG0("Setting any required VM passwords"); - if (qemuProcessInitPasswords(conn, driver, vm, qemuCaps) < 0) + if (qemuProcessInitPasswords(conn, driver, vm) < 0) goto cleanup; /* If we have -device, then addresses are assigned explicitly. * If not, then we have to detect dynamic ones here */ - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { VIR_DEBUG0("Determining domain device PCI addresses"); if (qemuProcessInitPCIAddresses(driver, vm) < 0) goto cleanup; @@ -2421,7 +2421,6 @@ int qemuProcessStart(virConnectPtr conn, if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) goto cleanup; - qemuCapsFree(qemuCaps); virCommandFree(cmd); VIR_FORCE_CLOSE(logfile); @@ -2431,7 +2430,6 @@ cleanup: /* We jump here if we failed to start the VM for any reason, or * if we failed to initialize the now running VM. kill it off and * pretend we never started it */ - qemuCapsFree(qemuCaps); virCommandFree(cmd); VIR_FORCE_CLOSE(logfile); qemuProcessStop(driver, vm, 0); @@ -2602,6 +2600,8 @@ retry: vm->state = VIR_DOMAIN_SHUTOFF; VIR_FREE(priv->vcpupids); priv->nvcpupids = 0; + qemuCapsFree(priv->qemuCaps); + priv->qemuCaps = NULL; /* The "release" hook cleans up additional resources */ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) { -- 1.7.4.4

On 05/04/2011 07:49 AM, Daniel P. Berrange wrote:
To cope with the QEMU binary being changed while a VM is running, it is neccessary to persist the original qemu capabilities at the time the VM is booted.
Yay! About time.
@@ -1986,13 +1984,16 @@ qemuProcessReconnect(void *payload, const void *name ATTRIBUTE_UNUSED, void *opa goto error; }
- /* XXX we should be persisting the original flags in the XML - * not re-detecting them, since the binary may have changed - * since launch time */ - if (qemuCapsExtractVersionInfo(obj->def->emulator, obj->def->os.arch, + /* If upgrading from old QEMU we won't have found any
s/QEMU/libvirt/ ACK with that nit fixed. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

* src/qemu/qemu_hotplug.h, src/qemu/qemu_hotplug.c: Remove qemuCaps parameters from all methods * src/qemu/qemu_driver.c: Don't create & pass qemuCaps to hotplug methods --- src/qemu/qemu_driver.c | 71 +++++++----------- src/qemu/qemu_hotplug.c | 185 +++++++++++++++++++++-------------------------- src/qemu/qemu_hotplug.h | 46 ++++-------- 3 files changed, 127 insertions(+), 175 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0919503..b214e44 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3791,8 +3791,7 @@ cleanup: static int qemuDomainAttachDeviceDiskLive(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk = dev->data.disk; virCgroupPtr cgroup = NULL; @@ -3818,16 +3817,16 @@ qemuDomainAttachDeviceDiskLive(struct qemud_driver *driver, switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_CDROM: case VIR_DOMAIN_DISK_DEVICE_FLOPPY: - ret = qemuDomainChangeEjectableMedia(driver, vm, disk, qemuCaps, false); + ret = qemuDomainChangeEjectableMedia(driver, vm, disk, false); break; case VIR_DOMAIN_DISK_DEVICE_DISK: if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) ret = qemuDomainAttachUsbMassstorageDevice(driver, vm, - disk, qemuCaps); + disk); else if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainAttachPciDiskDevice(driver, vm, disk, qemuCaps); + ret = qemuDomainAttachPciDiskDevice(driver, vm, disk); else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) - ret = qemuDomainAttachSCSIDisk(driver, vm, disk, qemuCaps); + ret = qemuDomainAttachSCSIDisk(driver, vm, disk); else qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("disk bus '%s' cannot be hotplugged."), @@ -3854,15 +3853,14 @@ end: static int qemuDomainAttachDeviceControllerLive(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainControllerDefPtr cont = dev->data.controller; int ret = -1; switch (cont->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: - ret = qemuDomainAttachPciControllerDevice(driver, vm, cont, qemuCaps); + ret = qemuDomainAttachPciControllerDevice(driver, vm, cont); break; default: qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -3876,35 +3874,34 @@ qemuDomainAttachDeviceControllerLive(struct qemud_driver *driver, static int qemuDomainAttachDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev, - virDomainPtr dom, - virBitmapPtr qemuCaps) + virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev, qemuCaps); + ret = qemuDomainAttachDeviceDiskLive(driver, vm, dev); if (!ret) dev->data.disk = NULL; break; case VIR_DOMAIN_DEVICE_CONTROLLER: - ret = qemuDomainAttachDeviceControllerLive(driver, vm, dev, qemuCaps); + ret = qemuDomainAttachDeviceControllerLive(driver, vm, dev); if (!ret) dev->data.controller = NULL; break; case VIR_DOMAIN_DEVICE_NET: ret = qemuDomainAttachNetDevice(dom->conn, driver, vm, - dev->data.net, qemuCaps); + dev->data.net); if (!ret) dev->data.net = NULL; break; case VIR_DOMAIN_DEVICE_HOSTDEV: ret = qemuDomainAttachHostDevice(driver, vm, - dev->data.hostdev, qemuCaps); + dev->data.hostdev); if (!ret) dev->data.hostdev = NULL; break; @@ -3922,8 +3919,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, static int qemuDomainDetachDeviceDiskLive(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk = dev->data.disk; int ret = -1; @@ -3931,11 +3927,11 @@ qemuDomainDetachDeviceDiskLive(struct qemud_driver *driver, switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_DISK: if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainDetachPciDiskDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachPciDiskDevice(driver, vm, dev); else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) - ret = qemuDomainDetachDiskDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachDiskDevice(driver, vm, dev); else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) - ret = qemuDomainDetachDiskDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachDiskDevice(driver, vm, dev); else qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This type of disk cannot be hot unplugged")); @@ -3952,15 +3948,14 @@ qemuDomainDetachDeviceDiskLive(struct qemud_driver *driver, static int qemuDomainDetachDeviceControllerLive(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainControllerDefPtr cont = dev->data.controller; int ret = -1; switch (cont->type) { case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: - ret = qemuDomainDetachPciControllerDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachPciControllerDevice(driver, vm, dev); break; default : qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -3973,24 +3968,23 @@ qemuDomainDetachDeviceControllerLive(struct qemud_driver *driver, static int qemuDomainDetachDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev, - virDomainPtr dom, - virBitmapPtr qemuCaps) + virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachDeviceDiskLive(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CONTROLLER: - ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_NET: - ret = qemuDomainDetachNetDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachNetDevice(driver, vm, dev); break; case VIR_DOMAIN_DEVICE_HOSTDEV: - ret = qemuDomainDetachHostDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachHostDevice(driver, vm, dev); break; default: qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -4005,7 +3999,6 @@ static int qemuDomainChangeDiskMediaLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev, struct qemud_driver *driver, - virBitmapPtr qemuCaps, bool force) { virDomainDiskDefPtr disk = dev->data.disk; @@ -4027,7 +4020,7 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm, switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_CDROM: case VIR_DOMAIN_DISK_DEVICE_FLOPPY: - ret = qemuDomainChangeEjectableMedia(driver, vm, disk, qemuCaps, force); + ret = qemuDomainChangeEjectableMedia(driver, vm, disk, force); if (ret == 0) dev->data.disk = NULL; break; @@ -4053,7 +4046,6 @@ static int qemuDomainUpdateDeviceLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev, virDomainPtr dom, - virBitmapPtr qemuCaps, bool force) { struct qemud_driver *driver = dom->conn->privateData; @@ -4061,7 +4053,7 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm, switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = qemuDomainChangeDiskMediaLive(vm, dev, driver, qemuCaps, force); + ret = qemuDomainChangeDiskMediaLive(vm, dev, driver, force); break; case VIR_DOMAIN_DEVICE_GRAPHICS: ret = qemuDomainChangeGraphics(driver, vm, dev->data.graphics); @@ -4199,7 +4191,6 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags, int action) { struct qemud_driver *driver = dom->conn->privateData; - virBitmapPtr qemuCaps = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr vmdef = NULL; virDomainDeviceDefPtr dev = NULL; @@ -4250,11 +4241,6 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, if (dev == NULL) goto endjob; - if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, - NULL, - &qemuCaps) < 0) - goto endjob; - if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { /* Make a copy for updated domain. */ vmdef = virDomainObjCopyPersistentDef(driver->caps, vm); @@ -4281,13 +4267,13 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, if (!ret && (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)) { switch (action) { case QEMU_DEVICE_ATTACH: - ret = qemuDomainAttachDeviceLive(vm, dev, dom, qemuCaps); + ret = qemuDomainAttachDeviceLive(vm, dev, dom); break; case QEMU_DEVICE_DETACH: - ret = qemuDomainDetachDeviceLive(vm, dev, dom, qemuCaps); + ret = qemuDomainDetachDeviceLive(vm, dev, dom); break; case QEMU_DEVICE_UPDATE: - ret = qemuDomainUpdateDeviceLive(vm, dev, dom, qemuCaps, force); + ret = qemuDomainUpdateDeviceLive(vm, dev, dom, force); break; default: qemuReportError(VIR_ERR_INTERNAL_ERROR, @@ -4316,7 +4302,6 @@ endjob: vm = NULL; cleanup: - qemuCapsFree(qemuCaps); virDomainDefFree(vmdef); virDomainDeviceDefFree(dev); if (vm) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 5fdb013..dae2269 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -44,14 +44,13 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps, bool force) { virDomainDiskDefPtr origdisk = NULL; int i; int ret; char *driveAlias = NULL; - qemuDomainObjPrivatePtr priv; + qemuDomainObjPrivatePtr priv = vm->privateData; for (i = 0 ; i < vm->def->ndisks ; i++) { if (vm->def->disks[i]->bus == disk->bus && @@ -87,10 +86,9 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver, vm, disk) < 0) return -1; - if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCaps))) + if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, priv->qemuCaps))) goto error; - priv = vm->privateData; qemuDomainObjEnterMonitorWithDriver(driver, vm); if (disk->src) { const char *format = NULL; @@ -139,8 +137,7 @@ error: int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps) + virDomainDiskDefPtr disk) { int i, ret; const char* type = virDomainDiskBusTypeToString(disk->bus); @@ -161,17 +158,17 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver, vm, disk) < 0) return -1; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &disk->info) < 0) goto error; releaseaddr = true; - if (qemuAssignDeviceDiskAlias(disk, qemuCaps) < 0) + if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) goto error; - if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(disk, 0, priv->qemuCaps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(disk, priv->qemuCaps))) goto error; } @@ -181,7 +178,7 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -221,7 +218,7 @@ error: VIR_FREE(devstr); VIR_FREE(drivestr); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0) @@ -237,8 +234,7 @@ error: int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainControllerDefPtr controller, - virBitmapPtr qemuCaps) + virDomainControllerDefPtr controller) { int i; int ret = -1; @@ -257,14 +253,14 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &controller->info) < 0) goto cleanup; releaseaddr = true; if (qemuAssignDeviceControllerAlias(controller) < 0) goto cleanup; - if (!(devstr = qemuBuildControllerDevStr(controller, qemuCaps))) { + if (!(devstr = qemuBuildControllerDevStr(controller, priv->qemuCaps))) { goto cleanup; } } @@ -275,7 +271,7 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDevice(priv->mon, devstr); } else { ret = qemuMonitorAttachPCIDiskController(priv->mon, @@ -291,7 +287,7 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, cleanup: if ((ret != 0) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &controller->info) < 0) @@ -305,11 +301,11 @@ cleanup: static virDomainControllerDefPtr qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver *driver, virDomainObjPtr vm, - int controller, - virBitmapPtr qemuCaps) + int controller) { int i; virDomainControllerDefPtr cont; + for (i = 0 ; i < vm->def->ncontrollers ; i++) { cont = vm->def->controllers[i]; @@ -332,7 +328,7 @@ qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver *driver, VIR_INFO0("No SCSI controller present, hotplugging one"); if (qemuDomainAttachPciControllerDevice(driver, - vm, cont, qemuCaps) < 0) { + vm, cont) < 0) { VIR_FREE(cont); return NULL; } @@ -351,8 +347,7 @@ qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver *driver, int qemuDomainAttachSCSIDisk(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps) + virDomainDiskDefPtr disk) { int i; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -382,18 +377,18 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver, goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(disk, qemuCaps) < 0) + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(disk, priv->qemuCaps))) goto error; } - if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(disk, 0, priv->qemuCaps))) goto error; for (i = 0 ; i <= disk->info.addr.drive.controller ; i++) { - cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i, qemuCaps); + cont = qemuDomainFindOrCreateSCSIDiskController(driver, vm, i); if (!cont) goto error; } @@ -415,7 +410,7 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -467,8 +462,7 @@ error: int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps) + virDomainDiskDefPtr disk) { qemuDomainObjPrivatePtr priv = vm->privateData; int i, ret; @@ -493,12 +487,12 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, goto error; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { - if (qemuAssignDeviceDiskAlias(disk, qemuCaps) < 0) + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuAssignDeviceDiskAlias(disk, priv->qemuCaps) < 0) goto error; - if (!(drivestr = qemuBuildDriveStr(disk, 0, qemuCaps))) + if (!(drivestr = qemuBuildDriveStr(disk, 0, priv->qemuCaps))) goto error; - if (!(devstr = qemuBuildDriveDevStr(disk, qemuCaps))) + if (!(devstr = qemuBuildDriveDevStr(disk, priv->qemuCaps))) goto error; } @@ -508,7 +502,7 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorAddDrive(priv->mon, drivestr); if (ret == 0) { ret = qemuMonitorAddDevice(priv->mon, devstr); @@ -552,8 +546,7 @@ error: int qemuDomainAttachNetDevice(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, - virDomainNetDefPtr net, - virBitmapPtr qemuCaps) + virDomainNetDefPtr net) { qemuDomainObjPrivatePtr priv = vm->privateData; char *tapfd_name = NULL; @@ -567,7 +560,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, int vlan; bool releaseaddr = false; - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_HOST_NET_ADD)) { + if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("installed qemu version does not support host_net_add")); return -1; @@ -576,36 +569,36 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE || net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net, - qemuCaps)) < 0) + priv->qemuCaps)) < 0) return -1; - if (qemuOpenVhostNet(vm->def, net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) goto cleanup; } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { if ((tapfd = qemuPhysIfaceConnect(vm->def, conn, driver, net, - qemuCaps, + priv->qemuCaps, VIR_VM_OP_CREATE)) < 0) return -1; - if (qemuOpenVhostNet(vm->def, net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) goto cleanup; } if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) goto no_memory; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NET_NAME) || - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) || + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0) goto cleanup; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &net->info) < 0) goto cleanup; releaseaddr = true; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { vlan = -1; } else { vlan = qemuDomainNetVLAN(net); @@ -627,8 +620,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto no_memory; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (!(netstr = qemuBuildHostNetStr(net, ',', -1, tapfd_name, vhostfd_name))) goto cleanup; @@ -639,8 +632,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorAddNetdev(priv->mon, netstr, tapfd, tapfd_name, vhostfd, vhostfd_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); @@ -666,8 +659,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, goto cleanup; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { - if (!(nicstr = qemuBuildNicDevStr(net, vlan, qemuCaps))) + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + if (!(nicstr = qemuBuildNicDevStr(net, vlan, priv->qemuCaps))) goto try_remove; } else { if (!(nicstr = qemuBuildNicStr(net, NULL, vlan))) @@ -675,7 +668,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditNet(vm, NULL, net, "attach", false); @@ -701,7 +694,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, cleanup: if ((ret != 0) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &net->info) < 0) @@ -724,8 +717,8 @@ try_remove: goto cleanup; if (vlan < 0) { - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { char *netdev_name; if (virAsprintf(&netdev_name, "host%s", net->info.alias) < 0) goto no_memory; @@ -759,8 +752,7 @@ no_memory: int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps) + virDomainHostdevDefPtr hostdev) { qemuDomainObjPrivatePtr priv = vm->privateData; int ret; @@ -777,13 +769,13 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, if (qemuPrepareHostdevPCIDevices(driver, &hostdev, 1) < 0) return -1; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) goto error; if (qemuDomainPCIAddressEnsureAddr(priv->pciaddrs, &hostdev->info) < 0) goto error; releaseaddr = true; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) { configfd = qemuOpenPCIConfig(hostdev); if (configfd >= 0) { if (virAsprintf(&configfd_name, "fd-%s", @@ -801,7 +793,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, } if (!(devstr = qemuBuildPCIHostdevDevStr(hostdev, configfd_name, - qemuCaps))) + priv->qemuCaps))) goto error; qemuDomainObjEnterMonitorWithDriver(driver, vm); @@ -833,7 +825,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, return 0; error: - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && (hostdev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && releaseaddr && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &hostdev->info) < 0) @@ -851,14 +843,13 @@ error: int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps) + virDomainHostdevDefPtr hostdev) { int ret; qemuDomainObjPrivatePtr priv = vm->privateData; char *devstr = NULL; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) goto error; if (!(devstr = qemuBuildUSBHostdevDevStr(hostdev))) @@ -893,7 +884,7 @@ int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) ret = qemuMonitorAddDevice(priv->mon, devstr); else ret = qemuMonitorAddUSBDeviceExact(priv->mon, @@ -918,8 +909,7 @@ error: int qemuDomainAttachHostDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps) + virDomainHostdevDefPtr hostdev) { if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -952,13 +942,13 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver, switch (hostdev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: if (qemuDomainAttachHostPciDevice(driver, vm, - hostdev, qemuCaps) < 0) + hostdev) < 0) goto error; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: if (qemuDomainAttachHostUsbDevice(driver, vm, - hostdev, qemuCaps) < 0) + hostdev) < 0) goto error; break; @@ -1113,8 +1103,7 @@ static inline int qemuFindDisk(virDomainDefPtr def, const char *dst) int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { int i, ret = -1; virDomainDiskDefPtr detach = NULL; @@ -1157,7 +1146,7 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { qemuDomainObjExitMonitor(vm); goto cleanup; @@ -1177,7 +1166,7 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, qemuAuditDisk(vm, detach, NULL, "detach", ret >= 0); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN("Unable to release PCI address on %s", dev->data.disk->src); @@ -1204,8 +1193,7 @@ cleanup: int qemuDomainDetachDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { int i, ret = -1; virDomainDiskDefPtr detach = NULL; @@ -1221,7 +1209,7 @@ int qemuDomainDetachDiskDevice(struct qemud_driver *driver, goto cleanup; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { qemuReportError(VIR_ERR_OPERATION_FAILED, _("Underlying qemu does not support %s disk removal"), virDomainDiskBusTypeToString(dev->data.disk->bus)); @@ -1334,8 +1322,7 @@ static bool qemuDomainControllerIsBusy(virDomainObjPtr vm, int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { int i, ret = -1; virDomainControllerDefPtr detach = NULL; @@ -1370,13 +1357,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, goto cleanup; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuAssignDeviceControllerAlias(detach) < 0) goto cleanup; } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) { qemuDomainObjExitMonitor(vm); goto cleanup; @@ -1404,7 +1391,7 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, vm->def->ncontrollers = 0; } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN0("Unable to release PCI address on controller"); @@ -1418,8 +1405,7 @@ cleanup: int qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { int i, ret = -1; virDomainNetDefPtr detach = NULL; @@ -1464,7 +1450,7 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { qemuDomainObjExitMonitor(vm); qemuAuditNet(vm, detach, NULL, "detach", false); @@ -1479,8 +1465,8 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, } } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && - qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) && + qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) { qemuDomainObjExitMonitorWithDriver(driver, vm); qemuAuditNet(vm, detach, NULL, "detach", false); @@ -1497,7 +1483,7 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, qemuAuditNet(vm, detach, NULL, "detach", true); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN0("Unable to release PCI address on NIC"); @@ -1545,8 +1531,7 @@ cleanup: int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainHostdevDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -1590,7 +1575,7 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, } qemuDomainObjEnterMonitorWithDriver(driver, vm); - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { ret = qemuMonitorDelDevice(priv->mon, detach->info.alias); } else { ret = qemuMonitorRemovePCIDevice(priv->mon, &detach->info.addr.pci); @@ -1615,7 +1600,7 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, pciFreeDevice(pci); } - if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) && qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &detach->info) < 0) VIR_WARN0("Unable to release PCI address on host device"); @@ -1639,8 +1624,7 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainHostdevDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; @@ -1686,7 +1670,7 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, return -1; } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { + if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("device cannot be detached with this QEMU version")); return -1; @@ -1719,8 +1703,7 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, int qemuDomainDetachHostDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps) + virDomainDeviceDefPtr dev) { virDomainHostdevDefPtr hostdev = dev->data.hostdev; int ret; @@ -1734,10 +1717,10 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver, switch (hostdev->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - ret = qemuDomainDetachHostPciDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachHostPciDevice(driver, vm, dev); break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - ret = qemuDomainDetachHostUsbDevice(driver, vm, dev, qemuCaps); + ret = qemuDomainDetachHostUsbDevice(driver, vm, dev); break; default: qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index db3970c..d18b393 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -30,41 +30,32 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver, virDomainObjPtr vm, virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps, bool force); int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps); + virDomainDiskDefPtr disk); int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainControllerDefPtr controller, - virBitmapPtr qemuCaps); + virDomainControllerDefPtr controller); int qemuDomainAttachSCSIDisk(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps); + virDomainDiskDefPtr disk); int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDiskDefPtr disk, - virBitmapPtr qemuCaps); + virDomainDiskDefPtr disk); int qemuDomainAttachNetDevice(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, - virDomainNetDefPtr net, - virBitmapPtr qemuCaps); + virDomainNetDefPtr net); int qemuDomainAttachHostPciDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps); + virDomainHostdevDefPtr hostdev); int qemuDomainAttachHostUsbDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps); + virDomainHostdevDefPtr hostdev); int qemuDomainAttachHostDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainHostdevDefPtr hostdev, - virBitmapPtr qemuCaps); + virDomainHostdevDefPtr hostdev); int qemuDomainChangeGraphics(struct qemud_driver *driver, virDomainObjPtr vm, virDomainGraphicsDefPtr dev); @@ -75,32 +66,25 @@ int qemuDomainChangeGraphicsPasswords(struct qemud_driver *driver, const char *defaultPasswd); int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachDiskDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachNetDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachHostPciDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); int qemuDomainDetachHostDevice(struct qemud_driver *driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev, - virBitmapPtr qemuCaps); + virDomainDeviceDefPtr dev); #endif /* __QEMU_HOTPLUG_H__ */ -- 1.7.4.4

On 05/04/2011 07:49 AM, Daniel P. Berrange wrote:
* src/qemu/qemu_hotplug.h, src/qemu/qemu_hotplug.c: Remove qemuCaps parameters from all methods * src/qemu/qemu_driver.c: Don't create & pass qemuCaps to hotplug methods --- src/qemu/qemu_driver.c | 71 +++++++----------- src/qemu/qemu_hotplug.c | 185 +++++++++++++++++++++-------------------------- src/qemu/qemu_hotplug.h | 46 ++++-------- 3 files changed, 127 insertions(+), 175 deletions(-)
Oh, I meant to say in my last email - this whole series is obviously post-0.9.1. ACK. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

* src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Remove qemuCaps parameters & use cached data * src/qemu/qemu_driver.c: Don't create & pass qemuCaps to migration methods --- src/qemu/qemu_driver.c | 11 ++--------- src/qemu/qemu_migration.c | 32 ++++++-------------------------- src/qemu/qemu_migration.h | 1 - 3 files changed, 8 insertions(+), 36 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b214e44..f033ea3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1878,7 +1878,6 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, struct stat sb; bool is_reg = false; unsigned long long offset; - virBitmapPtr qemuCaps = NULL; int fd = -1; memset(&header, 0, sizeof(header)); @@ -1910,11 +1909,6 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, } } - if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, - NULL, - &qemuCaps) < 0) - goto endjob; - /* Get XML for the domain */ xml = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE); if (!xml) { @@ -2040,7 +2034,7 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom, } /* Perform the migration */ - if (qemuMigrationToFile(driver, vm, qemuCaps, fd, offset, path, + if (qemuMigrationToFile(driver, vm, fd, offset, path, qemuCompressProgramName(compressed), is_reg, bypassSecurityDriver) < 0) goto endjob; @@ -2078,7 +2072,6 @@ endjob: } cleanup: - qemuCapsFree(qemuCaps); VIR_FORCE_CLOSE(fd); VIR_FREE(xml); if (ret != 0 && is_reg) @@ -2296,7 +2289,7 @@ static int doCoreDump(struct qemud_driver *driver, goto cleanup; } - if (qemuMigrationToFile(driver, vm, NULL, fd, 0, path, + if (qemuMigrationToFile(driver, vm, fd, 0, path, qemuCompressProgramName(compress), true, false) < 0) goto cleanup; diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 7f4b111..670c4a6 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -255,7 +255,6 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver, int ret = -1; int internalret; int dataFD[2] = { -1, -1 }; - virBitmapPtr qemuCaps = NULL; qemuDomainObjPrivatePtr priv = NULL; struct timeval now; @@ -307,14 +306,6 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver, goto endjob; } - /* check that this qemu version supports the interactive exec */ - if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, - NULL, &qemuCaps) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot determine QEMU argv syntax %s"), - vm->def->emulator); - goto endjob; - } /* Start the QEMU daemon, with the same command-line arguments plus * -incoming stdio (which qemu_command might convert to exec:cat or fd:n) */ @@ -371,7 +362,6 @@ endjob: } cleanup: - qemuCapsFree(qemuCaps); virDomainDefFree(def); VIR_FORCE_CLOSE(dataFD[0]); VIR_FORCE_CLOSE(dataFD[1]); @@ -703,7 +693,6 @@ static int doTunnelMigrate(struct qemud_driver *driver, virStreamPtr st = NULL; char *unixfile = NULL; int internalret; - virBitmapPtr qemuCaps = NULL; int status; unsigned long long transferred, remaining, total; unsigned int background_flags = QEMU_MONITOR_MIGRATE_BACKGROUND; @@ -764,16 +753,9 @@ static int doTunnelMigrate(struct qemud_driver *driver, } /* check that this qemu version supports the unix migration */ - if (qemuCapsExtractVersionInfo(vm->def->emulator, vm->def->os.arch, - NULL, &qemuCaps) < 0) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, - _("Cannot extract Qemu version from '%s'"), - vm->def->emulator); - goto cleanup; - } - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX) && - !qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { + if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX) && + !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Source qemu is too old to support tunnelled migration")); goto cleanup; @@ -815,11 +797,11 @@ static int doTunnelMigrate(struct qemud_driver *driver, background_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK; if (flags & VIR_MIGRATE_NON_SHARED_INC) background_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_INC; - if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_UNIX)) { internalret = qemuMonitorMigrateToUnix(priv->mon, background_flags, unixfile); } - else if (qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { + else if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_EXEC)) { const char *args[] = { "nc", "-U", unixfile, NULL }; internalret = qemuMonitorMigrateToCommand(priv->mon, QEMU_MONITOR_MIGRATE_BACKGROUND, args); } else { @@ -889,7 +871,6 @@ finish: cleanup: VIR_FORCE_CLOSE(client_sock); VIR_FORCE_CLOSE(qemu_sock); - qemuCapsFree(qemuCaps); if (ddomain) virUnrefDomain(ddomain); @@ -1289,7 +1270,6 @@ cleanup: /* Helper function called while driver lock is held and vm is active. */ int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, - virBitmapPtr qemuCaps, int fd, off_t offset, const char *path, const char *compressor, bool is_reg, bool bypassSecurityDriver) @@ -1302,7 +1282,7 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, virCommandPtr cmd = NULL; int pipeFD[2] = { -1, -1 }; - if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && (!compressor || pipe(pipeFD) == 0)) { /* All right! We can use fd migration, which means that qemu * doesn't have to open() the file, so while we still have to @@ -1349,7 +1329,7 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, if (!compressor) { const char *args[] = { "cat", NULL }; - if (qemuCaps && qemuCapsGet(qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && + if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATE_QEMU_FD) && priv->monConfig->type == VIR_DOMAIN_CHR_TYPE_UNIX) { rc = qemuMonitorMigrateToFd(priv->mon, QEMU_MONITOR_MIGRATE_BACKGROUND, diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h index db16ce4..f4e86c8 100644 --- a/src/qemu/qemu_migration.h +++ b/src/qemu/qemu_migration.h @@ -61,7 +61,6 @@ virDomainPtr qemuMigrationFinish(struct qemud_driver *driver, int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, - virBitmapPtr qemuCaps, int fd, off_t offset, const char *path, const char *compressor, bool is_reg, bool bypassSecurityDriver) -- 1.7.4.4

On 05/04/2011 07:49 AM, Daniel P. Berrange wrote:
* src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Remove qemuCaps parameters & use cached data * src/qemu/qemu_driver.c: Don't create & pass qemuCaps to migration methods --- src/qemu/qemu_driver.c | 11 ++--------- src/qemu/qemu_migration.c | 32 ++++++-------------------------- src/qemu/qemu_migration.h | 1 - 3 files changed, 8 insertions(+), 36 deletions(-)
@@ -2296,7 +2289,7 @@ static int doCoreDump(struct qemud_driver *driver, goto cleanup; }
- if (qemuMigrationToFile(driver, vm, NULL, fd, 0, path, + if (qemuMigrationToFile(driver, vm, fd, 0, path,
Sweet! This change lets core dump use fd: migration instead of always falling back to exec: migration. ACK. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 05/04/2011 07:49 AM, Daniel P. Berrange wrote:
* src/qemu/qemu_migration.c, src/qemu/qemu_migration.h: Remove qemuCaps parameters & use cached data * src/qemu/qemu_driver.c: Don't create & pass qemuCaps to migration methods --- +++ b/src/qemu/qemu_migration.h @@ -61,7 +61,6 @@ virDomainPtr qemuMigrationFinish(struct qemud_driver *driver,
int qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm, - virBitmapPtr qemuCaps, int fd, off_t offset, const char *path, const char *compressor, bool is_reg, bool bypassSecurityDriver)
Ouch - we changed the offset of parameters within the signature, but not the offset of the corresponding ATTRIBUTE_NONNULL that goes with them. Oh, you already saw this. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On Wed, May 04, 2011 at 02:49:48PM +0100, Daniel P. Berrange wrote:
Currently, whenever we require QEMU capabilities data, we rerun QEMU to extract the info. This isn't desirable because it is inefficient and the QEMU binary may have changed since we started the guest. This series makes us keep a copy of the capability data around for lifetime of the VM process
I've pushed this now, though it exposes a latent bug http://www.redhat.com/archives/libvir-list/2011-May/msg00189.html Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
Eric Blake