]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device-monitor: expose low-level functions
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 27 May 2024 03:22:30 +0000 (12:22 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Aug 2024 02:22:24 +0000 (11:22 +0900)
To make it work without sd-event.

Prompted by recent chat:
> Hey all!
> reading man libudev, it says to use sd-device instead now. I've read that
> APIs header file and it seems it no longer has an equivalent to libudev's
> udev_monitor_get_fd, which AFAICT means I have to use sd-event to watch
> for events I'm interested in. I know I can "embed" sd-event in other event
> loops I might already have, but that seems overkill when I'm only interested
> in this one type of event and don't need sd-event for anything else.

src/libsystemd/libsystemd.sym
src/libsystemd/sd-device/device-monitor-private.h
src/libsystemd/sd-device/device-monitor.c
src/libsystemd/sd-device/test-sd-device-monitor.c
src/libudev/libudev-monitor.c
src/systemd/sd-device.h

index fa3c0e9933fea63f10c91f9714fb20e1b7cdbdc0..65b81db46447998e3e0d313eb0b02f6e7384ab72 100644 (file)
@@ -1045,4 +1045,6 @@ global:
         sd_varlink_unref;
         sd_varlink_wait;
         sd_device_monitor_is_running;
+        sd_device_monitor_get_fd;
+        sd_device_monitor_receive;
 } LIBSYSTEMD_256;
index 6cd2fef3ca1733696943fcb5b15edf1c24a27666..af7dd2ec356c83ff63982401918639731eeb2ada 100644 (file)
@@ -18,6 +18,4 @@ typedef enum MonitorNetlinkGroup {
 int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group, int fd);
 int device_monitor_get_address(sd_device_monitor *m, union sockaddr_union *ret);
 int device_monitor_allow_unicast_sender(sd_device_monitor *m, sd_device_monitor *sender);
-int device_monitor_get_fd(sd_device_monitor *m);
 int device_monitor_send_device(sd_device_monitor *m, const union sockaddr_union *destination, sd_device *device);
-int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret);
index 50d4d577738cc273fd6a6094113f20eebb1d712d..002edd4f96b6e805ad59f37cc48eace7799139e7 100644 (file)
@@ -125,8 +125,8 @@ _public_ int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, siz
         return fd_set_rcvbuf(m->sock, size, false);
 }
 
-int device_monitor_get_fd(sd_device_monitor *m) {
-        assert(m);
+_public_ int sd_device_monitor_get_fd(sd_device_monitor *m) {
+        assert_return(m, -EINVAL);
 
         return m->sock;
 }
@@ -308,7 +308,7 @@ static int device_monitor_event_handler(sd_event_source *s, int fd, uint32_t rev
         _unused_ _cleanup_(log_context_unrefp) LogContext *c = NULL;
         sd_device_monitor *m = ASSERT_PTR(userdata);
 
-        if (device_monitor_receive_device(m, &device) <= 0)
+        if (sd_device_monitor_receive(m, &device) <= 0)
                 return 0;
 
         if (log_context_enabled())
@@ -537,7 +537,7 @@ static bool check_sender_uid(sd_device_monitor *m, uid_t uid) {
         return false;
 }
 
-int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
+_public_ int sd_device_monitor_receive(sd_device_monitor *m, sd_device **ret) {
         _cleanup_(sd_device_unrefp) sd_device *device = NULL;
         _cleanup_free_ uint8_t *buf_alloc = NULL;
         union {
@@ -562,8 +562,8 @@ int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) {
         bool is_initialized = false;
         int r;
 
-        assert(m);
-        assert(ret);
+        assert_return(m, -EINVAL);
+        assert_return(ret, -EINVAL);
 
         n = next_datagram_size_fd(m->sock);
         if (n < 0) {
index 651490ad1cb31dc772c1c78735ecd0e544b6109b..a64f2b4b84377fd584e9420e967570eac93bcc8a 100644 (file)
@@ -9,6 +9,7 @@
 #include "device-monitor-private.h"
 #include "device-private.h"
 #include "device-util.h"
+#include "io-util.h"
 #include "macro.h"
 #include "mountpoint-util.h"
 #include "path-util.h"
@@ -323,6 +324,38 @@ TEST(sd_device_monitor_filter_remove) {
         ASSERT_EQ(sd_event_loop(sd_device_monitor_get_event(monitor_client)), 100);
 }
 
+TEST(sd_device_monitor_receive) {
+        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor_server = NULL, *monitor_client = NULL;
+        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+        union sockaddr_union sa;
+        const char *syspath;
+        int fd, r;
+
+        prepare_loopback(&device);
+
+        ASSERT_OK(sd_device_get_syspath(device, &syspath));
+
+        prepare_monitor(&monitor_server, &monitor_client, &sa);
+
+        ASSERT_OK(device_monitor_send_device(monitor_server, &sa, device));
+
+        ASSERT_OK(fd = sd_device_monitor_get_fd(monitor_client));
+        for (;;) {
+                r = fd_wait_for_event(fd, POLLIN, 10 * USEC_PER_SEC);
+                if (r == -EINTR)
+                        continue;
+                ASSERT_GT(r, 0);
+                break;
+        }
+
+        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+        ASSERT_GT(sd_device_monitor_receive(monitor_client, &dev), 0);
+
+        const char *s;
+        ASSERT_OK(sd_device_get_syspath(dev, &s));
+        ASSERT_TRUE(streq(s, syspath));
+}
+
 static int intro(void) {
         if (getuid() != 0)
                 return log_tests_skipped("not root");
index b283154c40009d993e5aee80517a8d37ba61ef8e..55b6eb00f6769913fb0de768716f0d54f3863688 100644 (file)
@@ -186,7 +186,7 @@ _public_ struct udev *udev_monitor_get_udev(struct udev_monitor *udev_monitor) {
 _public_ int udev_monitor_get_fd(struct udev_monitor *udev_monitor) {
         assert_return(udev_monitor, -EINVAL);
 
-        return device_monitor_get_fd(udev_monitor->monitor);
+        return sd_device_monitor_get_fd(udev_monitor->monitor);
 }
 
 static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_device **ret) {
@@ -197,13 +197,13 @@ static int udev_monitor_receive_sd_device(struct udev_monitor *udev_monitor, sd_
 
         for (;;) {
                 /* r == 0 means a device is received but it does not pass the current filter. */
-                r = device_monitor_receive_device(udev_monitor->monitor, ret);
+                r = sd_device_monitor_receive(udev_monitor->monitor, ret);
                 if (r != 0)
                         return r;
 
                 for (;;) {
                         /* Wait for next message */
-                        r = fd_wait_for_event(device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0);
+                        r = fd_wait_for_event(sd_device_monitor_get_fd(udev_monitor->monitor), POLLIN, 0);
                         if (r == -EINTR)
                                 continue;
                         if (r < 0)
index 40786fc1cdccb7d71fe03ed54b61ce37d4762db6..c84cc552029abd944e5622341f8745dca0f94867 100644 (file)
@@ -142,6 +142,7 @@ int sd_device_monitor_new(sd_device_monitor **ret);
 sd_device_monitor *sd_device_monitor_ref(sd_device_monitor *m);
 sd_device_monitor *sd_device_monitor_unref(sd_device_monitor *m);
 
+int sd_device_monitor_get_fd(sd_device_monitor *m);
 int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, size_t size);
 int sd_device_monitor_attach_event(sd_device_monitor *m, sd_event *event);
 int sd_device_monitor_detach_event(sd_device_monitor *m);
@@ -152,6 +153,7 @@ int sd_device_monitor_get_description(sd_device_monitor *m, const char **ret);
 int sd_device_monitor_is_running(sd_device_monitor *m);
 int sd_device_monitor_start(sd_device_monitor *m, sd_device_monitor_handler_t callback, void *userdata);
 int sd_device_monitor_stop(sd_device_monitor *m);
+int sd_device_monitor_receive(sd_device_monitor *m, sd_device **ret);
 
 int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype);
 int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag);