]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device-monitor: introduce sd_device_monitor_filter_add_match_parent()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 21 Feb 2021 00:54:55 +0000 (09:54 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 2 Apr 2021 06:10:09 +0000 (15:10 +0900)
src/libsystemd/libsystemd.sym
src/libsystemd/sd-device/device-monitor.c
src/systemd/sd-device.h

index 0ac00081ae1cdfbec75c55533f844dcb3003a751..b025b550267426f787cef377679d54695d873882 100644 (file)
@@ -755,4 +755,5 @@ global:
 LIBSYSTEMD_249 {
 global:
         sd_device_monitor_filter_add_match_sysattr;
+        sd_device_monitor_filter_add_match_parent;
 } LIBSYSTEMD_248;
index b12687cc2b5fe6ac6087a86c54cb202096f5e1fb..b485e3e2b632aba145bd654b28b0316bcabaa307 100644 (file)
@@ -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;
index d7f78d827087f22e0d8b332453cc6f5c4bdc9e91..e760e03f35a9b413f5f5193a41c9e5e55f8bfb4e 100644 (file)
@@ -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);