#include "device-handler.h"
#include "cdrom.h"
+/* We set a default monitor buffer size, as we may not process monitor
+ * events while performing device discvoery. systemd uses a 128M buffer, so
+ * we'll do the same here */
+static const int monitor_bufsize = 128 * 1024 * 1024;
+
struct pb_udev {
struct udev *udev;
struct udev_monitor *monitor;
{
struct pb_udev *udev = p;
- udev_monitor_unref(udev->monitor);
- udev->monitor = NULL;
+ if (udev->monitor) {
+ udev_monitor_unref(udev->monitor);
+ udev->monitor = NULL;
+ }
- udev_unref(udev->udev);
- udev->udev = NULL;
+ if (udev->udev) {
+ udev_unref(udev->udev);
+ udev->udev = NULL;
+ }
return 0;
}
if (ddev) {
pb_log("SKIP: %s UUID [%s] already present (as %s)\n",
name, uuid, ddev->device->id);
- return -1;
+ return 0;
}
}
static int udev_handle_dev_action(struct udev_device *dev, const char *action)
{
struct pb_udev *udev = udev_get_userdata(udev_device_get_udev(dev));
+ struct udev_list_entry *list;
+ const char *name;
-#ifdef DEBUG
- {
- struct udev_list_entry *list;
- const char *name;
-
- list = udev_device_get_properties_list_entry(dev);
- name = udev_device_get_sysname(dev);
+ list = udev_device_get_properties_list_entry(dev);
+ name = udev_device_get_sysname(dev);
- pb_debug("%s: action %s, device %s\n", __func__, action, name);
- pb_debug("%s properties:\n", __func__);
+ pb_debug("udev: action %s, device %s\n", action, name);
+ pb_debug("udev: properties:\n");
- for (; list; list = udev_list_entry_get_next(list))
- pb_log("\t%-20s: %s\n", udev_list_entry_get_name(list),
- udev_list_entry_get_value(list));
- } while (0);
-#endif
+ for (; list; list = udev_list_entry_get_next(list))
+ pb_debug("\t%-20s: %s\n", udev_list_entry_get_name(list),
+ udev_list_entry_get_value(list));
if (!strcmp(action, "add"))
return udev_handle_dev_add(udev, dev);
list = udev_enumerate_get_list_entry(enumerate);
- if (!list) {
- pb_log("udev_enumerate_get_list_entry failed\n");
- goto fail;
- }
-
udev_list_entry_foreach(entry, list) {
const char *syspath;
struct udev_device *dev;
goto out_err;
}
+ result = udev_monitor_set_receive_buffer_size(m, monitor_bufsize);
+ if (result) {
+ pb_log("udev_monitor_set_rx_bufsize(%d) failed\n",
+ monitor_bufsize);
+ }
+
result = udev_monitor_filter_add_match_subsystem_devtype(m, "block",
NULL);
struct udev_monitor *monitor = arg;
struct udev_device *dev;
const char *action;
- int result;
dev = udev_monitor_receive_device(monitor);
-
if (!dev) {
pb_log("udev_monitor_receive_device failed\n");
return -1;
if (!action) {
pb_log("udev_device_get_action failed\n");
- goto fail;
+ } else {
+ udev_handle_dev_action(dev, action);
}
- result = udev_handle_dev_action(dev, action);
-
- udev_device_unref(dev);
- return result;
-
-fail:
udev_device_unref(dev);
- return -1;
+ return 0;
}
static void udev_log_fn(struct udev __attribute__((unused)) *udev,
vfprintf(pb_log_get_stream(), format, args);
}
-struct pb_udev *udev_init(struct waitset *waitset,
- struct device_handler *handler)
+struct pb_udev *udev_init(struct device_handler *handler,
+ struct waitset *waitset)
{
+ struct pb_udev *udev;
int result;
- struct pb_udev *udev = talloc(NULL, struct pb_udev);
+ udev = talloc_zero(handler, struct pb_udev);
talloc_set_destructor(udev, udev_destructor);
udev->handler = handler;
if (!udev->udev) {
pb_log("udev_new failed\n");
- goto fail_new;
+ goto fail;
}
udev_set_userdata(udev->udev, udev);
result = udev_setup_monitor(udev->udev, &udev->monitor);
if (result)
- goto fail_monitor;
+ goto fail;
result = udev_enumerate(udev->udev);
if (result)
- goto fail_enumerate;
+ goto fail;
waiter_register_io(waitset, udev_monitor_get_fd(udev->monitor), WAIT_IN,
udev_process, udev->monitor);
return udev;
-fail_monitor:
- udev_monitor_unref(udev->monitor);
-fail_enumerate:
- udev_unref(udev->udev);
-fail_new:
+fail:
talloc_free(udev);
return NULL;
}
-void udev_destroy(struct pb_udev *udev)
+void udev_reinit(struct pb_udev *udev)
{
- talloc_free(udev);
+ pb_log("udev: reinit requested, starting enumeration\n");
+ udev_enumerate(udev->udev);
}