]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
rfkill: move wait_for_initialized() to shared/
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 14 Dec 2018 11:32:33 +0000 (12:32 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 17 Dec 2018 12:50:51 +0000 (13:50 +0100)
The function interface is the same, except that the output pointer may be NULL.

The implementation is slightly simplified by taking advantage of changes in
ancestor commit 'sd-device: attempt to read db again if it wasn't found', by
not creating a new sd_device object before re-checking the is_initialized
status.

v2:
- In v1, the old object was always used and the device received back from the
  sd_device_monitor_start callback was ignored. I *think* the result will be
  equivalent in both cases, because by the time we the callback gets called,
  the db entry in the filesystem will also exist, and any subsequent access to
  properties of the object would trigger a read of the database from disk. But
  I'm not certain, and anyway, using the device object received in the callback
  seems cleaner.

src/rfkill/rfkill.c
src/shared/udev-util.c
src/shared/udev-util.h

index 1cc887df122370cbe733a7e8fdda6737da605978..ac21dc064cae76bcf3de6518ed42094805c029e4 100644 (file)
@@ -18,6 +18,7 @@
 #include "proc-cmdline.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "udev-util.h"
 #include "util.h"
 #include "list.h"
 
@@ -88,89 +89,6 @@ static int find_device(
         return 0;
 }
 
-struct DeviceMonitorData {
-        const char *sysname;
-        sd_device *device;
-};
-
-static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
-        struct DeviceMonitorData *data = userdata;
-        const char *sysname;
-
-        assert(device);
-        assert(data);
-        assert(data->sysname);
-
-        if (sd_device_get_sysname(device, &sysname) >= 0 && streq(sysname, data->sysname)) {
-                data->device = sd_device_ref(device);
-                return sd_event_exit(sd_device_monitor_get_event(monitor), 0);
-        }
-
-        return 0;
-}
-
-static int wait_for_initialized(
-                sd_device *device,
-                sd_device **ret) {
-
-        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
-        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
-        _cleanup_(sd_device_unrefp) sd_device *d = NULL;
-        struct DeviceMonitorData data = {};
-        int r;
-
-        assert(device);
-        assert(ret);
-
-        if (sd_device_get_is_initialized(device) > 0) {
-                *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_default(&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, "rfkill", NULL);
-        if (r < 0)
-                return log_error_errno(r, "Failed to add rfkill device match to monitor: %m");
-
-        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 */
-        r = sd_device_new_from_subsystem_sysname(&d, "rfkill", data.sysname);
-        if (r < 0)
-                return log_full_errno(IN_SET(r, -ENOENT, -ENXIO, -ENODEV) ? LOG_DEBUG : LOG_ERR, r,
-                                      "Failed to open device '%s': %m", data.sysname);
-
-        if (sd_device_get_is_initialized(d) > 0) {
-                *ret = TAKE_PTR(d);
-                return 0;
-        }
-
-        r = sd_event_loop(event);
-        if (r < 0)
-                return log_error_errno(r, "Event loop failed: %m");
-
-        *ret = TAKE_PTR(data.device);
-        return 0;
-}
-
 static int determine_state_file(
                 const struct rfkill_event *event,
                 char **ret) {
@@ -187,7 +105,7 @@ static int determine_state_file(
         if (r < 0)
                 return r;
 
-        r = wait_for_initialized(d, &device);
+        r = device_wait_for_initialization(d, "rfkill", &device);
         if (r < 0)
                 return r;
 
index fdeaf8f613e5c2138ae3cd3e2259923ab8fedcde..4200032b3b6c15aeaddedae3cdc3ae4c35cb0268 100644 (file)
@@ -91,3 +91,81 @@ int udev_parse_config_full(
 
         return 0;
 }
+
+struct DeviceMonitorData {
+        const char *sysname;
+        sd_device *device;
+};
+
+static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
+        struct DeviceMonitorData *data = userdata;
+        const char *sysname;
+
+        assert(device);
+        assert(data);
+        assert(data->sysname);
+        assert(!data->device);
+
+        if (sd_device_get_sysname(device, &sysname) >= 0 && streq(sysname, data->sysname)) {
+                data->device = sd_device_ref(device);
+                return sd_event_exit(sd_device_monitor_get_event(monitor), 0);
+        }
+
+        return 0;
+}
+
+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_default(&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;
+}
index be08fe1ff898b95ad4bb02ebfd3938249c73c3fe..932c4a9cd5f6083e8329f1d79c4830fa1188f9d0 100644 (file)
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 #pragma once
 
+#include "sd-device.h"
+
 #include "time-util.h"
 
 typedef enum ResolveNameTiming {
@@ -23,3 +25,5 @@ int udev_parse_config_full(
 static inline int udev_parse_config(void) {
         return udev_parse_config_full(NULL, NULL, NULL, NULL);
 }
+
+int device_wait_for_initialization(sd_device *device, const char *subsystem, sd_device **ret);