When we pci_add a NIC, we need to retain the PCI address assigned by
qemu for using during detach.
* src/qemu_driver.c: use qemudParsePciAddReply() to pull the PCI
address from the pci_add reply
* src/domain_conf.c: handle storing and parsing the PCI address in the
domain state XML file
---
src/domain_conf.c | 9 ++++++++-
src/domain_conf.h | 1 +
src/qemu_driver.c | 17 +++++++++++++++--
3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/domain_conf.c b/src/domain_conf.c
index cce863c..ce47e59 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -341,6 +341,7 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
VIR_FREE(def->ifname);
VIR_FREE(def->nic_name);
VIR_FREE(def->hostnet_name);
+ VIR_FREE(def->pci_addr);
VIR_FREE(def);
}
@@ -954,6 +955,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
char *internal = NULL;
char *nic_name = NULL;
char *hostnet_name = NULL;
+ char *pci_addr = NULL;
char *vlan = NULL;
if (VIR_ALLOC(def) < 0) {
@@ -1024,6 +1026,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
xmlStrEqual(cur->name, BAD_CAST "state")) {
nic_name = virXMLPropString(cur, "nic");
hostnet_name = virXMLPropString(cur, "hostnet");
+ pci_addr = virXMLPropString(cur, "devaddr");
vlan = virXMLPropString(cur, "vlan");
}
}
@@ -1038,7 +1041,8 @@ virDomainNetDefParseXML(virConnectPtr conn,
def->nic_name = nic_name;
def->hostnet_name = hostnet_name;
- nic_name = hostnet_name = NULL;
+ def->pci_addr = pci_addr;
+ nic_name = hostnet_name = pci_addr = NULL;
def->vlan = -1;
if (vlan && virStrToLong_i(vlan, NULL, 10, &def->vlan) < 0) {
@@ -1168,6 +1172,7 @@ cleanup:
VIR_FREE(internal);
VIR_FREE(nic_name);
VIR_FREE(hostnet_name);
+ VIR_FREE(pci_addr);
VIR_FREE(vlan);
return def;
@@ -3624,6 +3629,8 @@ virDomainNetDefFormat(virConnectPtr conn,
virBufferEscapeString(buf, " nic='%s'", def->nic_name);
if (def->hostnet_name)
virBufferEscapeString(buf, " hostnet='%s'",
def->hostnet_name);
+ if (def->pci_addr)
+ virBufferEscapeString(buf, " devaddr='%s'",
def->pci_addr);
if (def->vlan > 0)
virBufferVSprintf(buf, " vlan='%d'", def->vlan);
virBufferAddLit(buf, "/>\n");
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 8fa384a..7a168a8 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -177,6 +177,7 @@ struct _virDomainNetDef {
char *ifname;
char *nic_name;
char *hostnet_name;
+ char *pci_addr;
int vlan;
};
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 27bda12..a3bb650 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -4552,7 +4552,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
{
virDomainNetDefPtr net =
dev->data.net;
char *cmd, *reply, *remove_cmd;
- int i;
+ int i, domain, bus, slot;
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, _("%s"),
@@ -4622,10 +4622,23 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
goto try_remove;
}
- VIR_FREE(reply);
VIR_FREE(cmd);
+
+ if (qemudParsePciAddReply(vm, reply, &domain, &bus, &slot) < 0) {
+ qemudReportError(conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _("parsing pci_add reply failed: %s"), reply);
+ VIR_FREE(reply);
+ goto try_remove;
+ }
+
+ VIR_FREE(reply);
VIR_FREE(remove_cmd);
+ if (virAsprintf(&net->pci_addr, "%.4x:%.2x:%.2x", domain, bus, slot)
< 0) {
+ virReportOOMError(conn);
+ goto try_remove;
+ }
+
vm->def->nets[vm->def->nnets++] = net;
return 0;
--
1.6.2.5