Retain PCI address from NIC attach

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
This commit is contained in:
Mark McLoughlin 2009-07-17 22:08:34 +01:00
parent ffec099e75
commit 4e21a95afe
3 changed files with 44 additions and 1 deletions

View File

@ -962,6 +962,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
char *internal = NULL; char *internal = NULL;
char *nic_name = NULL; char *nic_name = NULL;
char *hostnet_name = NULL; char *hostnet_name = NULL;
char *devaddr = NULL;
char *vlan = NULL; char *vlan = NULL;
if (VIR_ALLOC(def) < 0) { if (VIR_ALLOC(def) < 0) {
@ -1032,6 +1033,7 @@ virDomainNetDefParseXML(virConnectPtr conn,
xmlStrEqual(cur->name, BAD_CAST "state")) { xmlStrEqual(cur->name, BAD_CAST "state")) {
nic_name = virXMLPropString(cur, "nic"); nic_name = virXMLPropString(cur, "nic");
hostnet_name = virXMLPropString(cur, "hostnet"); hostnet_name = virXMLPropString(cur, "hostnet");
devaddr = virXMLPropString(cur, "devaddr");
vlan = virXMLPropString(cur, "vlan"); vlan = virXMLPropString(cur, "vlan");
} }
} }
@ -1044,6 +1046,17 @@ virDomainNetDefParseXML(virConnectPtr conn,
virCapabilitiesGenerateMac(caps, def->mac); virCapabilitiesGenerateMac(caps, def->mac);
} }
if (devaddr &&
sscanf(devaddr, "%x:%x:%x",
&def->pci_addr.domain,
&def->pci_addr.bus,
&def->pci_addr.slot) < 3) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("Unable to parse devaddr parameter '%s'"),
devaddr);
goto error;
}
def->nic_name = nic_name; def->nic_name = nic_name;
def->hostnet_name = hostnet_name; def->hostnet_name = hostnet_name;
nic_name = hostnet_name = NULL; nic_name = hostnet_name = NULL;
@ -1176,6 +1189,7 @@ cleanup:
VIR_FREE(internal); VIR_FREE(internal);
VIR_FREE(nic_name); VIR_FREE(nic_name);
VIR_FREE(hostnet_name); VIR_FREE(hostnet_name);
VIR_FREE(devaddr);
VIR_FREE(vlan); VIR_FREE(vlan);
return def; return def;
@ -3634,6 +3648,11 @@ virDomainNetDefFormat(virConnectPtr conn,
virBufferEscapeString(buf, " nic='%s'", def->nic_name); virBufferEscapeString(buf, " nic='%s'", def->nic_name);
if (def->hostnet_name) if (def->hostnet_name)
virBufferEscapeString(buf, " hostnet='%s'", def->hostnet_name); virBufferEscapeString(buf, " hostnet='%s'", def->hostnet_name);
if (virNetHasValidPciAddr(def))
virBufferVSprintf(buf, " devaddr='%.4x:%.2x:%.2x'",
def->pci_addr.domain,
def->pci_addr.bus,
def->pci_addr.slot);
if (def->vlan > 0) if (def->vlan > 0)
virBufferVSprintf(buf, " vlan='%d'", def->vlan); virBufferVSprintf(buf, " vlan='%d'", def->vlan);
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");

View File

@ -192,9 +192,20 @@ struct _virDomainNetDef {
char *ifname; char *ifname;
char *nic_name; char *nic_name;
char *hostnet_name; char *hostnet_name;
struct {
unsigned domain;
unsigned bus;
unsigned slot;
} pci_addr;
int vlan; int vlan;
}; };
static inline int
virNetHasValidPciAddr(virDomainNetDefPtr def)
{
return def->pci_addr.domain || def->pci_addr.domain || def->pci_addr.slot;
}
enum virDomainChrSrcType { enum virDomainChrSrcType {
VIR_DOMAIN_CHR_TYPE_NULL, VIR_DOMAIN_CHR_TYPE_NULL,
VIR_DOMAIN_CHR_TYPE_VC, VIR_DOMAIN_CHR_TYPE_VC,

View File

@ -4551,6 +4551,7 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
virDomainNetDefPtr net = dev->data.net; virDomainNetDefPtr net = dev->data.net;
char *cmd, *reply, *remove_cmd; char *cmd, *reply, *remove_cmd;
int i; int i;
unsigned domain, bus, slot;
if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) { if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HOST_NET_ADD)) {
qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s", qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
@ -4622,10 +4623,22 @@ static int qemudDomainAttachNetDevice(virConnectPtr conn,
goto try_remove; goto try_remove;
} }
VIR_FREE(reply);
VIR_FREE(cmd); 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); VIR_FREE(remove_cmd);
net->pci_addr.domain = domain;
net->pci_addr.bus = bus;
net->pci_addr.slot = slot;
vm->def->nets[vm->def->nnets++] = net; vm->def->nets[vm->def->nnets++] = net;
return 0; return 0;