int device_wait_for_initialization(sd_device *device, const char *subsystem, sd_device **ret) { _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL; struct DeviceMonitorData data = {}; int r; assert(device); assert(subsystem); if (sd_device_get_is_initialized(device) > 0) { if (ret) *ret = sd_device_ref(device); return 0; } assert_se(sd_device_get_sysname(device, &data.sysname) >= 0); /* Wait until the device is initialized, so that we can get access to the ID_PATH property */ r = sd_event_new(&event); if (r < 0) return log_error_errno(r, "Failed to get default event: %m"); r = sd_device_monitor_new(&monitor); if (r < 0) return log_error_errno(r, "Failed to acquire monitor: %m"); r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, NULL); if (r < 0) return log_error_errno(r, "Failed to add %s subsystem match to monitor: %m", subsystem); r = sd_device_monitor_attach_event(monitor, event); if (r < 0) return log_error_errno(r, "Failed to attach event to device monitor: %m"); r = sd_device_monitor_start(monitor, device_monitor_handler, &data); if (r < 0) return log_error_errno(r, "Failed to start device monitor: %m"); /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized * yet. */ if (sd_device_get_is_initialized(device) > 0) { if (ret) *ret = sd_device_ref(device); return 0; } r = sd_event_loop(event); if (r < 0) return log_error_errno(r, "Event loop failed: %m"); if (ret) *ret = TAKE_PTR(data.device); return 0; }
static int setup_monitor(MonitorNetlinkGroup sender, sd_event *event, sd_device_monitor **ret) { _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL; const char *subsystem, *devtype, *tag; Iterator i; int r; r = device_monitor_new_full(&monitor, sender, -1); if (r < 0) return log_error_errno(r, "Failed to create netlink socket: %m"); (void) sd_device_monitor_set_receive_buffer_size(monitor, 128*1024*1024); r = sd_device_monitor_attach_event(monitor, event); if (r < 0) return log_error_errno(r, "Failed to attach event: %m"); HASHMAP_FOREACH_KEY(devtype, subsystem, arg_subsystem_filter, i) { r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, devtype); if (r < 0) return log_error_errno(r, "Failed to apply subsystem filter '%s%s%s': %m", subsystem, devtype ? "/" : "", strempty(devtype)); }