pid1: drop unit caches only based on mtime
v2: - do not watch mtime of transient and generated dirs We'd reload the map after every transient unit we created, which we don't need to do, since we create those units ourselves and know their fragment path.
This commit is contained in:
+56
-1
@@ -152,8 +152,47 @@ static int unit_ids_map_get(
|
||||
return -ELOOP;
|
||||
}
|
||||
|
||||
static bool lookup_paths_mtime_exclude(const LookupPaths *lp, const char *path) {
|
||||
/* Paths that are under our exclusive control. Users shall not alter those directly. */
|
||||
|
||||
return streq_ptr(path, lp->generator) ||
|
||||
streq_ptr(path, lp->generator_early) ||
|
||||
streq_ptr(path, lp->generator_late) ||
|
||||
streq_ptr(path, lp->transient) ||
|
||||
streq_ptr(path, lp->persistent_control) ||
|
||||
streq_ptr(path, lp->runtime_control);
|
||||
}
|
||||
|
||||
static bool lookup_paths_mtime_good(const LookupPaths *lp, usec_t mtime) {
|
||||
char **dir;
|
||||
|
||||
STRV_FOREACH(dir, (char**) lp->search_path) {
|
||||
struct stat st;
|
||||
|
||||
if (lookup_paths_mtime_exclude(lp, *dir))
|
||||
continue;
|
||||
|
||||
/* Determine the latest lookup path modification time */
|
||||
if (stat(*dir, &st) < 0) {
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
|
||||
log_debug_errno(errno, "Failed to stat %s, ignoring: %m", *dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (timespec_load(&st.st_mtim) > mtime) {
|
||||
log_debug_errno(errno, "Unit dir %s has changed, need to update cache.", *dir);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int unit_file_build_name_map(
|
||||
const LookupPaths *lp,
|
||||
usec_t *cache_mtime,
|
||||
Hashmap **ret_unit_ids_map,
|
||||
Hashmap **ret_unit_names_map,
|
||||
Set **ret_path_cache) {
|
||||
@@ -171,6 +210,12 @@ int unit_file_build_name_map(
|
||||
_cleanup_set_free_free_ Set *paths = NULL;
|
||||
char **dir;
|
||||
int r;
|
||||
usec_t mtime = 0;
|
||||
|
||||
/* Before doing anything, check if the mtime that was passed is still valid. If
|
||||
* yes, do nothing. If *cache_time == 0, always build the cache. */
|
||||
if (cache_mtime && *cache_mtime > 0 && lookup_paths_mtime_good(lp, *cache_mtime))
|
||||
return 0;
|
||||
|
||||
if (ret_path_cache) {
|
||||
paths = set_new(&path_hash_ops);
|
||||
@@ -181,6 +226,7 @@ int unit_file_build_name_map(
|
||||
STRV_FOREACH(dir, (char**) lp->search_path) {
|
||||
struct dirent *de;
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
struct stat st;
|
||||
|
||||
d = opendir(*dir);
|
||||
if (!d) {
|
||||
@@ -189,6 +235,13 @@ int unit_file_build_name_map(
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Determine the latest lookup path modification time */
|
||||
if (fstat(dirfd(d), &st) < 0)
|
||||
return log_error_errno(errno, "Failed to fstat %s: %m", *dir);
|
||||
|
||||
if (!lookup_paths_mtime_exclude(lp, *dir))
|
||||
mtime = MAX(mtime, timespec_load(&st.st_mtim));
|
||||
|
||||
FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
|
||||
char *filename;
|
||||
_cleanup_free_ char *_filename_free = NULL, *simplified = NULL;
|
||||
@@ -316,12 +369,14 @@ int unit_file_build_name_map(
|
||||
basename(dst), src);
|
||||
}
|
||||
|
||||
if (cache_mtime)
|
||||
*cache_mtime = mtime;
|
||||
*ret_unit_ids_map = TAKE_PTR(ids);
|
||||
*ret_unit_names_map = TAKE_PTR(names);
|
||||
if (ret_path_cache)
|
||||
*ret_path_cache = TAKE_PTR(paths);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int unit_file_find_fragment(
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "hashmap.h"
|
||||
#include "time-util.h"
|
||||
#include "unit-name.h"
|
||||
|
||||
typedef enum UnitFileState UnitFileState;
|
||||
@@ -42,6 +43,7 @@ int unit_validate_alias_symlink_and_warn(const char *filename, const char *targe
|
||||
|
||||
int unit_file_build_name_map(
|
||||
const LookupPaths *lp,
|
||||
usec_t *ret_time,
|
||||
Hashmap **ret_unit_ids_map,
|
||||
Hashmap **ret_unit_names_map,
|
||||
Set **ret_path_cache);
|
||||
|
||||
Reference in New Issue
Block a user