mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 15:15:25 +00:00
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:
parent
ffec099e75
commit
4e21a95afe
@ -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");
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user