From: Yu Watanabe Date: Sun, 21 Feb 2021 00:54:55 +0000 (+0900) Subject: sd-device-monitor: introduce sd_device_monitor_filter_add_match_parent() X-Git-Tag: v249-rc1~483^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8a0edbb2a27a3392653bb898629fe20efcef402;p=thirdparty%2Fsystemd.git sd-device-monitor: introduce sd_device_monitor_filter_add_match_parent() --- diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 0ac00081ae1..b025b550267 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -755,4 +755,5 @@ global: LIBSYSTEMD_249 { global: sd_device_monitor_filter_add_match_sysattr; + sd_device_monitor_filter_add_match_parent; } LIBSYSTEMD_248; diff --git a/src/libsystemd/sd-device/device-monitor.c b/src/libsystemd/sd-device/device-monitor.c index b12687cc2b5..b485e3e2b63 100644 --- a/src/libsystemd/sd-device/device-monitor.c +++ b/src/libsystemd/sd-device/device-monitor.c @@ -39,6 +39,8 @@ struct sd_device_monitor { Set *tag_filter; Hashmap *match_sysattr_filter; Hashmap *nomatch_sysattr_filter; + Set *match_parent_filter; + Set *nomatch_parent_filter; bool filter_uptodate; sd_event *event; @@ -340,6 +342,8 @@ static sd_device_monitor *device_monitor_free(sd_device_monitor *m) { set_free(m->tag_filter); hashmap_free(m->match_sysattr_filter); hashmap_free(m->nomatch_sysattr_filter); + set_free(m->match_parent_filter); + set_free(m->nomatch_parent_filter); return mfree(m); } @@ -404,7 +408,10 @@ static int passes_filter(sd_device_monitor *m, sd_device *device) { if (!check_tag_filter(m, device)) return false; - return device_match_sysattr(device, m->match_sysattr_filter, m->nomatch_sysattr_filter); + if (!device_match_sysattr(device, m->match_sysattr_filter, m->nomatch_sysattr_filter)) + return false; + + return device_match_parent(device, m->match_parent_filter, m->nomatch_parent_filter); } int device_monitor_receive_device(sd_device_monitor *m, sd_device **ret) { @@ -782,6 +789,27 @@ _public_ int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, co return hashmap_put_strdup_full(hashmap, &trivial_hash_ops_free_free, sysattr, value); } +_public_ int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match) { + const char *syspath; + Set **set; + int r; + + assert_return(m, -EINVAL); + assert_return(device, -EINVAL); + + r = sd_device_get_syspath(device, &syspath); + if (r < 0) + return r; + + if (match) + set = &m->match_parent_filter; + else + set = &m->nomatch_parent_filter; + + /* TODO: unset m->filter_uptodate on success when we support this filter on BPF. */ + return set_put_strdup(set, syspath); +} + _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) { static const struct sock_fprog filter = { 0, NULL }; @@ -791,6 +819,8 @@ _public_ int sd_device_monitor_filter_remove(sd_device_monitor *m) { m->tag_filter = set_free(m->tag_filter); m->match_sysattr_filter = hashmap_free(m->match_sysattr_filter); m->nomatch_sysattr_filter = hashmap_free(m->nomatch_sysattr_filter); + m->match_parent_filter = set_free(m->match_parent_filter); + m->nomatch_parent_filter = set_free(m->nomatch_parent_filter); if (setsockopt(m->sock, SOL_SOCKET, SO_DETACH_FILTER, &filter, sizeof(filter)) < 0) return -errno; diff --git a/src/systemd/sd-device.h b/src/systemd/sd-device.h index d7f78d82708..e760e03f35a 100644 --- a/src/systemd/sd-device.h +++ b/src/systemd/sd-device.h @@ -137,6 +137,7 @@ int sd_device_monitor_stop(sd_device_monitor *m); 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); int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, const char *sysattr, const char *value, int match); +int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match); int sd_device_monitor_filter_update(sd_device_monitor *m); int sd_device_monitor_filter_remove(sd_device_monitor *m);