Skip to content

Commit

Permalink
udev: cleanup stack directory /run/udev/links when all workers exited
Browse files Browse the repository at this point in the history
By the previous commit, the stack directories are not removed event it
it is empty. To reduce the inode usage of /run, let's cleanup the
directories.
  • Loading branch information
yuwata committed Apr 12, 2022
1 parent 633a7ad commit 02952ad
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/udev/udev-node.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,34 @@

#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 be called when no worker exists. Otherwise, it causes an 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) {
if (de->d_name[0] == '.')
continue;

if (de->d_type != DT_DIR)
continue;

if (unlinkat(dirfd(dir), de->d_name, AT_REMOVEDIR) < 0 && errno != ENOTEMPTY)
log_debug_errno(errno, "Failed to remove directory '/run/udev/links/%s', ignoring: %m", de->d_name);
}

return 0;
}

static int create_symlink(const char *target, const char *slink) {
int r;

Expand Down
1 change: 1 addition & 0 deletions src/udev/udev-node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
10 changes: 10 additions & 0 deletions src/udev/udevd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -111,6 +112,7 @@ typedef struct Manager {

usec_t last_usec;

bool udev_node_needs_cleanup;
bool stop_exec_queue;
bool exit;
} Manager;
Expand Down Expand Up @@ -1188,6 +1190,9 @@ static int on_uevent(sd_device_monitor *monitor, sd_device *dev, void *userdata)

(void) event_queue_assume_block_device_unlocked(manager, dev);

/* To make the stack directory /run/udev/links cleaned up later. */
manager->udev_node_needs_cleanup = true;

/* we have fresh events, try to schedule them */
event_queue_start(manager);

Expand Down Expand Up @@ -1642,6 +1647,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);

Expand Down

0 comments on commit 02952ad

Please sign in to comment.