Projects
Mega:23.03
systemd
_service:tar_scm:backport-udevadm-cleanup-db-do...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:backport-udevadm-cleanup-db-don-t-delete-information-for-kept.patch of Package systemd
From 7a23db67795b6583028b7d7c0d5d8ef63c67d8c9 Mon Sep 17 00:00:00 2001 From: Martin Wilck <mwilck@suse.com> Date: Thu, 20 Jan 2022 14:31:45 +0100 Subject: [PATCH] udevadm: cleanup-db: don't delete information for kept db entries devices with the db_persist property won't be deleted during database cleanup. This applies to dm and md devices in particular. For such devices, we should also keep the files under /run/udev/links, /run/udev/tags, and /run/udev/watch, to make sure that after restart, udevd has the same information about the devices as it did before the cleanup. If we don't do this, a lower-priority device that is discovered in the coldplug phase may take over symlinks from a device that persisted. Not removing the watches also enables udevd to resume watching a device after restart. Signed-off-by: Martin Wilck <mwilck@suse.com> (cherry picked from commit 7ec624147a41d80f8e492c9fe19a24e2cda58c25) (cherry picked from commit ef7ceef26adb714ef44b2fbc07a219c05a012b42) Conflict:NA Reference:https://github.com/systemd/systemd/commit/7a23db67795b6583028b7d7c0d5d8ef63c67d8c9 --- src/udev/udevadm-info.c | 64 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index f05363150e..3314d6335e 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -248,6 +248,64 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) { } } +/* + * Assume that dir is a directory with file names matching udev data base + * 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). + * Returns true if the directory is empty after cleanup. + */ +static bool cleanup_dir_after_db_cleanup(DIR *dir, DIR *datadir) { + unsigned int kept = 0; + struct dirent *dent; + + assert(dir && datadir); + + FOREACH_DIRENT_ALL(dent, dir, break) { + struct stat data_stats, link_stats; + + if (dot_or_dot_dot(dent->d_name)) + continue; + if (fstatat(dirfd(dir), dent->d_name, &link_stats, AT_SYMLINK_NOFOLLOW) < 0) { + if (errno != ENOENT) + kept++; + continue; + } + + if (fstatat(dirfd(datadir), dent->d_name, &data_stats, 0) < 0) + (void) unlinkat(dirfd(dir), dent->d_name, + S_ISDIR(link_stats.st_mode) ? AT_REMOVEDIR : 0); + else + /* The entry still exists under /run/udev/data */ + kept++; + } + + return kept == 0; +} + +static void cleanup_dirs_after_db_cleanup(DIR *dir, DIR *datadir) { + struct dirent *dent; + + assert(dir && datadir); + + FOREACH_DIRENT_ALL(dent, dir, break) { + struct stat stats; + + if (dot_or_dot_dot(dent->d_name)) + continue; + if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) < 0) + continue; + if (S_ISDIR(stats.st_mode)) { + _cleanup_closedir_ DIR *dir2 = NULL; + + dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)); + if (dir2 && cleanup_dir_after_db_cleanup(dir2, datadir)) + (void) unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR); + } else + (void) unlinkat(dirfd(dir), dent->d_name, 0); + } +} + static void cleanup_db(void) { _cleanup_closedir_ DIR *dir1 = NULL, *dir2 = NULL, *dir3 = NULL, *dir4 = NULL, *dir5 = NULL; @@ -257,11 +315,11 @@ static void cleanup_db(void) { dir2 = opendir("/run/udev/links"); if (dir2) - cleanup_dir(dir2, 0, 2); + cleanup_dirs_after_db_cleanup(dir2, dir1); dir3 = opendir("/run/udev/tags"); if (dir3) - cleanup_dir(dir3, 0, 2); + cleanup_dirs_after_db_cleanup(dir3, dir1); dir4 = opendir("/run/udev/static_node-tags"); if (dir4) @@ -269,7 +327,7 @@ static void cleanup_db(void) { dir5 = opendir("/run/udev/watch"); if (dir5) - cleanup_dir(dir5, 0, 1); + cleanup_dir_after_db_cleanup(dir5, dir1); } static int query_device(QueryType query, sd_device* device) { -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2