mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 14:57:42 +00:00
udev: Remove event handle on shutdown
This fixes a segfault when the event handler is called after shutdown when the global driver state is NULL again. Also fix a locking issue in an error path.
This commit is contained in:
parent
7f7676e77b
commit
d115ed59e0
@ -41,6 +41,11 @@
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_NODEDEV
|
||||
|
||||
struct _udevPrivate {
|
||||
struct udev_monitor *udev_monitor;
|
||||
int watch;
|
||||
};
|
||||
|
||||
static virDeviceMonitorStatePtr driverState = NULL;
|
||||
|
||||
static int udevStrToLong_ull(char const *s,
|
||||
@ -1354,12 +1359,18 @@ static int udevDeviceMonitorShutdown(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
udevPrivate *priv = NULL;
|
||||
struct udev_monitor *udev_monitor = NULL;
|
||||
struct udev *udev = NULL;
|
||||
|
||||
if (driverState) {
|
||||
|
||||
nodeDeviceLock(driverState);
|
||||
|
||||
priv = driverState->privateData;
|
||||
|
||||
if (priv->watch != -1)
|
||||
virEventRemoveHandle(priv->watch);
|
||||
|
||||
udev_monitor = DRV_STATE_UDEV_MONITOR(driverState);
|
||||
|
||||
if (udev_monitor != NULL) {
|
||||
@ -1375,7 +1386,7 @@ static int udevDeviceMonitorShutdown(void)
|
||||
nodeDeviceUnlock(driverState);
|
||||
virMutexDestroy(&driverState->lock);
|
||||
VIR_FREE(driverState);
|
||||
|
||||
VIR_FREE(priv);
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
@ -1534,18 +1545,28 @@ out:
|
||||
|
||||
static int udevDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
|
||||
{
|
||||
udevPrivate *priv = NULL;
|
||||
struct udev *udev = NULL;
|
||||
struct udev_monitor *udev_monitor = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (VIR_ALLOC(priv) < 0) {
|
||||
virReportOOMError(NULL);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
priv->watch = -1;
|
||||
|
||||
if (VIR_ALLOC(driverState) < 0) {
|
||||
virReportOOMError(NULL);
|
||||
VIR_FREE(priv);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (virMutexInit(&driverState->lock) < 0) {
|
||||
VIR_ERROR0("Failed to initialize mutex for driverState");
|
||||
VIR_FREE(priv);
|
||||
VIR_FREE(driverState);
|
||||
ret = -1;
|
||||
goto out;
|
||||
@ -1562,18 +1583,19 @@ static int udevDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
|
||||
udev = udev_new();
|
||||
udev_set_log_fn(udev, udevLogFunction);
|
||||
|
||||
udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (udev_monitor == NULL) {
|
||||
priv->udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
|
||||
if (priv->udev_monitor == NULL) {
|
||||
VIR_FREE(priv);
|
||||
nodeDeviceUnlock(driverState);
|
||||
VIR_ERROR0("udev_monitor_new_from_netlink returned NULL");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
udev_monitor_enable_receiving(udev_monitor);
|
||||
udev_monitor_enable_receiving(priv->udev_monitor);
|
||||
|
||||
/* udev can be retrieved from udev_monitor */
|
||||
driverState->privateData = udev_monitor;
|
||||
nodeDeviceUnlock(driverState);
|
||||
driverState->privateData = priv;
|
||||
|
||||
/* We register the monitor with the event callback so we are
|
||||
* notified by udev of device changes before we enumerate existing
|
||||
@ -1583,14 +1605,17 @@ static int udevDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
|
||||
* enumeration. The alternative is to register the callback after
|
||||
* we enumerate, in which case we will fail to create any devices
|
||||
* that appear while the enumeration is taking place. */
|
||||
if (virEventAddHandle(udev_monitor_get_fd(udev_monitor),
|
||||
priv->watch = virEventAddHandle(udev_monitor_get_fd(priv->udev_monitor),
|
||||
VIR_EVENT_HANDLE_READABLE,
|
||||
udevEventHandleCallback,
|
||||
NULL, NULL) == -1) {
|
||||
udevEventHandleCallback, NULL, NULL);
|
||||
if (priv->watch == -1) {
|
||||
nodeDeviceUnlock(driverState);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
nodeDeviceUnlock(driverState);
|
||||
|
||||
/* Create a fictional 'computer' device to root the device tree. */
|
||||
if (udevSetupSystemDev() != 0) {
|
||||
ret = -1;
|
||||
|
@ -23,8 +23,10 @@
|
||||
#include <libudev.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _udevPrivate udevPrivate;
|
||||
|
||||
#define SYSFS_DATA_SIZE 4096
|
||||
#define DRV_STATE_UDEV_MONITOR(ds) ((struct udev_monitor *)((ds)->privateData))
|
||||
#define DRV_STATE_UDEV_MONITOR(ds) (((udevPrivate *)((ds)->privateData))->udev_monitor)
|
||||
#define DMI_DEVPATH "/sys/devices/virtual/dmi/id"
|
||||
#define DMI_DEVPATH_FALLBACK "/sys/class/dmi/id"
|
||||
#define PROPERTY_FOUND 0
|
||||
|
Loading…
Reference in New Issue
Block a user