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:
Peter Krempa 2022-10-06 13:17:00 +02:00
parent e506b0ad37
commit d9e4075d4e
4 changed files with 72 additions and 83 deletions

View File

@ -1061,6 +1061,14 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
"iscsi",
);
VIR_ENUM_IMPL(virDomainHostdevPCIOrigstate,
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST,
"unbind",
"removeslot",
"reprobe",
);
VIR_ENUM_IMPL(virDomainHostdevSubsysUSBGuestReset,
VIR_DOMAIN_HOSTDEV_USB_GUEST_RESET_LAST,
"default",
@ -3365,8 +3373,10 @@ void virDomainHostdevDefClear(virDomainHostdevDef *def)
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
VIR_FREE(def->source.subsys.u.scsi_host.wwpn);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
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_LAST:
break;
@ -5731,41 +5741,6 @@ virDomainHostdevSubsysUSBDefParseXML(xmlNodePtr node,
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
virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
@ -5774,7 +5749,6 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
unsigned int flags)
{
xmlNodePtr address = NULL;
xmlNodePtr origstates = NULL;
VIR_XPATH_NODE_AUTORESTORE(ctxt)
ctxt->node = node;
@ -5788,10 +5762,35 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node,
virPCIDeviceAddressParseXML(address, &def->source.subsys.u.pci.addr) < 0)
return -1;
if ((flags & VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES) &&
(origstates = virXPathNode("./origstates", ctxt)) &&
virDomainHostdevSubsysPCIOrigStatesDefParseXML(origstates, &def->origstates) < 0)
return -1;
if ((flags & VIR_DOMAIN_DEF_PARSE_PCI_ORIG_STATES)) {
virDomainHostdevSubsysPCI *pcisrc = &def->source.subsys.u.pci;
g_autofree xmlNodePtr *nodes = NULL;
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;
}
@ -23154,7 +23153,6 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf,
{
g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER;
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;
if (def->writeFiltering != VIR_TRISTATE_BOOL_ABSENT)
@ -23176,15 +23174,14 @@ virDomainHostdevDefFormatSubsysPCI(virBuffer *buf,
virPCIDeviceAddressFormat(&sourceChildBuf, pcisrc->addr, includeTypeInAddr);
if ((flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) {
if (def->origstates.states.pci.unbind_from_stub)
virBufferAddLit(&origstatesChildBuf, "<unbind/>\n");
if (pcisrc->origstates &&
(flags & VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES)) {
g_auto(virBuffer) origstatesChildBuf = VIR_BUFFER_INIT_CHILD(&sourceChildBuf);
ssize_t n = -1;
if (def->origstates.states.pci.remove_slot)
virBufferAddLit(&origstatesChildBuf, "<removeslot/>\n");
if (def->origstates.states.pci.reprobe)
virBufferAddLit(&origstatesChildBuf, "<reprobe/>\n");
while ((n = virBitmapNextSetBit(pcisrc->origstates, n)) >= 0)
virBufferAsprintf(&origstatesChildBuf, "<%s/>\n",
virDomainHostdevPCIOrigstateTypeToString(n));
virXMLFormatElement(&sourceChildBuf, "origstates", NULL, &origstatesChildBuf);
}

View File

@ -167,28 +167,14 @@ typedef enum {
} virDomainHyperVMode;
VIR_ENUM_DECL(virDomainHyperVMode);
struct _virDomainHostdevOrigStates {
union {
struct {
/* Does the device need to unbind from stub when
* reattaching to host?
*/
bool unbind_from_stub;
typedef enum {
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_UNBIND = 0, /* device needs to unbind from stub when reattaching */
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REMOVESLOT, /* use remove_slot when reattaching */
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REPROBE, /* reprobe driver for device when reattaching */
/* Does it need to use remove_slot when reattaching
* the device to host?
*/
bool remove_slot;
/* Does it need to reprobe driver for the device when
* reattaching to host?
*/
bool reprobe;
} pci;
/* Perhaps 'usb' in future */
} states;
};
VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST
} virDomainHostdevPCIOrigstate;
VIR_ENUM_DECL(virDomainHostdevPCIOrigstate);
struct _virDomainLeaseDef {
char *lockspace;
@ -262,6 +248,8 @@ struct _virDomainHostdevSubsysUSB {
struct _virDomainHostdevSubsysPCI {
virPCIDeviceAddress addr; /* host address */
virDomainHostdevSubsysPCIBackendType backend;
virBitmap *origstates;
};
struct _virDomainHostdevSubsysSCSIHost {
@ -394,7 +382,6 @@ struct _virDomainHostdevDef {
virDomainHostdevSubsys subsys;
virDomainHostdevCaps caps;
} source;
virDomainHostdevOrigStates origstates;
virDomainNetTeamingInfo *teaming;
virDomainDeviceInfo *info; /* Guest address */
};

View File

@ -116,8 +116,6 @@ typedef struct _virDomainHostdevCaps virDomainHostdevCaps;
typedef struct _virDomainHostdevDef virDomainHostdevDef;
typedef struct _virDomainHostdevOrigStates virDomainHostdevOrigStates;
typedef struct _virDomainHostdevSubsys virDomainHostdevSubsys;
typedef struct _virDomainHostdevSubsysMediatedDev virDomainHostdevSubsysMediatedDev;

View File

@ -873,12 +873,18 @@ virHostdevPreparePCIDevicesImpl(virHostdevManager *mgr,
if (actual) {
VIR_DEBUG("Saving network configuration of PCI device %s",
virPCIDeviceGetName(actual));
hostdev->origstates.states.pci.unbind_from_stub =
virPCIDeviceGetUnbindFromStub(actual);
hostdev->origstates.states.pci.remove_slot =
virPCIDeviceGetRemoveSlot(actual);
hostdev->origstates.states.pci.reprobe =
virPCIDeviceGetReprobe(actual);
if (!pcisrc->origstates)
pcisrc->origstates = virBitmapNew(VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_LAST);
else
virBitmapClearAll(pcisrc->origstates);
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++) {
const virDomainHostdevDef *hostdev = hostdevs[i];
g_autoptr(virPCIDevice) actual = NULL;
virBitmap *orig = hostdev->source.subsys.u.pci.origstates;
if (virHostdevGetPCIHostDevice(hostdev, &actual) < 0)
goto cleanup;
@ -1143,9 +1150,9 @@ virHostdevUpdateActivePCIDevices(virHostdevManager *mgr,
goto cleanup;
/* Setup the original states for the PCI device */
virPCIDeviceSetUnbindFromStub(actual, hostdev->origstates.states.pci.unbind_from_stub);
virPCIDeviceSetRemoveSlot(actual, hostdev->origstates.states.pci.remove_slot);
virPCIDeviceSetReprobe(actual, hostdev->origstates.states.pci.reprobe);
virPCIDeviceSetUnbindFromStub(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_UNBIND));
virPCIDeviceSetRemoveSlot(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REMOVESLOT));
virPCIDeviceSetReprobe(actual, virBitmapIsBitSet(orig, VIR_DOMAIN_HOSTDEV_PCI_ORIGSTATE_REPROBE));
if (virPCIDeviceListAdd(mgr->activePCIHostdevs, actual) < 0)
goto cleanup;