[libvirt] [PATCH 8/8] qemu: Add support for hot/cold-(un)plug of shmem devices

John Ferlan jferlan at redhat.com
Fri Oct 7 17:05:29 UTC 2016



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 at redhat.com>
> ---
>  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>
> 




More information about the libvir-list mailing list