On 09/27/2016 08:24 AM, Martin Kletzander wrote: > This is needed in order to migrate a domain with shmem devices as that > is not allowed to migrate. Sure, but how would anyone know since the migration fails... Not sure where could/should describe it, but perhaps something nice to be described somewhere... > > Signed-off-by: Martin Kletzander <mkletzan@xxxxxxxxxx> > --- > src/qemu/qemu_driver.c | 39 +++- > src/qemu/qemu_hotplug.c | 247 ++++++++++++++++++++- > src/qemu/qemu_hotplug.h | 6 + > tests/qemuhotplugtest.c | 21 ++ > .../qemuhotplug-ivshmem-doorbell-detach.xml | 7 + > .../qemuhotplug-ivshmem-doorbell.xml | 4 + > .../qemuhotplug-ivshmem-plain-detach.xml | 6 + > .../qemuhotplug-ivshmem-plain.xml | 3 + > ...muhotplug-base-live+ivshmem-doorbell-detach.xml | 1 + > .../qemuhotplug-base-live+ivshmem-doorbell.xml | 65 ++++++ > .../qemuhotplug-base-live+ivshmem-plain-detach.xml | 1 + > .../qemuhotplug-base-live+ivshmem-plain.xml | 58 +++++ > 12 files changed, 453 insertions(+), 5 deletions(-) > create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell-detach.xml > create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell.xml > create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain-detach.xml > create mode 100644 tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain.xml > create mode 120000 tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell-detach.xml > create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell.xml > create mode 120000 tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain-detach.xml > create mode 100644 tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain.xml Jeez someday I should try to learn how to use these hotplug tests ;-) [...] > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index 72dd93bbe467..03d75be5e3d7 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -2242,6 +2242,131 @@ qemuDomainAttachHostDevice(virConnectPtr conn, > return -1; > } > > + > +int > +qemuDomainAttachShmemDevice(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainShmemDefPtr shmem) > +{ > + int ret = -1; > + char *shmstr = NULL; > + char *charAlias = NULL; > + char *memAlias = NULL; > + bool release_backing = false; > + bool release_address = true; > + virErrorPtr orig_err = NULL; > + virJSONValuePtr props = NULL; > + qemuDomainObjPrivatePtr priv = vm->privateData; > + > + switch ((virDomainShmemModel)shmem->model) { > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN: > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL: This is where I'd expect the capabilities checks to be > + break; > + > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM: > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > + _("live attach of shmem model '%s' is not supported"), > + virDomainShmemModelTypeToString(shmem->model)); > + /* fall-through */ > + case VIR_DOMAIN_SHMEM_MODEL_LAST: > + return -1; > + } > + > + if (qemuAssignDeviceShmemAlias(vm->def, shmem, -1) < 0) > + return -1; > + > + if (qemuDomainPrepareShmemChardev(shmem) < 0) > + return -1; > + > + if (VIR_REALLOC_N(vm->def->shmems, vm->def->nshmems + 1) < 0) > + return -1; > + > + if ((shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE || > + shmem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) && > + (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &shmem->info) < 0)) > + return -1; > + > + if (!(shmstr = qemuBuildShmemDevStr(vm->def, shmem, priv->qemuCaps))) > + goto cleanup; > + > + if (shmem->server.enabled) { > + if (virAsprintf(&charAlias, "char%s", shmem->info.alias) < 0) > + goto cleanup; > + } else { > + if (!(props = qemuBuildShmemBackendMemProps(shmem))) > + goto cleanup; > + > + if (virAsprintf(&memAlias, "shmmem-%s", shmem->info.alias) < 0) > + goto cleanup; > + } > + > + qemuDomainObjEnterMonitor(driver, vm); > + > + if (shmem->server.enabled) { > + if (qemuMonitorAttachCharDev(priv->mon, charAlias, > + &shmem->server.chr) < 0) > + goto exit_monitor; > + } else { > + if (qemuMonitorAddObject(priv->mon, "memory-backend-file", > + memAlias, props) < 0) { Some day we should change the AddObject to be &props <sigh> > + props = NULL; > + goto exit_monitor; > + } > + props = NULL; > + } > + > + release_backing = true; > + > + if (qemuMonitorAddDevice(priv->mon, shmstr) < 0) > + goto exit_monitor; > + > + if (qemuDomainObjExitMonitor(driver, vm) < 0) { > + release_address = false; > + goto cleanup; > + } > + > + /* Doing a copy here just so the pointer doesn't get nullified > + * because we need it in the audit function */ > + VIR_APPEND_ELEMENT_COPY_INPLACE(vm->def->shmems, vm->def->nshmems, shmem); > + > + ret = 0; > + release_address = false; > + > + audit: > + virDomainAuditShmem(vm, shmem, "attach", ret == 0); > + > + cleanup: > + if (release_address) > + qemuDomainReleaseDeviceAddress(vm, &shmem->info, NULL); > + > + virJSONValueFree(props); > + VIR_FREE(memAlias); > + VIR_FREE(charAlias); > + VIR_FREE(shmstr); > + > + return ret; > + > + exit_monitor: > + orig_err = virSaveLastError(); > + if (release_backing) { > + if (shmem->server.enabled) > + ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); > + else > + ignore_value(qemuMonitorDelObject(priv->mon, memAlias)); > + } > + > + if (orig_err) { > + virSetError(orig_err); > + virFreeError(orig_err); > + } > + > + if (qemuDomainObjExitMonitor(driver, vm) < 0) > + release_address = false; > + > + goto audit; > +} > + > + > static int > qemuDomainChangeNetBridge(virDomainObjPtr vm, > virDomainNetDefPtr olddev, > @@ -3486,6 +3611,61 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, > } > > > +static int > +qemuDomainRemoveShmemDevice(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainShmemDefPtr shmem) > +{ > + int rc; > + int ret = -1; > + ssize_t idx = -1; > + char *charAlias = NULL; > + char *memAlias = NULL; > + qemuDomainObjPrivatePtr priv = vm->privateData; > + virObjectEventPtr event = NULL; > + > + VIR_DEBUG("Removing shmem device %s from domain %p %s", > + shmem->info.alias, vm, vm->def->name); > + > + if (shmem->server.enabled) { > + if (virAsprintf(&charAlias, "char%s", shmem->info.alias) < 0) > + return -1; > + } else { > + if (virAsprintf(&memAlias, "shmmem-%s", shmem->info.alias) < 0) > + return -1; > + } > + > + qemuDomainObjEnterMonitor(driver, vm); > + > + if (shmem->server.enabled) > + rc = qemuMonitorDetachCharDev(priv->mon, charAlias); > + else > + rc = qemuMonitorDelObject(priv->mon, memAlias); > + > + if (qemuDomainObjExitMonitor(driver, vm) < 0) > + goto cleanup; > + > + virDomainAuditShmem(vm, shmem, "detach", rc == 0); > + > + if (rc < 0) > + goto cleanup; > + > + event = virDomainEventDeviceRemovedNewFromObj(vm, shmem->info.alias); > + qemuDomainEventQueue(driver, event); > + > + if ((idx = virDomainShmemDefFind(vm->def, shmem)) >= 0) > + virDomainShmemDefRemove(vm->def, idx); > + qemuDomainReleaseDeviceAddress(vm, &shmem->info, NULL); I think there be a virDomainShmemDefFree(shmem) here, right? The virDomainShmemDefRemove only removes shmem from the list > + > + ret = 0; > + cleanup: > + VIR_FREE(charAlias); > + VIR_FREE(memAlias); > + > + return ret; > +} > + > + > int > qemuDomainRemoveDevice(virQEMUDriverPtr driver, > virDomainObjPtr vm, > @@ -3517,6 +3697,10 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, > ret = qemuDomainRemoveMemoryDevice(driver, vm, dev->data.memory); > break; > > + case VIR_DOMAIN_DEVICE_SHMEM: > + ret = qemuDomainRemoveShmemDevice(driver, vm, dev->data.shmem); > + break; > + > case VIR_DOMAIN_DEVICE_NONE: > case VIR_DOMAIN_DEVICE_LEASE: > case VIR_DOMAIN_DEVICE_FS: > @@ -3530,7 +3714,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, > case VIR_DOMAIN_DEVICE_SMARTCARD: > case VIR_DOMAIN_DEVICE_MEMBALLOON: > case VIR_DOMAIN_DEVICE_NVRAM: > - case VIR_DOMAIN_DEVICE_SHMEM: > case VIR_DOMAIN_DEVICE_TPM: > case VIR_DOMAIN_DEVICE_PANIC: > case VIR_DOMAIN_DEVICE_IOMMU: > @@ -4105,6 +4288,68 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, > return qemuDomainDetachThisHostDevice(driver, vm, detach); > } > > + > +int > +qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainDeviceDefPtr dev) > +{ > + int ret = -1; > + ssize_t idx = -1; > + virErrorPtr orig_err = NULL; > + virDomainShmemDefPtr shmem = NULL; > + qemuDomainObjPrivatePtr priv = vm->privateData; > + > + if ((idx = virDomainShmemDefFind(vm->def, dev->data.shmem) < 0)) { > + virReportError(VIR_ERR_OPERATION_INVALID, "%s", > + _("device not present in domain configuration")); > + return -1; > + } > + > + shmem = vm->def->shmems[idx]; > + > + switch ((virDomainShmemModel)shmem->model) { > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN: > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_DOORBELL: > + break; > + > + case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM: > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > + _("live detach of shmem model '%s' is not supported"), > + virDomainShmemModelTypeToString(shmem->model)); > + /* fall-through */ > + case VIR_DOMAIN_SHMEM_MODEL_LAST: > + return -1; > + } > + > + qemuDomainMarkDeviceForRemoval(vm, &shmem->info); > + qemuDomainObjEnterMonitor(driver, vm); > + > + ret = qemuMonitorDelDevice(priv->mon, shmem->info.alias); > + > + if (ret < 0) > + orig_err = virSaveLastError(); > + > + if (qemuDomainObjExitMonitor(driver, vm) < 0) > + ret = -1; > + > + if (ret == 0) { > + if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) { > + qemuDomainReleaseDeviceAddress(vm, &shmem->info, NULL); > + ret = qemuDomainRemoveDevice(driver, vm, dev); Why not a direct qemuDomainRemoveShmemDevice(driver, vm, shmem); It's the pattern other code uses - just concern over the difference - it does result in the same call eventually. ACK with the capabilities checks and of course being sure we've free'd shmem. John > + } > + } > + qemuDomainResetDeviceRemoval(vm); > + > + if (orig_err) { > + virSetError(orig_err); > + virFreeError(orig_err); > + } > + > + return ret; > +} > + > + > int > qemuDomainDetachNetDevice(virQEMUDriverPtr driver, > virDomainObjPtr vm, > diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h > index b048cf4688a4..12994e7cd468 100644 > --- a/src/qemu/qemu_hotplug.h > +++ b/src/qemu/qemu_hotplug.h > @@ -50,6 +50,9 @@ int qemuDomainAttachHostDevice(virConnectPtr conn, > virQEMUDriverPtr driver, > virDomainObjPtr vm, > virDomainHostdevDefPtr hostdev); > +int qemuDomainAttachShmemDevice(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainShmemDefPtr shmem); > int qemuDomainFindGraphicsIndex(virDomainDefPtr def, > virDomainGraphicsDefPtr dev); > int qemuDomainAttachMemory(virQEMUDriverPtr driver, > @@ -86,6 +89,9 @@ int qemuDomainDetachNetDevice(virQEMUDriverPtr driver, > int qemuDomainDetachHostDevice(virQEMUDriverPtr driver, > virDomainObjPtr vm, > virDomainDeviceDefPtr dev); > +int qemuDomainDetachShmemDevice(virQEMUDriverPtr driver, > + virDomainObjPtr vm, > + virDomainDeviceDefPtr dev); > int qemuDomainAttachLease(virQEMUDriverPtr driver, > virDomainObjPtr vm, > virDomainLeaseDefPtr lease); > diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c > index 43eb1cfd1fc3..d1357ebd7c57 100644 > --- a/tests/qemuhotplugtest.c > +++ b/tests/qemuhotplugtest.c > @@ -74,6 +74,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, > virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VIRTIO_SCSI); > virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE); > virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW); > + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM_PLAIN); > + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_IVSHMEM_DOORBELL); > if (event) > virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT); > > @@ -120,6 +122,9 @@ testQemuHotplugAttach(virDomainObjPtr vm, > case VIR_DOMAIN_DEVICE_CHR: > ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr); > break; > + case VIR_DOMAIN_DEVICE_SHMEM: > + ret = qemuDomainAttachShmemDevice(&driver, vm, dev->data.shmem); > + break; > default: > VIR_TEST_VERBOSE("device type '%s' cannot be attached\n", > virDomainDeviceTypeToString(dev->type)); > @@ -142,6 +147,9 @@ testQemuHotplugDetach(virDomainObjPtr vm, > case VIR_DOMAIN_DEVICE_CHR: > ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr); > break; > + case VIR_DOMAIN_DEVICE_SHMEM: > + ret = qemuDomainDetachShmemDevice(&driver, vm, dev); > + break; > default: > VIR_TEST_VERBOSE("device type '%s' cannot be detached\n", > virDomainDeviceTypeToString(dev->type)); > @@ -561,6 +569,19 @@ mymain(void) > "human-monitor-command", HMP("OK\\r\\n"), > "device_add", QMP_OK); > > + DO_TEST_ATTACH("base-live", "ivshmem-plain", false, true, > + "object-add", QMP_OK, > + "device_add", QMP_OK); > + DO_TEST_ATTACH("base-live", "ivshmem-doorbell", false, true, > + "chardev-add", QMP_OK, > + "device_add", QMP_OK); > + DO_TEST_DETACH("base-live+ivshmem-plain", "ivshmem-doorbell-detach", false, true, > + "device_del", QMP_OK, > + "chardev-remove", QMP_OK); > + DO_TEST_DETACH("base-live", "ivshmem-plain-detach", false, false, > + "device_del", QMP_OK, > + "object-del", QMP_OK); > + > qemuTestDriverFree(&driver); > return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE; > } > diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell-detach.xml > new file mode 100644 > index 000000000000..7c066964d745 > --- /dev/null > +++ b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell-detach.xml > @@ -0,0 +1,7 @@ > +<shmem name='shmem1'> > + <model type='ivshmem-doorbell'/> > + <server path='/var/lib/libvirt/shmem-shmem1-sock'/> > + <msi ioeventfd='on'/> > + <alias name='shmem1'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> > +</shmem> > diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell.xml b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell.xml > new file mode 100644 > index 000000000000..06cb0c978605 > --- /dev/null > +++ b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-doorbell.xml > @@ -0,0 +1,4 @@ > +<shmem name='shmem1'> > + <model type='ivshmem-doorbell'/> > + <server/> > +</shmem> > diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain-detach.xml b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain-detach.xml > new file mode 100644 > index 000000000000..68f592fb2128 > --- /dev/null > +++ b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain-detach.xml > @@ -0,0 +1,6 @@ > +<shmem name='shmem0'> > + <model type='ivshmem-plain'/> > + <size unit='M'>4</size> > + <alias name='shmem0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> > +</shmem> > diff --git a/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain.xml b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain.xml > new file mode 100644 > index 000000000000..6bd96ff16767 > --- /dev/null > +++ b/tests/qemuhotplugtestdevices/qemuhotplug-ivshmem-plain.xml > @@ -0,0 +1,3 @@ > +<shmem name='shmem0'> > + <model type='ivshmem-plain'/> > +</shmem> > diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell-detach.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell-detach.xml > new file mode 120000 > index 000000000000..021e5471d197 > --- /dev/null > +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell-detach.xml > @@ -0,0 +1 @@ > +qemuhotplug-base-live+ivshmem-plain.xml > \ No newline at end of file > diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell.xml > new file mode 100644 > index 000000000000..8d09fee265fc > --- /dev/null > +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-doorbell.xml > @@ -0,0 +1,65 @@ > +<domain type='kvm' id='7'> > + <name>hotplug</name> > + <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid> > + <memory unit='KiB'>4194304</memory> > + <currentMemory unit='KiB'>4194304</currentMemory> > + <vcpu placement='static'>4</vcpu> > + <os> > + <type arch='x86_64' machine='pc'>hvm</type> > + <boot dev='hd'/> > + </os> > + <features> > + <acpi/> > + <apic/> > + <pae/> > + </features> > + <clock offset='utc'/> > + <on_poweroff>destroy</on_poweroff> > + <on_reboot>restart</on_reboot> > + <on_crash>restart</on_crash> > + <devices> > + <emulator>/usr/libexec/qemu-kvm</emulator> > + <controller type='usb' index='0'> > + <alias name='usb'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> > + </controller> > + <controller type='ide' index='0'> > + <alias name='ide'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> > + </controller> > + <controller type='scsi' index='0' model='virtio-scsi'> > + <alias name='scsi0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> > + </controller> > + <controller type='pci' index='0' model='pci-root'> > + <alias name='pci'/> > + </controller> > + <controller type='virtio-serial' index='0'> > + <alias name='virtio-serial0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> > + </controller> > + <input type='mouse' bus='ps2'> > + <alias name='input0'/> > + </input> > + <input type='keyboard' bus='ps2'> > + <alias name='input1'/> > + </input> > + <memballoon model='none'> > + <alias name='balloon0'/> > + </memballoon> > + <shmem name='shmem0'> > + <model type='ivshmem-plain'/> > + <size unit='M'>4</size> > + <alias name='shmem0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> > + </shmem> > + <shmem name='shmem1'> > + <model type='ivshmem-doorbell'/> > + <server path='/var/lib/libvirt/shmem-shmem1-sock'/> > + <msi ioeventfd='on'/> > + <alias name='shmem1'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> > + </shmem> > + </devices> > + <seclabel type='none' model='none'/> > +</domain> > diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain-detach.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain-detach.xml > new file mode 120000 > index 000000000000..48c1b1755a4e > --- /dev/null > +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain-detach.xml > @@ -0,0 +1 @@ > +qemuhotplug-base-live.xml > \ No newline at end of file > diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain.xml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain.xml > new file mode 100644 > index 000000000000..ac3fa4f42047 > --- /dev/null > +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+ivshmem-plain.xml > @@ -0,0 +1,58 @@ > +<domain type='kvm' id='7'> > + <name>hotplug</name> > + <uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid> > + <memory unit='KiB'>4194304</memory> > + <currentMemory unit='KiB'>4194304</currentMemory> > + <vcpu placement='static'>4</vcpu> > + <os> > + <type arch='x86_64' machine='pc'>hvm</type> > + <boot dev='hd'/> > + </os> > + <features> > + <acpi/> > + <apic/> > + <pae/> > + </features> > + <clock offset='utc'/> > + <on_poweroff>destroy</on_poweroff> > + <on_reboot>restart</on_reboot> > + <on_crash>restart</on_crash> > + <devices> > + <emulator>/usr/libexec/qemu-kvm</emulator> > + <controller type='usb' index='0'> > + <alias name='usb'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> > + </controller> > + <controller type='ide' index='0'> > + <alias name='ide'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> > + </controller> > + <controller type='scsi' index='0' model='virtio-scsi'> > + <alias name='scsi0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> > + </controller> > + <controller type='pci' index='0' model='pci-root'> > + <alias name='pci'/> > + </controller> > + <controller type='virtio-serial' index='0'> > + <alias name='virtio-serial0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> > + </controller> > + <input type='mouse' bus='ps2'> > + <alias name='input0'/> > + </input> > + <input type='keyboard' bus='ps2'> > + <alias name='input1'/> > + </input> > + <memballoon model='none'> > + <alias name='balloon0'/> > + </memballoon> > + <shmem name='shmem0'> > + <model type='ivshmem-plain'/> > + <size unit='M'>4</size> > + <alias name='shmem0'/> > + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> > + </shmem> > + </devices> > + <seclabel type='none' model='none'/> > +</domain> > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list