diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 63ec0a21889ae4c585cda6d3f056036f410c267a..a80bc3fe3a9d570d1b9157511a77e798cb847713 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -4096,6 +4096,31 @@ libxlDomainUpdateDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) } +static void +libxlDomainAttachDeviceNormalize(const virDomainDeviceDef *devConf, + virDomainDeviceDefPtr devLive) +{ + /* + * Fixup anything that needs to be identical in the live and + * config versions of DeviceDef, but might not be. Do this by + * changing the contents of devLive. This is done after all + * post-parse tweaks and validation, so be very careful about what + * changes are made. + */ + + /* MAC address should be identical in both DeviceDefs, but if it + * wasn't specified in the XML, and was instead autogenerated, it + * will be different for the two since they are each the result of + * a separate parser call. If it *was* specified, it will already + * be the same, so copying does no harm. + */ + + if (devConf->type == VIR_DOMAIN_DEVICE_NET) + virMacAddrSet(&devLive->data.net->mac, &devConf->data.net->mac); + +} + + static int libxlDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, unsigned int flags) @@ -4104,7 +4129,9 @@ libxlDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); virDomainObjPtr vm = NULL; virDomainDefPtr vmdef = NULL; - virDomainDeviceDefPtr dev = NULL; + virDomainDeviceDefPtr devConf = NULL; + virDomainDeviceDef devConfSave = { 0 }; + virDomainDeviceDefPtr devLive = NULL; int ret = -1; virCheckFlags(VIR_DOMAIN_DEVICE_MODIFY_LIVE | @@ -4123,28 +4150,36 @@ libxlDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, goto endjob; if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) { - if (!(dev = virDomainDeviceDefParse(xml, vm->def, - driver->xmlopt, NULL, - VIR_DOMAIN_DEF_PARSE_INACTIVE))) + if (!(devConf = virDomainDeviceDefParse(xml, vm->def, + driver->xmlopt, NULL, + VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto endjob; /* Make a copy for updated domain. */ if (!(vmdef = virDomainObjCopyPersistentDef(vm, driver->xmlopt, NULL))) goto endjob; - if (libxlDomainAttachDeviceConfig(vmdef, dev) < 0) + /* + * devConf will be NULLed out by + * libxlDomainAttachDeviceConfig(), so save it for later use by + * libxlDomainAttachDeviceNormalize() + */ + devConfSave = *devConf; + + if (libxlDomainAttachDeviceConfig(vmdef, devConf) < 0) goto endjob; } if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) { - /* If dev exists it was created to modify the domain config. Free it. */ - virDomainDeviceDefFree(dev); - if (!(dev = virDomainDeviceDefParse(xml, vm->def, + if (!(devLive = virDomainDeviceDefParse(xml, vm->def, driver->xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto endjob; - if (libxlDomainAttachDeviceLive(driver, vm, dev) < 0) + if (flags & VIR_DOMAIN_AFFECT_CONFIG) + libxlDomainAttachDeviceNormalize(&devConfSave, devLive); + + if (libxlDomainAttachDeviceLive(driver, vm, devLive) < 0) goto endjob; /* @@ -4171,7 +4206,8 @@ libxlDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, cleanup: virDomainDefFree(vmdef); - virDomainDeviceDefFree(dev); + virDomainDeviceDefFree(devConf); + virDomainDeviceDefFree(devLive); virDomainObjEndAPI(&vm); virObjectUnref(cfg); return ret;