diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-11 21:52:49 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-09-03 05:01:52 +0900 |
commit | 1055172804e660df2e1c498dafa998ffd65e0c88 (patch) | |
tree | f551de6955888afd5afcfe11916f8bcf4463d224 /src | |
parent | 57a272902aa821f9598dd0d74eab98d287473a63 (diff) | |
download | systemd-1055172804e660df2e1c498dafa998ffd65e0c88.tar.gz |
udev: cleanup stack directory /run/udev/links when all workers exited
By the previous commit, the stack directories are not removed even if
it is empty. To reduce the inode usage of /run, let's cleanup the
directories.
Diffstat (limited to 'src')
-rw-r--r-- | src/udev/udev-node.c | 42 | ||||
-rw-r--r-- | src/udev/udev-node.h | 1 | ||||
-rw-r--r-- | src/udev/udevd.c | 10 |
3 files changed, 53 insertions, 0 deletions
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 42efaaa028..4e7dca06de 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -26,6 +26,48 @@ #define UDEV_NODE_HASH_KEY SD_ID128_MAKE(b9,6a,f1,ce,40,31,44,1a,9e,19,ec,8b,ae,f3,e3,2f) +int udev_node_cleanup(void) { + _cleanup_closedir_ DIR *dir = NULL; + + /* This must not be called when any workers exist. It would cause a race between mkdir() called + * by stack_directory_lock() and unlinkat() called by this. */ + + dir = opendir("/run/udev/links"); + if (!dir) { + if (errno == ENOENT) + return 0; + + return log_debug_errno(errno, "Failed to open directory '/run/udev/links', ignoring: %m"); + } + + FOREACH_DIRENT_ALL(de, dir, break) { + _cleanup_free_ char *lockfile = NULL; + + if (de->d_name[0] == '.') + continue; + + if (de->d_type != DT_DIR) + continue; + + /* As commented in the above, this is called when no worker exists, hence the file is not + * locked. On a later uevent, the lock file will be created if necessary. So, we can safely + * remove the file now. */ + lockfile = path_join(de->d_name, ".lock"); + if (!lockfile) + return log_oom_debug(); + + if (unlinkat(dirfd(dir), lockfile, 0) < 0 && errno != ENOENT) { + log_debug_errno(errno, "Failed to remove '/run/udev/links/%s', ignoring: %m", lockfile); + continue; + } + + if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0 && errno != ENOTEMPTY) + log_debug_errno(errno, "Failed to remove '/run/udev/links/%s', ignoring: %m", de->d_name); + } + + return 0; +} + static int node_symlink(sd_device *dev, const char *devnode, const char *slink) { _cleanup_free_ char *target = NULL; const char *id, *slink_tmp; diff --git a/src/udev/udev-node.h b/src/udev/udev-node.h index 86a829545a..0c545e4a0f 100644 --- a/src/udev/udev-node.h +++ b/src/udev/udev-node.h @@ -24,5 +24,6 @@ int static_node_apply_permissions( int udev_node_remove(sd_device *dev); int udev_node_update(sd_device *dev, sd_device *dev_old); +int udev_node_cleanup(void); size_t udev_node_escape_path(const char *src, char *dest, size_t size); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index b179dfac37..c519e19897 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -65,6 +65,7 @@ #include "udev-builtin.h" #include "udev-ctrl.h" #include "udev-event.h" +#include "udev-node.h" #include "udev-util.h" #include "udev-watch.h" #include "user-util.h" @@ -111,6 +112,7 @@ typedef struct Manager { usec_t last_usec; + bool udev_node_needs_cleanup; bool stop_exec_queue; bool exit; } Manager; @@ -976,6 +978,9 @@ static int event_queue_start(Manager *manager) { if (!manager->events || manager->exit || manager->stop_exec_queue) return 0; + /* To make the stack directory /run/udev/links cleaned up later. */ + manager->udev_node_needs_cleanup = true; + r = event_source_disable(manager->kill_workers_event); if (r < 0) log_warning_errno(r, "Failed to disable event source for cleaning up idle workers, ignoring: %m"); @@ -1607,6 +1612,11 @@ static int on_post(sd_event_source *s, void *userdata) { /* There are no idle workers. */ + if (manager->udev_node_needs_cleanup) { + (void) udev_node_cleanup(); + manager->udev_node_needs_cleanup = false; + } + if (manager->exit) return sd_event_exit(manager->event, 0); |