mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 23:07:44 +00:00
nodedev: handle mdevs that disappear from mdevctl
mdevctl does not currently provide any events when the list of defined devices changes, so we will need to poll mdevctl for the list of defined devices periodically. When a mediated device no longer exists from one iteration to the next, we need to treat it as an "undefine" event. When we get such an event, we remove the device from the list if it's not active. Otherwise, we simply mark it as non-persistent. Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com> Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
00b649d0cf
commit
259ed0ff28
@ -1189,21 +1189,82 @@ virMdevctlListDefined(virNodeDeviceDef ***devs, char **errmsg)
|
||||
}
|
||||
|
||||
|
||||
typedef struct _virMdevctlForEachData virMdevctlForEachData;
|
||||
struct _virMdevctlForEachData {
|
||||
int ndefs;
|
||||
virNodeDeviceDef **defs;
|
||||
};
|
||||
|
||||
|
||||
/* This function keeps the list of persistent mediated devices consistent
|
||||
* between the nodedev driver and mdevctl.
|
||||
* @obj is a device that is currently known by the nodedev driver, and @opaque
|
||||
* contains the most recent list of devices defined by mdevctl. If @obj is no
|
||||
* longer defined in mdevctl, mark it as undefined and possibly remove it from
|
||||
* the driver as well. Returning 'true' from this function indicates that the
|
||||
* device should be removed from the nodedev driver list. */
|
||||
static bool
|
||||
removeMissingPersistentMdev(virNodeDeviceObj *obj,
|
||||
const void *opaque)
|
||||
{
|
||||
bool remove = false;
|
||||
const virMdevctlForEachData *data = opaque;
|
||||
size_t i;
|
||||
virNodeDeviceDef *def = virNodeDeviceObjGetDef(obj);
|
||||
virObjectEvent *event;
|
||||
|
||||
if (def->caps->data.type != VIR_NODE_DEV_CAP_MDEV)
|
||||
return false;
|
||||
|
||||
/* transient mdevs are populated via udev, so don't remove them from the
|
||||
* nodedev driver just because they are not reported by by mdevctl */
|
||||
if (!virNodeDeviceObjIsPersistent(obj))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < data->ndefs; i++) {
|
||||
/* OK, this mdev is still defined by mdevctl */
|
||||
if (STREQ(data->defs[i]->name, def->name))
|
||||
return false;
|
||||
}
|
||||
|
||||
event = virNodeDeviceEventLifecycleNew(def->name,
|
||||
VIR_NODE_DEVICE_EVENT_UNDEFINED,
|
||||
0);
|
||||
|
||||
/* The device is active, but no longer defined by mdevctl. Keep the device
|
||||
* in the list, but mark it as non-persistent */
|
||||
if (virNodeDeviceObjIsActive(obj))
|
||||
virNodeDeviceObjSetPersistent(obj, false);
|
||||
else
|
||||
remove = true;
|
||||
|
||||
virObjectEventStateQueue(driver->nodeDeviceEventState, event);
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nodeDeviceUpdateMediatedDevices(void)
|
||||
{
|
||||
g_autofree virNodeDeviceDef **defs = NULL;
|
||||
g_autofree char *errmsg = NULL;
|
||||
int ndefs;
|
||||
virMdevctlForEachData data = { 0, };
|
||||
size_t i;
|
||||
|
||||
if ((ndefs = virMdevctlListDefined(&defs, &errmsg)) < 0) {
|
||||
if ((data.ndefs = virMdevctlListDefined(&defs, &errmsg)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("failed to query mdevs from mdevctl: %s"), errmsg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ndefs; i++) {
|
||||
/* Any mdevs that were previously defined but were not returned in the
|
||||
* latest mdevctl query should be removed from the device list */
|
||||
data.defs = defs;
|
||||
virNodeDeviceObjListForEachRemove(driver->devs,
|
||||
removeMissingPersistentMdev, &data);
|
||||
|
||||
for (i = 0; i < data.ndefs; i++) {
|
||||
virNodeDeviceObj *obj;
|
||||
virObjectEvent *event;
|
||||
g_autoptr(virNodeDeviceDef) def = defs[i];
|
||||
|
Loading…
Reference in New Issue
Block a user