[libvirt] [PATCH v2] qemu: Allow to attach/detach controller device persistently
Osier Yang
jyang at redhat.com
Mon Jul 30 12:52:50 UTC 2012
ping again.
On 2012年07月23日 16:18, Osier Yang wrote:
> * src/conf/domain_conf.c:
> - Add virDomainControllerFind to find controller device by type
> and index.
> - Add virDomainControllerRemove to remove the controller device
> from maintained controler list.
>
> * src/conf/domain_conf.h:
> - Declare the two new helpers.
>
> * src/libvirt_private.syms:
> - Expose private symbols for the two new helpers.
>
> * src/qemu/qemu_driver.c:
> - Support attach/detach controller device persistently
>
> * src/qemu/qemu_hotplug.c:
> - Use the two helpers to simplify the codes.
>
> v1 - v2:
> - Allow to detach the controller too.
>
> ---
> src/conf/domain_conf.c | 37 ++++++++++++++++++++++++++++++++++++
> src/conf/domain_conf.h | 3 +-
> src/libvirt_private.syms | 2 +
> src/qemu/qemu_driver.c | 35 ++++++++++++++++++++++++++++++++-
> src/qemu/qemu_hotplug.c | 47 ++++++++++++---------------------------------
> 5 files changed, 87 insertions(+), 37 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 41726ff..a7ae604 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -7554,6 +7554,43 @@ void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
> def->ncontrollers++;
> }
>
> +int
> +virDomainControllerFind(virDomainDefPtr def,
> + int type, int idx)
> +{
> + int i;
> +
> + for (i = 0 ; i< def->ncontrollers ; i++) {
> + if ((def->controllers[i]->type == type)&&
> + (def->controllers[i]->idx == idx)) {
> + return i;
> + }
> + }
> +
> + return -1;
> +}
> +
> +virDomainControllerDefPtr
> +virDomainControllerRemove(virDomainDefPtr def, size_t i)
> +{
> + virDomainControllerDefPtr controller = def->controllers[i];
> +
> + if (def->ncontrollers> 1) {
> + memmove(def->controllers + i,
> + def->controllers + i + 1,
> + sizeof(*def->controllers) *
> + (def->ncontrollers - (i + 1)));
> + def->ncontrollers--;
> + if (VIR_REALLOC_N(def->controllers, def->ncontrollers)< 0) {
> + /* ignore, harmless */
> + }
> + } else {
> + VIR_FREE(def->controllers);
> + def->ncontrollers = 0;
> + }
> +
> + return controller;
> +}
>
> int virDomainLeaseIndex(virDomainDefPtr def,
> virDomainLeaseDefPtr lease)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 469d3b6..b102a43 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2043,7 +2043,8 @@ int virDomainControllerInsert(virDomainDefPtr def,
> virDomainControllerDefPtr controller);
> void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
> virDomainControllerDefPtr controller);
> -
> +int virDomainControllerFind(virDomainDefPtr def, int type, int idx);
> +virDomainControllerDefPtr virDomainControllerRemove(virDomainDefPtr def, size_t i);
>
> int virDomainLeaseIndex(virDomainDefPtr def,
> virDomainLeaseDefPtr lease);
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 734c881..9f14077 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -266,12 +266,14 @@ virDomainClockOffsetTypeFromString;
> virDomainClockOffsetTypeToString;
> virDomainConfigFile;
> virDomainControllerDefFree;
> +virDomainControllerFind;
> virDomainControllerInsert;
> virDomainControllerInsertPreAlloced;
> virDomainControllerModelSCSITypeFromString;
> virDomainControllerModelSCSITypeToString;
> virDomainControllerModelUSBTypeFromString;
> virDomainControllerModelUSBTypeToString;
> +virDomainControllerRemove;
> virDomainControllerTypeToString;
> virDomainCpuPlacementModeTypeFromString;
> virDomainCpuPlacementModeTypeToString;
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 6cf3882..2d9c3a9 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -5535,6 +5535,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
> virDomainNetDefPtr net;
> virDomainHostdevDefPtr hostdev;
> virDomainLeaseDefPtr lease;
> + virDomainControllerDefPtr controller;
>
> switch (dev->type) {
> case VIR_DOMAIN_DEVICE_DISK:
> @@ -5607,6 +5608,23 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
> dev->data.lease = NULL;
> break;
>
> + case VIR_DOMAIN_DEVICE_CONTROLLER:
> + controller = dev->data.controller;
> + if (virDomainControllerFind(vmdef, controller->type,
> + controller->idx)> 0) {
> + virReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("Target already exists"));
> + return -1;
> + }
> +
> + if (virDomainControllerInsert(vmdef, controller)< 0)
> + return -1;
> + dev->data.controller = NULL;
> +
> + if (qemuDomainAssignAddresses(vmdef, NULL, NULL)< 0)
> + return -1;
> + break;
> +
> default:
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> _("persistent attach of device is not supported"));
> @@ -5624,6 +5642,8 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
> virDomainNetDefPtr net, det_net;
> virDomainHostdevDefPtr hostdev, det_hostdev;
> virDomainLeaseDefPtr lease, det_lease;
> + virDomainControllerDefPtr cont, det_cont;
> + int idx;
>
> switch (dev->type) {
> case VIR_DOMAIN_DEVICE_DISK:
> @@ -5650,8 +5670,6 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
> break;
>
> case VIR_DOMAIN_DEVICE_HOSTDEV: {
> - int idx;
> -
> hostdev = dev->data.hostdev;
> if ((idx = virDomainHostdevFind(vmdef, hostdev,&det_hostdev))< 0) {
> virReportError(VIR_ERR_INVALID_ARG, "%s",
> @@ -5674,6 +5692,19 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
> virDomainLeaseDefFree(det_lease);
> break;
>
> + case VIR_DOMAIN_DEVICE_CONTROLLER:
> + cont = dev->data.controller;
> + if ((idx = virDomainControllerFind(vmdef, cont->type,
> + cont->idx))< 0) {
> + virReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("device not present in domain configuration"));
> + return -1;
> + }
> + det_cont = virDomainControllerRemove(vmdef, idx);
> + virDomainControllerDefFree(det_cont);
> +
> + break;
> +
> default:
> virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> _("persistent detach of device is not supported"));
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 7880606..c3ac938 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -308,21 +308,17 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver,
> virDomainObjPtr vm,
> virDomainControllerDefPtr controller)
> {
> - int i;
> int ret = -1;
> const char* type = virDomainControllerTypeToString(controller->type);
> char *devstr = NULL;
> qemuDomainObjPrivatePtr priv = vm->privateData;
> bool releaseaddr = false;
>
> - for (i = 0 ; i< vm->def->ncontrollers ; i++) {
> - if ((vm->def->controllers[i]->type == controller->type)&&
> - (vm->def->controllers[i]->idx == controller->idx)) {
> - virReportError(VIR_ERR_OPERATION_FAILED,
> - _("target %s:%d already exists"),
> - type, controller->idx);
> - return -1;
> - }
> + if (virDomainControllerFind(vm->def, controller->type, controller->idx)> 0) {
> + virReportError(VIR_ERR_OPERATION_FAILED,
> + _("target %s:%d already exists"),
> + type, controller->idx);
> + return -1;
> }
>
> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
> @@ -1874,19 +1870,13 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
> virDomainObjPtr vm,
> virDomainDeviceDefPtr dev)
> {
> - int i, ret = -1;
> + int idx, ret = -1;
> virDomainControllerDefPtr detach = NULL;
> qemuDomainObjPrivatePtr priv = vm->privateData;
>
> - for (i = 0 ; i< vm->def->ncontrollers ; i++) {
> - if ((vm->def->controllers[i]->type == dev->data.controller->type)&&
> - (vm->def->controllers[i]->idx == dev->data.controller->idx)) {
> - detach = vm->def->controllers[i];
> - break;
> - }
> - }
> -
> - if (!detach) {
> + if ((idx = virDomainControllerFind(vm->def,
> + dev->data.controller->type,
> + dev->data.controller->idx))< 0) {
> virReportError(VIR_ERR_OPERATION_FAILED,
> _("disk controller %s:%d not found"),
> virDomainControllerTypeToString(dev->data.controller->type),
> @@ -1894,6 +1884,8 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
> goto cleanup;
> }
>
> + detach = vm->def->controllers[idx];
> +
> if (!virDomainDeviceAddressIsValid(&detach->info,
> VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) {
> virReportError(VIR_ERR_OPERATION_FAILED, "%s",
> @@ -1934,27 +1926,14 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
> }
> qemuDomainObjExitMonitorWithDriver(driver, vm);
>
> - if (vm->def->ncontrollers> 1) {
> - memmove(vm->def->controllers + i,
> - vm->def->controllers + i + 1,
> - sizeof(*vm->def->controllers) *
> - (vm->def->ncontrollers - (i + 1)));
> - vm->def->ncontrollers--;
> - if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers)< 0) {
> - /* ignore, harmless */
> - }
> - } else {
> - VIR_FREE(vm->def->controllers);
> - vm->def->ncontrollers = 0;
> - }
> + virDomainControllerRemove(vm->def, idx);
> + virDomainControllerDefFree(detach);
>
> if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)&&
> qemuDomainPCIAddressReleaseSlot(priv->pciaddrs,
> detach->info.addr.pci.slot)< 0)
> VIR_WARN("Unable to release PCI address on controller");
>
> - virDomainControllerDefFree(detach);
> -
> ret = 0;
>
> cleanup:
More information about the libvir-list
mailing list