1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

sd-device-monitor: expose low-level functions

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.
This commit is contained in:
Yu Watanabe 2024-05-27 12:22:30 +09:00
parent d3fa16131e
commit bab889c51e
6 changed files with 46 additions and 11 deletions

View 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;

View 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);

View 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) {

View 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");

View 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)

View 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);