When attaching a device that already exists, xend driver updates
the device with "device_configure", it causes problems (e.g. for
disk device, it only can be used to update device like CDROM),
and actually we provide additional API (virDomainUpdateDevice) to
update device, this fix is to raise up errors instead of updating
the existed device.
* src/xen/xend_internal.c
---
src/xen/xend_internal.c | 36 +++++++++++++++++++++++++-----------
1 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 6ce0c3f..c71aeb3 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -3956,6 +3956,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
virDomainDefPtr def = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
char class[8], ref[80];
+ char *target;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
virXendError(VIR_ERR_INVALID_ARG, __FUNCTION__);
@@ -4020,6 +4021,8 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
STREQ(def->os.type, "hvm") ? 1 : 0,
priv->xendConfigVersion, 1) < 0)
goto cleanup;
+
+ target = dev->data.disk->dst;
break;
case VIR_DOMAIN_DEVICE_NET:
@@ -4029,6 +4032,12 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
STREQ(def->os.type, "hvm") ? 1 : 0,
priv->xendConfigVersion, 1) < 0)
goto cleanup;
+
+ if (virParseMacAddr(target, dev->data.net->mac) < 0) {
+ virXendError(VIR_ERR_INTERNAL_ERROR,
+ _("malformed mac address '%s'"), target);
+ goto cleanup;
+ }
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
@@ -4037,13 +4046,18 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
if (xenDaemonFormatSxprOnePCI(dev->data.hostdev,
&buf, 0) < 0)
goto cleanup;
- } else {
- virXendError(VIR_ERR_NO_SUPPORT, "%s",
- _("unsupported device type"));
- goto cleanup;
- }
- break;
+ virDomainDevicePCIAddress PCIAddr;
+
+ PCIAddr = dev->data.hostdev->source.subsys.u.pci;
+ virAsprintf(&target, "PCI device: %.4x:%.2x:%.2x",
PCIAddr.domain,
+ PCIAddr.bus, PCIAddr.slot);
+
+ if (target == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
default:
virXendError(VIR_ERR_NO_SUPPORT, "%s",
_("unsupported device type"));
@@ -4056,17 +4070,17 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
/* device doesn't exist, define it */
ret = xend_op(domain->conn, domain->name, "op",
"device_create",
"config", sexpr, NULL);
- }
- else {
- /* device exists, attempt to modify it */
- ret = xend_op(domain->conn, domain->name, "op",
"device_configure",
- "config", sexpr, "dev", ref, NULL);
+ } else {
+ virXendError(VIR_ERR_OPERATION_INVALID,
+ _("target '%s' already exists"), target);
}
cleanup:
VIR_FREE(sexpr);
virDomainDefFree(def);
virDomainDeviceDefFree(dev);
+ if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV)
+ VIR_FREE(target);
return ret;
}
--
1.7.3.2