On Fri, 22 Apr 2011 12:07:56 +0900 KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> wrote: > > Rebased ont the latest git tree, which makes this work easier. > This series adds support for attach/detach/update disks of domain config. Ping ? Thanks, -Kame > == > This patch adds functions for modify domain's persistent definition. > To do error recovery in easy way, we use a copy of vmdef and update it. > > The whole sequence will be: > > make a copy of domain definition. > > if (flags & MODIFY_CONFIG) > update copied domain definition > if (flags & MODIF_LIVE) > do hotplug. > if (no error) > save copied one to the file and update cached definition. > else > discard copied definition. > > This patch is mixuture of Eric Blake's work and mine. > From: Eric Blake <eblake@xxxxxxxxxx> > Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> > > Changelog: v11 -> v12 > - rebased and fixed hunks. > - renamed qemudDomain....to qemuDomain... > > (virDomainObjCopyPersistentDef): make a copy of persistent vm definition > (qemuDomainAttach/Detach/UpdateDeviceConfig) : callbacks. now empty > (qemuDomainModifyDeviceFlags): add support for MODIFY_CONFIG and MODIFY_CURRENT > --- > src/conf/domain_conf.c | 18 ++++++ > src/conf/domain_conf.h | 3 + > src/libvirt_private.syms | 1 + > src/qemu/qemu_driver.c | 147 ++++++++++++++++++++++++++++++++++++---------- > 4 files changed, 137 insertions(+), 32 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 381e692..6c1098a 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -9509,3 +9509,21 @@ cleanup: > > return ret; > } > + > + > +virDomainDefPtr > +virDomainObjCopyPersistentDef(virCapsPtr caps, virDomainObjPtr dom) > +{ > + char *xml; > + virDomainDefPtr cur, ret; > + > + cur = virDomainObjGetPersistentDef(caps, dom); > + > + xml = virDomainDefFormat(cur, VIR_DOMAIN_XML_WRITE_FLAGS); > + if (!xml) > + return NULL; > + > + ret = virDomainDefParseString(caps, xml, VIR_DOMAIN_XML_READ_FLAGS); > + > + return ret; > +} > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 6ea30b9..ddf111a 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1288,6 +1288,9 @@ int virDomainObjSetDefTransient(virCapsPtr caps, > virDomainDefPtr > virDomainObjGetPersistentDef(virCapsPtr caps, > virDomainObjPtr domain); > +virDomainDefPtr > +virDomainObjCopyPersistentDef(virCapsPtr caps, virDomainObjPtr dom); > + > void virDomainRemoveInactive(virDomainObjListPtr doms, > virDomainObjPtr dom); > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index ba7739d..f732431 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -287,6 +287,7 @@ virDomainMemballoonModelTypeToString; > virDomainNetDefFree; > virDomainNetTypeToString; > virDomainObjAssignDef; > +virDomainObjCopyPersistentDef; > virDomainObjSetDefTransient; > virDomainObjGetPersistentDef; > virDomainObjIsDuplicate; > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index 771678e..fd85c8a 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -4073,6 +4073,46 @@ qemuDomainUpdateDeviceLive(virDomainObjPtr vm, > return ret; > } > > +static int > +qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef ATTRIBUTE_UNUSED, > + virDomainDeviceDefPtr dev) > +{ > + switch (dev->type) { > + default: > + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("persistent attach of device is not supported")); > + return -1; > + } > + return 0; > +} > + > + > +static int > +qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef ATTRIBUTE_UNUSED, > + virDomainDeviceDefPtr dev) > +{ > + switch (dev->type) { > + default: > + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("persistent detach of device is not supported")); > + return -1; > + } > + return 0; > +} > + > +static int > +qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef ATTRIBUTE_UNUSED, > + virDomainDeviceDefPtr dev) > +{ > + switch (dev->type) { > + default: > + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > + _("persistent update of device is not supported")); > + return -1; > + } > + return 0; > +} > + > /* Actions for qemuDomainModifyDeviceFlags */ > enum { > QEMU_DEVICE_ATTACH, > @@ -4088,6 +4128,7 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, > struct qemud_driver *driver = dom->conn->privateData; > virBitmapPtr qemuCaps = NULL; > virDomainObjPtr vm = NULL; > + virDomainDefPtr vmdef = NULL; > virDomainDeviceDefPtr dev = NULL; > bool force = (flags & VIR_DOMAIN_DEVICE_MODIFY_FORCE) != 0; > int ret = -1; > @@ -4097,12 +4138,6 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, > (action == QEMU_DEVICE_UPDATE ? > VIR_DOMAIN_DEVICE_MODIFY_FORCE : 0), -1); > > - if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { > - qemuReportError(VIR_ERR_OPERATION_INVALID, > - "%s", _("cannot modify the persistent configuration of a domain")); > - return -1; > - } > - > qemuDriverLock(driver); > vm = virDomainFindByUUID(&driver->domains, dom->uuid); > if (!vm) { > @@ -4116,12 +4151,27 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, > if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0) > goto cleanup; > > - if (!virDomainObjIsActive(vm)) { > - qemuReportError(VIR_ERR_OPERATION_INVALID, > - "%s", _("cannot attach device on inactive domain")); > - goto endjob; > + if (virDomainObjIsActive(vm)) { > + if (flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT) > + flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE; > + } else { > + if (flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT) > + flags |= VIR_DOMAIN_DEVICE_MODIFY_CONFIG; > + /* check consistency between flags and the vm state */ > + if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { > + qemuReportError(VIR_ERR_OPERATION_INVALID, > + "%s", > + _("cannot do live update a device on " > + "inactive domain")); > + goto endjob; > + } > } > > + if ((flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) && !vm->persistent) { > + qemuReportError(VIR_ERR_OPERATION_INVALID, > + "%s", _("cannot modify device on transient domain")); > + goto endjob; > + } > dev = virDomainDeviceDefParse(driver->caps, vm->def, xml, > VIR_DOMAIN_XML_INACTIVE); > if (dev == NULL) > @@ -4132,35 +4182,68 @@ qemuDomainModifyDeviceFlags(virDomainPtr dom, const char *xml, > &qemuCaps) < 0) > goto endjob; > > - switch (action) { > - case QEMU_DEVICE_ATTACH: > - ret = qemuDomainAttachDeviceLive(vm, dev, dom, qemuCaps); > - break; > - case QEMU_DEVICE_DETACH: > - ret = qemuDomainDetachDeviceLive(vm, dev, dom, qemuCaps); > - break; > - case QEMU_DEVICE_UPDATE: > - ret = qemuDomainUpdateDeviceLive(vm, dev, dom, qemuCaps, force); > - break; > - default: > - qemuReportError(VIR_ERR_INTERNAL_ERROR, > - _("unknown domain modify action %d"), action); > - break; > - } > + if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { > + /* Make a copy for updated domain. */ > + vmdef = virDomainObjCopyPersistentDef(driver->caps, vm); > + if (!vmdef) > + goto endjob; > + switch (action) { > + case QEMU_DEVICE_ATTACH: > + ret = qemuDomainAttachDeviceConfig(vmdef, dev); > + break; > + case QEMU_DEVICE_DETACH: > + ret = qemuDomainDetachDeviceConfig(vmdef, dev); > + break; > + case QEMU_DEVICE_UPDATE: > + ret = qemuDomainUpdateDeviceConfig(vmdef, dev); > + break; > + default: > + qemuReportError(VIR_ERR_INTERNAL_ERROR, > + _("unknown domain modify action %d"), action); > + break; > + } > + } else > + ret = 0; > > - /* > - * update domain status forcibly because the domain status may be changed > - * even if we attach the device failed. For example, a new controller may > - * be created. > - */ > - if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) > - ret = -1; > + if (!ret && (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)) { > + switch (action) { > + case QEMU_DEVICE_ATTACH: > + ret = qemuDomainAttachDeviceLive(vm, dev, dom, qemuCaps); > + break; > + case QEMU_DEVICE_DETACH: > + ret = qemuDomainDetachDeviceLive(vm, dev, dom, qemuCaps); > + break; > + case QEMU_DEVICE_UPDATE: > + ret = qemuDomainUpdateDeviceLive(vm, dev, dom, qemuCaps, force); > + break; > + default: > + qemuReportError(VIR_ERR_INTERNAL_ERROR, > + _("unknown domain modify action %d"), action); > + break; > + } > + /* > + * update domain status forcibly because the domain status may be > + * changed even if we attach the device failed. For example, a > + * For example, a new controller may be created. > + */ > + if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) > + ret = -1; > + } > + /* Finally, if no error until here, we can save config. */ > + if (!ret && (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)) { > + ret = virDomainSaveConfig(driver->configDir, vmdef); > + if (!ret) { > + virDomainObjAssignDef(vm, vmdef, false); > + vmdef = NULL; > + } > + } > > endjob: > if (qemuDomainObjEndJob(vm) == 0) > vm = NULL; > > cleanup: > + virDomainDefFree(vmdef); > virDomainDeviceDefFree(dev); > if (vm) > virDomainObjUnlock(vm); > -- > 1.7.4.1 > > > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list