On Thu, Dec 24, 2020 at 08:14:30AM -0600, Jonathon Jongsma wrote: > Since a mediated device can be persistently defined by the mdevctl > backend, we need additional lifecycle events beyond CREATED/DELETED to > indicate that e.g. the device has been stopped but the device definition > still exists. This doesn't feel right to me. STARTED/STOPPED are esstentially the same as CREATED/DELETED semantically. None of the other APIs emit different events for persistent vs transient objects. We're adding the ability to define/undefine inactive mdev configs, so what is missing is the DEFINED/UNDEFINED events I believe. > > Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > --- > examples/c/misc/event-test.c | 4 ++++ > include/libvirt/libvirt-nodedev.h | 2 ++ > src/conf/node_device_conf.h | 1 + > src/node_device/node_device_driver.c | 1 + > src/node_device/node_device_udev.c | 25 +++++++++++++++++++++++-- > tools/virsh-nodedev.c | 4 +++- > 6 files changed, 34 insertions(+), 3 deletions(-) > > diff --git a/examples/c/misc/event-test.c b/examples/c/misc/event-test.c > index f164e825e1..d6eec648ec 100644 > --- a/examples/c/misc/event-test.c > +++ b/examples/c/misc/event-test.c > @@ -381,6 +381,10 @@ nodeDeviceEventToString(int event) > return "Created"; > case VIR_NODE_DEVICE_EVENT_DELETED: > return "Deleted"; > + case VIR_NODE_DEVICE_EVENT_STOPPED: > + return "Stopped"; > + case VIR_NODE_DEVICE_EVENT_STARTED: > + return "Started"; > case VIR_NODE_DEVICE_EVENT_LAST: > break; > } > diff --git a/include/libvirt/libvirt-nodedev.h b/include/libvirt/libvirt-nodedev.h > index d304283871..a473563857 100644 > --- a/include/libvirt/libvirt-nodedev.h > +++ b/include/libvirt/libvirt-nodedev.h > @@ -197,6 +197,8 @@ int virConnectNodeDeviceEventDeregisterAny(virConnectPtr conn, > typedef enum { > VIR_NODE_DEVICE_EVENT_CREATED = 0, > VIR_NODE_DEVICE_EVENT_DELETED = 1, > + VIR_NODE_DEVICE_EVENT_STOPPED = 2, > + VIR_NODE_DEVICE_EVENT_STARTED = 3, > > # ifdef VIR_ENUM_SENTINELS > VIR_NODE_DEVICE_EVENT_LAST > diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h > index 3d7872fd6e..bbc28cf2b9 100644 > --- a/src/conf/node_device_conf.h > +++ b/src/conf/node_device_conf.h > @@ -157,6 +157,7 @@ struct _virNodeDevCapMdev { > char *uuid; > virMediatedDeviceAttrPtr *attributes; > size_t nattributes; > + bool persistent; > }; > > typedef struct _virNodeDevCapPCIDev virNodeDevCapPCIDev; > diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c > index bbd373e32e..5309b8abd5 100644 > --- a/src/node_device/node_device_driver.c > +++ b/src/node_device/node_device_driver.c > @@ -899,6 +899,7 @@ nodeDeviceParseMdevctlChildDevice(const char *parent, > child->caps->data.type = VIR_NODE_DEV_CAP_MDEV; > > mdev = &child->caps->data.mdev; > + mdev->persistent = true; > mdev->uuid = g_strdup(uuid); > mdev->type = > g_strdup(virJSONValueObjectGetString(props, "mdev_type")); > diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c > index be59e6c6bc..632413d046 100644 > --- a/src/node_device/node_device_udev.c > +++ b/src/node_device/node_device_udev.c > @@ -1401,6 +1401,8 @@ udevRemoveOneDeviceSysPath(const char *path) > virNodeDeviceObjPtr obj = NULL; > virNodeDeviceDefPtr def; > virObjectEventPtr event = NULL; > + virNodeDevCapsDefPtr cap; > + int event_type = VIR_NODE_DEVICE_EVENT_DELETED; > > if (!(obj = virNodeDeviceObjListFindBySysfsPath(driver->devs, path))) { > VIR_DEBUG("Failed to find device to remove that has udev path '%s'", > @@ -1409,13 +1411,32 @@ udevRemoveOneDeviceSysPath(const char *path) > } > def = virNodeDeviceObjGetDef(obj); > > + /* If the device is a mediated device that has been 'stopped', it may still > + * be defined by mdevctl and can therefore be started again. Don't drop it > + * from the list of node devices */ > + cap = def->caps; > + while (cap != NULL) { > + if (cap->data.type == VIR_NODE_DEV_CAP_MDEV) { > + if (cap->data.mdev.persistent) { > + VIR_FREE(def->sysfs_path); > + event_type = VIR_NODE_DEVICE_EVENT_STOPPED; > + break; > + } > + } > + cap = cap->next; > + } > + > event = virNodeDeviceEventLifecycleNew(def->name, > - VIR_NODE_DEVICE_EVENT_DELETED, > + event_type, > 0); > > VIR_DEBUG("Removing device '%s' with sysfs path '%s'", > def->name, path); > - virNodeDeviceObjListRemove(driver->devs, obj); > + > + if (event_type == VIR_NODE_DEVICE_EVENT_DELETED) > + virNodeDeviceObjListRemove(driver->devs, obj); > + else > + virNodeDeviceObjSetActive(obj, false); > virNodeDeviceObjEndAPI(&obj); > > virObjectEventStateQueue(driver->nodeDeviceEventState, event); > diff --git a/tools/virsh-nodedev.c b/tools/virsh-nodedev.c > index 69422e20f5..35117585ff 100644 > --- a/tools/virsh-nodedev.c > +++ b/tools/virsh-nodedev.c > @@ -775,7 +775,9 @@ VIR_ENUM_DECL(virshNodeDeviceEvent); > VIR_ENUM_IMPL(virshNodeDeviceEvent, > VIR_NODE_DEVICE_EVENT_LAST, > N_("Created"), > - N_("Deleted")); > + N_("Deleted"), > + N_("Stopped"), > + N_("Started")); > > static const char * > virshNodeDeviceEventToString(int event) > -- > 2.26.2 > Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|