Introduce and use the driver functions for the node state shutdown preparation
and wait. As they're also called in the error/cleanup path of
`nodeStateInitialize`, they must be written in a way, that they can safely be
executed even if not everything is initialized.
In the next commit, these functions will be extended.
Signed-off-by: Marc Hartmayer <mhartmay(a)linux.ibm.com>
---
src/node_device/node_device_udev.c | 84 ++++++++++++++++++++++--------
1 file changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 1638a7196709..a3006433e842 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -92,12 +92,6 @@ udevEventDataDispose(void *obj)
g_list_free_full(g_steal_pointer(&priv->mdevctlMonitors),
g_object_unref);
}
- if (priv->watch != -1)
- virEventRemoveHandle(priv->watch);
-
- if (priv->mdevctlTimeout != -1)
- virEventRemoveTimeout(priv->mdevctlTimeout);
-
g_clear_pointer(&priv->udevThread, g_free);
if (priv->udev_monitor) {
@@ -1733,24 +1727,10 @@ udevPCITranslateDeinit(void)
static int
nodeStateCleanup(void)
{
- udevEventData *priv = NULL;
-
if (!driver)
return -1;
- priv = driver->privateData;
- if (priv) {
- VIR_WITH_OBJECT_LOCK_GUARD(priv) {
- priv->udevThreadQuit = true;
- virCondSignal(&priv->udevThreadCond);
- }
- if (priv->initThread)
- virThreadJoin(priv->initThread);
- if (priv->udevThread)
- virThreadJoin(priv->udevThread);
- }
-
- virObjectUnref(priv);
+ virObjectUnref(driver->privateData);
virObjectUnref(driver->nodeDeviceEventState);
virNodeDeviceObjListFree(driver->devs);
@@ -2241,6 +2221,64 @@ mdevctlEventHandleCallback(GFileMonitor *monitor G_GNUC_UNUSED,
}
+/* Note: It must be safe to call this function even if the driver was not
+ * successfully initialized. This must be considered when changing this
+ * function. */
+static int
+nodeStateShutdownPrepare(void)
+{
+ udevEventData *priv = NULL;
+
+ if (!driver)
+ return 0;
+
+ priv = driver->privateData;
+ if (!priv)
+ return 0;
+
+ VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+ if (priv->mdevctlTimeout != -1) {
+ virEventRemoveTimeout(priv->mdevctlTimeout);
+ priv->mdevctlTimeout = -1;
+ }
+
+ if (priv->watch) {
+ virEventRemoveHandle(priv->watch);
+ priv->watch = -1;
+ }
+
+ priv->udevThreadQuit = true;
+ virCondSignal(&priv->udevThreadCond);
+ }
+ return 0;
+}
+
+
+/* Note: It must be safe to call this function even if the driver was not
+ * successfully initialized. This must be considered when changing this
+ * function. */
+static int
+nodeStateShutdownWait(void)
+{
+ udevEventData *priv = NULL;
+
+ if (!driver)
+ return 0;
+
+ priv = driver->privateData;
+ if (!priv)
+ return 0;
+
+ VIR_WITH_OBJECT_LOCK_GUARD(priv) {
+ if (priv->initThread)
+ virThreadJoin(priv->initThread);
+ if (priv->udevThread)
+ virThreadJoin(priv->udevThread);
+ }
+ return 0;
+}
+
+
static int
nodeStateInitialize(bool privileged,
const char *root,
@@ -2375,6 +2413,8 @@ nodeStateInitialize(bool privileged,
return VIR_DRV_STATE_INIT_COMPLETE;
cleanup:
+ nodeStateShutdownPrepare();
+ nodeStateShutdownWait();
nodeStateCleanup();
return VIR_DRV_STATE_INIT_ERROR;
@@ -2440,6 +2480,8 @@ static virStateDriver udevStateDriver = {
.stateInitialize = nodeStateInitialize, /* 0.7.3 */
.stateCleanup = nodeStateCleanup, /* 0.7.3 */
.stateReload = nodeStateReload, /* 0.7.3 */
+ .stateShutdownPrepare = nodeStateShutdownPrepare, /* 10.3.0 */
+ .stateShutdownWait = nodeStateShutdownWait, /* 10.3.0 */
};
--
2.34.1