[libvirt] [PATCHv2.5 10/10] qemu: Implement memory device hotunplug

John Ferlan jferlan at redhat.com
Sat Mar 14 00:48:45 UTC 2015



On 03/04/2015 11:25 AM, Peter Krempa wrote:
> Add code to hot-remove memory devices from qemu. Unfortunately QEMU
> doesn't support this right now, so this is just for completenes.
> ---
>  src/qemu/qemu_driver.c  |  4 ++-
>  src/qemu/qemu_hotplug.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-
>  src/qemu/qemu_hotplug.h |  3 ++
>  3 files changed, 96 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index b917d76..cd9c0f2 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -7179,7 +7179,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
>          ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng);
>          break;
>      case VIR_DOMAIN_DEVICE_MEMORY:
> -        /* TODO: Implement later */
> +        ret = qemuDomainDetachMemoryDevice(driver, vm, dev->data.memory);
> +        break;
> +
>      case VIR_DOMAIN_DEVICE_FS:
>      case VIR_DOMAIN_DEVICE_INPUT:
>      case VIR_DOMAIN_DEVICE_SOUND:
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 967b678..359fb8e 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -2818,6 +2818,44 @@ qemuDomainRemoveControllerDevice(virQEMUDriverPtr driver,
>  }
> 
> 
> +static int
> +qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
> +                             virDomainObjPtr vm,
> +                             virDomainMemoryDefPtr mem)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virObjectEventPtr event;
> +    char *backendAlias = NULL;
> +    int rc;
> +    int idx;
> +
> +    VIR_DEBUG("Removing memory device %s from domain %p %s",
> +              mem->info.alias, vm, vm->def->name);
> +
> +    if ((event = virDomainEventDeviceRemovedNewFromObj(vm, mem->info.alias)))
> +        qemuDomainEventQueue(driver, event);
> +
> +    if (virAsprintf(&backendAlias, "mem%s", mem->info.alias) < 0)
> +        goto error;
> +
> +    qemuDomainObjEnterMonitor(driver, vm);
> +    rc = qemuMonitorDelObject(priv->mon, backendAlias);
> +    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
> +        goto error;
> +
> +    if ((idx = virDomainMemoryFindByDef(vm->def, mem)) >= 0)
> +        virDomainMemoryRemove(vm->def, idx);
> +
> +    virDomainMemoryDefFree(mem);
> +    VIR_FREE(backendAlias);
> +    return 0;
> +
> + error:
> +    VIR_FREE(backendAlias);
> +    return -1;
> +}
> +
> +
>  static void
>  qemuDomainRemovePCIHostDevice(virQEMUDriverPtr driver,
>                                virDomainObjPtr vm,
> @@ -3155,8 +3193,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
>          qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng);
>          break;
> 
> -    /* TODO: implement later */
>      case VIR_DOMAIN_DEVICE_MEMORY:
> +        ret = qemuDomainRemoveMemoryDevice(driver, vm, dev->data.memory);
> +        break;
> 
>      case VIR_DOMAIN_DEVICE_NONE:
>      case VIR_DOMAIN_DEVICE_LEASE:
> @@ -4108,3 +4147,53 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
>      qemuDomainResetDeviceRemoval(vm);
>      return ret;
>  }
> +
> +
> +int
> +qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
> +                             virDomainObjPtr vm,
> +                             virDomainMemoryDefPtr memdef)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virDomainMemoryDefPtr mem;
> +    int idx;
> +    int rc;
> +    int ret = -1;
> +
> +    if ((idx = virDomainMemoryFindByDef(vm->def, memdef)) < 0) {
> +        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                       _("device not present in domain configuration"));
> +        return -1;
> +    }
> +
> +    mem = vm->def->mems[idx];
> +
> +    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
> +        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                       _("qemu does not support -device"));
> +        return -1;
> +    }

This check could be first to save a cycle of searching FindByDef

Not that it matters because if we get this far, one would hope -device
was present!

ACK -

John
.

> +
> +    if (!mem->info.alias) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("alias for the memory device was not found"));
> +        return -1;
> +    }
> +
> +    qemuDomainMarkDeviceForRemoval(vm, &mem->info);
> +
> +    qemuDomainObjEnterMonitor(driver, vm);
> +    rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
> +    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
> +        goto cleanup;
> +
> +    rc = qemuDomainWaitForDeviceRemoval(vm);
> +    if (rc == 0 || rc == 1)
> +        ret = qemuDomainRemoveMemoryDevice(driver, vm, mem);
> +    else
> +        ret = 0;
> +
> + cleanup:
> +    qemuDomainResetDeviceRemoval(vm);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
> index ad4ff38..4140da3 100644
> --- a/src/qemu/qemu_hotplug.h
> +++ b/src/qemu/qemu_hotplug.h
> @@ -60,6 +60,9 @@ int qemuDomainFindGraphicsIndex(virDomainDefPtr def,
>  int qemuDomainAttachMemory(virQEMUDriverPtr driver,
>                             virDomainObjPtr vm,
>                             virDomainMemoryDefPtr mem);
> +int qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
> +                                 virDomainObjPtr vm,
> +                                 virDomainMemoryDefPtr memdef);
>  int qemuDomainChangeGraphics(virQEMUDriverPtr driver,
>                               virDomainObjPtr vm,
>                               virDomainGraphicsDefPtr dev);
> 




More information about the libvir-list mailing list