[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt PATCH v2 06/16] nodedev: add STOPPED/STARTED lifecycle events



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.

Signed-off-by: Jonathon Jongsma <jjongsma redhat com>
---
 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 52caa8ffa8..c40819969c 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 98a972e60d..423a583d45 100644
--- a/include/libvirt/libvirt-nodedev.h
+++ b/include/libvirt/libvirt-nodedev.h
@@ -192,6 +192,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 353dbebaf0..7e825ca6a9 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -144,6 +144,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 3b042e9a45..b47ecba10a 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -894,6 +894,7 @@ nodeDeviceParseMdevctlJSON(const char *jsonstring,
                 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 93b74b1f24..ac7986bc70 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1213,6 +1213,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'",
@@ -1221,13 +1223,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 e87761188f..f078ce6516 100644
--- a/tools/virsh-nodedev.c
+++ b/tools/virsh-nodedev.c
@@ -787,7 +787,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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]