]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: filter regular files when enumerating
authorLennart Poettering <lennart@poettering.net>
Tue, 12 Apr 2022 09:25:00 +0000 (11:25 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Apr 2022 12:41:04 +0000 (14:41 +0200)
Currently if enumerating with debug logging you'll likely see something
like this:

sd-device: the syspath "/sys/class/devcoredump/disabled" is not a directory.
sd-device: the syspath "/sys/class/firmware/timeout" is not a directory.
sd-device: the syspath "/sys/class/zram-control/hot_remove" is not a directory.
sd-device: the syspath "/sys/class/zram-control/hot_add" is not a directory.
sd-device: the syspath "/sys/class/drm/version" is not a directory.

This is because these sysfs classes place regular files in these
directories, which we so far didn't expect.

Let's filter them early, and only bother with enumerated inodes if they
actually are dirs or symlinks, i.e. can be kobject dirs. Regular file
definitely never are kobject dirs...

src/libsystemd/sd-device/device-enumerator.c

index 55b8aba53acbf06f4fcb53b02cc454e0a9582143..9345cbea6c1a170ea2eedb6a84d2916c5ec5e161 100644 (file)
@@ -577,6 +577,17 @@ static int test_matches(
         return true;
 }
 
+static bool relevant_sysfs_subdir(const struct dirent *de) {
+        assert(de);
+
+        if (de->d_name[0] == '.')
+                return false;
+
+        /* Also filter out regular files and such, i.e. stuff that definitely isn't a kobject path. (Note
+         * that we rely on the fact that sysfs fills in d_type here, i.e. doesn't do DT_UNKNOWN) */
+        return IN_SET(de->d_type, DT_DIR, DT_LNK);
+}
+
 static int enumerator_scan_dir_and_add_devices(
                 sd_device_enumerator *enumerator,
                 const char *basedir,
@@ -607,7 +618,7 @@ static int enumerator_scan_dir_and_add_devices(
                 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
                 char syspath[strlen(path) + 1 + strlen(de->d_name) + 1];
 
-                if (de->d_name[0] == '.')
+                if (!relevant_sysfs_subdir(de))
                         continue;
 
                 if (!match_sysname(enumerator, de->d_name))
@@ -682,7 +693,7 @@ static int enumerator_scan_dir(
         FOREACH_DIRENT_ALL(de, dir, return -errno) {
                 int k;
 
-                if (de->d_name[0] == '.')
+                if (!relevant_sysfs_subdir(de))
                         continue;
 
                 if (!match_subsystem(enumerator, subsystem ? : de->d_name))