mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
conf: Store 'origstates' of PCI hostdevs in a bitmap
Refactor the code to use a bitmap with an enum. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
This commit is contained in:
@@ -1061,6 +1061,14 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
|
|||||||
"iscsi",
|
"iscsi",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainHostdevPCIOrigstate,
|
||||||
|
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST,
|
||||||
|
"unbind",
|
||||||
|
"removeslot",
|
||||||
|
"reprobe",
|
||||||
|
);
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainHostdevSubsysUSBGuestReset,
|
VIR_ENUM_IMPL(virDomainHostdevSubsysUSBGuestReset,
|
||||||
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_LAST,
|
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_LAST,
|
||||||
"default",
|
"default",
|
||||||
@@ -3365,8 +3373,10 @@ void virDomainHostdevDefClear(virDomainHostdevDef *def)
|
|||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
|
||||||
VIR_FREE(def->source.subsys.u.scsi_host.wwpn);
|
VIR_FREE(def->source.subsys.u.scsi_host.wwpn);
|
||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
|
||||||
|
virBitmapFree(def->source.subsys.u.pci.origstates);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
|
||||||
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
|
||||||
break;
|
break;
|
||||||
@@ -5731,41 +5741,6 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The internal XML for host PCI device's original states:
|
|
||||||
*
|
|
||||||
* <origstates>
|
|
||||||
* <unbind/>
|
|
||||||
* <removeslot/>
|
|
||||||
* <reprobe/>
|
|
||||||
* </origstates>
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
virDomainHostdevSubsysPCIOrigStatesDefParseXML(xmlNodePtr node,
|
|
||||||
virDomainHostdevOrigStates *def)
|
|
||||||
{
|
|
||||||
xmlNodePtr cur;
|
|
||||||
cur = node->children;
|
|
||||||
|
|
||||||
while (cur != NULL) {
|
|
||||||
if (cur->type == XML_ELEMENT_NODE) {
|
|
||||||
if (virXMLNodeNameEqual(cur, "unbind")) {
|
|
||||||
def->states.pci.unbind_from_stub = true;
|
|
||||||
} else if (virXMLNodeNameEqual(cur, "removeslot")) {
|
|
||||||
def->states.pci.remove_slot = true;
|
|
||||||
} else if (virXMLNodeNameEqual(cur, "reprobe")) {
|
|
||||||
def->states.pci.reprobe = true;
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("unsupported element '%s' of 'origstates'"),
|
|
||||||
cur->name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur = cur->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
|
virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
|
||||||
@@ -5774,7 +5749,6 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
xmlNodePtr address = NULL;
|
xmlNodePtr address = NULL;
|
||||||
xmlNodePtr origstates = NULL;
|
|
||||||
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
VIR_XPATH_NODE_AUTORESTORE(ctxt)
|
||||||
|
|
||||||
ctxt->node = node;
|
ctxt->node = node;
|
||||||
@@ -5788,10 +5762,35 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
|
|||||||
virPCIDeviceAddressParseXML(address, &def->source.subsys.u.pci.addr) < 0)
|
virPCIDeviceAddressParseXML(address, &def->source.subsys.u.pci.addr) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((flags & VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES) &&
|
if ((flags & VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES)) {
|
||||||
(origstates = virXPathNode("./origstates", ctxt)) &&
|
virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci;
|
||||||
virDomainHostdevSubsysPCIOrigStatesDefParseXML(origstates, &def->origstates) < 0)
|
g_autofree xmlNodePtr *nodes = NULL;
|
||||||
return -1;
|
ssize_t nnodes;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if ((nnodes = virXPathNodeSet("./origstates/*", ctxt, &nodes)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nnodes > 0) {
|
||||||
|
if (!pcisrc->origstates)
|
||||||
|
pcisrc->origstates = virBitmapNew(VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST);
|
||||||
|
else
|
||||||
|
virBitmapClearAll(pcisrc->origstates);
|
||||||
|
|
||||||
|
for (i = 0; i < nnodes; i++) {
|
||||||
|
int state;
|
||||||
|
|
||||||
|
if ((state = virDomainHostdevPCIOrigstateTypeFromString((const char *) nodes[i]->name)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported element '%s' of 'origstates'"),
|
||||||
|
(const char *) nodes[i]->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBitmapSetBitExpand(pcisrc->origstates, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -23154,7 +23153,6 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf,
|
|||||||
{
|
{
|
||||||
g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER;
|
g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER;
|
||||||
g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf);
|
g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(buf);
|
||||||
g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf);
|
|
||||||
virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci;
|
virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci;
|
||||||
|
|
||||||
if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT)
|
if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT)
|
||||||
@@ -23176,15 +23174,14 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf,
|
|||||||
|
|
||||||
virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr);
|
virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr);
|
||||||
|
|
||||||
if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) {
|
if (pcisrc->origstates &&
|
||||||
if (def->origstates.states.pci.unbind_from_stub)
|
(flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) {
|
||||||
virBufferAddLit(&origstatesChildBuf, "<unbind/>\n");
|
g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf);
|
||||||
|
ssize_t n = -1;
|
||||||
|
|
||||||
if (def->origstates.states.pci.remove_slot)
|
while ((n = virBitmapNextSetBit(pcisrc->origstates, n)) >= 0)
|
||||||
virBufferAddLit(&origstatesChildBuf, "<removeslot/>\n");
|
virBufferAsprintf(&origstatesChildBuf, "<%s/>\n",
|
||||||
|
virDomainHostdevPCIOrigstateTypeToString(n));
|
||||||
if (def->origstates.states.pci.reprobe)
|
|
||||||
virBufferAddLit(&origstatesChildBuf, "<reprobe/>\n");
|
|
||||||
|
|
||||||
virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf);
|
virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,28 +167,14 @@ typedef enum {
|
|||||||
} virDomainHyperVMode;
|
} virDomainHyperVMode;
|
||||||
VIR_ENUM_DECL(virDomainHyperVMode);
|
VIR_ENUM_DECL(virDomainHyperVMode);
|
||||||
|
|
||||||
struct _virDomainHostdevOrigStates {
|
typedef enum {
|
||||||
union {
|
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_UNBIND = 0, /* device needs to unbind from stub when reattaching */
|
||||||
struct {
|
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REMOVESLOT, /* use remove_slot when reattaching */
|
||||||
/* Does the device need to unbind from stub when
|
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REPROBE, /* reprobe driver for device when reattaching */
|
||||||
* reattaching to host?
|
|
||||||
*/
|
|
||||||
bool unbind_from_stub;
|
|
||||||
|
|
||||||
/* Does it need to use remove_slot when reattaching
|
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST
|
||||||
* the device to host?
|
} virDomainHostdevPCIOrigstate;
|
||||||
*/
|
VIR_ENUM_DECL(virDomainHostdevPCIOrigstate);
|
||||||
bool remove_slot;
|
|
||||||
|
|
||||||
/* Does it need to reprobe driver for the device when
|
|
||||||
* reattaching to host?
|
|
||||||
*/
|
|
||||||
bool reprobe;
|
|
||||||
} pci;
|
|
||||||
|
|
||||||
/* Perhaps 'usb' in future */
|
|
||||||
} states;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _virDomainLeaseDef {
|
struct _virDomainLeaseDef {
|
||||||
char *lockspace;
|
char *lockspace;
|
||||||
@@ -262,6 +248,8 @@ struct _virDomainHostdevSubsysUSB {
|
|||||||
struct _virDomainHostdevSubsysPCI {
|
struct _virDomainHostdevSubsysPCI {
|
||||||
virPCIDeviceAddress addr; /* host address */
|
virPCIDeviceAddress addr; /* host address */
|
||||||
virDomainHostdevSubsysPCIBackendType backend;
|
virDomainHostdevSubsysPCIBackendType backend;
|
||||||
|
|
||||||
|
virBitmap *origstates;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _virDomainHostdevSubsysSCSIHost {
|
struct _virDomainHostdevSubsysSCSIHost {
|
||||||
@@ -394,7 +382,6 @@ struct _virDomainHostdevDef {
|
|||||||
virDomainHostdevSubsys subsys;
|
virDomainHostdevSubsys subsys;
|
||||||
virDomainHostdevCaps caps;
|
virDomainHostdevCaps caps;
|
||||||
} source;
|
} source;
|
||||||
virDomainHostdevOrigStates origstates;
|
|
||||||
virDomainNetTeamingInfo *teaming;
|
virDomainNetTeamingInfo *teaming;
|
||||||
virDomainDeviceInfo *info; /* Guest address */
|
virDomainDeviceInfo *info; /* Guest address */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -116,8 +116,6 @@ typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
|
|||||||
|
|
||||||
typedef struct _virDomainHostdevDef virDomainHostdevDef;
|
typedef struct _virDomainHostdevDef virDomainHostdevDef;
|
||||||
|
|
||||||
typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates;
|
|
||||||
|
|
||||||
typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys;
|
typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys;
|
||||||
|
|
||||||
typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev;
|
typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev;
|
||||||
|
|||||||
@@ -873,12 +873,18 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr,
|
|||||||
if (actual) {
|
if (actual) {
|
||||||
VIR_DEBUG("Saving network configuration of PCI device %s",
|
VIR_DEBUG("Saving network configuration of PCI device %s",
|
||||||
virPCIDeviceGetName(actual));
|
virPCIDeviceGetName(actual));
|
||||||
hostdev->origstates.states.pci.unbind_from_stub =
|
|
||||||
virPCIDeviceGetUnbindFromStub(actual);
|
if (!pcisrc->origstates)
|
||||||
hostdev->origstates.states.pci.remove_slot =
|
pcisrc->origstates = virBitmapNew(VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST);
|
||||||
virPCIDeviceGetRemoveSlot(actual);
|
else
|
||||||
hostdev->origstates.states.pci.reprobe =
|
virBitmapClearAll(pcisrc->origstates);
|
||||||
virPCIDeviceGetReprobe(actual);
|
|
||||||
|
if (virPCIDeviceGetUnbindFromStub(actual))
|
||||||
|
virBitmapSetBitExpand(pcisrc->origstates, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_UNBIND);
|
||||||
|
if (virPCIDeviceGetRemoveSlot(actual))
|
||||||
|
virBitmapSetBitExpand(pcisrc->origstates, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REMOVESLOT);
|
||||||
|
if (virPCIDeviceGetReprobe(actual))
|
||||||
|
virBitmapSetBitExpand(pcisrc->origstates, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REPROBE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1132,6 +1138,7 @@ virHostdevUpdateActivePCIDevices(virHostdevManager *mgr,
|
|||||||
for (i = 0; i < nhostdevs; i++) {
|
for (i = 0; i < nhostdevs; i++) {
|
||||||
const virDomainHostdevDef *hostdev = hostdevs[i];
|
const virDomainHostdevDef *hostdev = hostdevs[i];
|
||||||
g_autoptr(virPCIDevice) actual = NULL;
|
g_autoptr(virPCIDevice) actual = NULL;
|
||||||
|
virBitmap *orig = hostdev->source.subsys.u.pci.origstates;
|
||||||
|
|
||||||
if (virHostdevGetPCIHostDevice(hostdev, &actual) < 0)
|
if (virHostdevGetPCIHostDevice(hostdev, &actual) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -1143,9 +1150,9 @@ virHostdevUpdateActivePCIDevices(virHostdevManager *mgr,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Setup the original states for the PCI device */
|
/* Setup the original states for the PCI device */
|
||||||
virPCIDeviceSetUnbindFromStub(actual, hostdev->origstates.states.pci.unbind_from_stub);
|
virPCIDeviceSetUnbindFromStub(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_UNBIND));
|
||||||
virPCIDeviceSetRemoveSlot(actual, hostdev->origstates.states.pci.remove_slot);
|
virPCIDeviceSetRemoveSlot(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REMOVESLOT));
|
||||||
virPCIDeviceSetReprobe(actual, hostdev->origstates.states.pci.reprobe);
|
virPCIDeviceSetReprobe(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REPROBE));
|
||||||
|
|
||||||
if (virPCIDeviceListAdd(mgr->activePCIHostdevs, actual) < 0)
|
if (virPCIDeviceListAdd(mgr->activePCIHostdevs, actual) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|||||||
Reference in New Issue
Block a user