From 4b7f3de68cde0ed9c8950374d345141e06721c0d Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Fri, 10 Jul 2026 16:09:34 +0800 Subject: [PATCH] udevadm-info: handle missing data db cleanup udevadm info --cleanup-db cleaned links and tags by comparing them against /run/udev/data, but asserted when that data directory was missing. Treat a missing data directory as an empty database, so stale link and tag entries can be removed without aborting. Add a database test that runs cleanup-db with links and tags present but no data directory. Reproducer: $ sudo unshare --mount --propagation private sh -c ' mount -t tmpfs tmpfs /run/udev mkdir -p /run/udev/links/foo udevadm info --cleanup-db ' Assertion 'datadir' failed at src/udev/udevadm-info.c:676, function cleanup_dirs_after_db_cleanup(). Aborting. Aborted (core dumped) The command should handle a missing /run/udev/data directory instead of aborting. --- src/udev/udevadm-info.c | 5 ++--- test/units/TEST-17-UDEV.database.sh | 11 +++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index f2944b02f31..78c9520017c 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -655,16 +655,16 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) { * entries for devices in /run/udev/data (such as "b8:16"), and removes * all files except those that haven't been deleted in /run/udev/data * (i.e. they were skipped during db cleanup because of the db_persist flag). + * If the database directory does not exist, all entries are considered stale. */ static void cleanup_dir_after_db_cleanup(DIR *dir, DIR *datadir) { assert(dir); - assert(datadir); FOREACH_DIRENT_ALL(dent, dir, break) { if (dot_or_dot_dot(dent->d_name)) continue; - if (faccessat(dirfd(datadir), dent->d_name, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) + if (datadir && faccessat(dirfd(datadir), dent->d_name, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) /* The corresponding udev database file still exists. * Assuming the persistent flag is set for the database. */ continue; @@ -675,7 +675,6 @@ static void cleanup_dir_after_db_cleanup(DIR *dir, DIR *datadir) { static void cleanup_dirs_after_db_cleanup(DIR *dir, DIR *datadir) { assert(dir); - assert(datadir); FOREACH_DIRENT_ALL(dent, dir, break) { struct stat stats; diff --git a/test/units/TEST-17-UDEV.database.sh b/test/units/TEST-17-UDEV.database.sh index 56a79a665b0..ed50daa5ad3 100755 --- a/test/units/TEST-17-UDEV.database.sh +++ b/test/units/TEST-17-UDEV.database.sh @@ -15,4 +15,15 @@ udevadm wait --timeout=10 --removed --settle "/sys/class/net/$IFNAME" # CHeck if the database file is removed. [[ ! -e "/run/udev/data/n$IFINDEX" ]] +unshare --mount --propagation private bash -eux <<'EOF' +mount -t tmpfs tmpfs /run/udev +mkdir -p /run/udev/links/test /run/udev/tags/test +touch /run/udev/links/test/stale /run/udev/tags/test/stale + +udevadm info --cleanup-db + +[[ ! -e /run/udev/links/test ]] +[[ ! -e /run/udev/tags/test ]] +EOF + exit 0 -- 2.47.3