290 lines
11 KiB
Diff
290 lines
11 KiB
Diff
From 91e0ee5f16321656ed6f827742ecbeb2b36027f2 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
Date: Wed, 10 Jul 2019 18:01:13 +0200
|
|
Subject: [PATCH] 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.
|
|
|
|
revert pid1 drop unit caches only based on mtime
|
|
---
|
|
src/analyze/analyze.c | 2 +-
|
|
src/core/load-fragment.c | 9 --------
|
|
src/core/manager.c | 14 ++++++++++--
|
|
src/core/manager.h | 1 -
|
|
src/shared/unit-file.c | 57 +----------------------------------------------
|
|
src/shared/unit-file.h | 2 --
|
|
src/systemctl/systemctl.c | 2 +-
|
|
src/test/test-unit-file.c | 13 +----------
|
|
8 files changed, 16 insertions(+), 84 deletions(-)
|
|
|
|
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
|
|
index 4d81026..322be1a 100644
|
|
--- a/src/analyze/analyze.c
|
|
+++ b/src/analyze/analyze.c
|
|
@@ -1569,7 +1569,7 @@ static int do_unit_files(int argc, char *argv[], void *userdata) {
|
|
if (r < 0)
|
|
return log_error_errno(r, "lookup_paths_init() failed: %m");
|
|
|
|
- r = unit_file_build_name_map(&lp, NULL, &unit_ids, &unit_names, NULL);
|
|
+ r = unit_file_build_name_map(&lp, &unit_ids, &unit_names, NULL);
|
|
if (r < 0)
|
|
return log_error_errno(r, "unit_file_build_name_map() failed: %m");
|
|
|
|
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
|
index 8eaf8b3..9821a92 100644
|
|
--- a/src/core/load-fragment.c
|
|
+++ b/src/core/load-fragment.c
|
|
@@ -4605,15 +4605,6 @@ int unit_load_fragment(Unit *u) {
|
|
return 0;
|
|
}
|
|
|
|
- /* Possibly rebuild the fragment map to catch new units */
|
|
- r = unit_file_build_name_map(&u->manager->lookup_paths,
|
|
- &u->manager->unit_cache_mtime,
|
|
- &u->manager->unit_id_map,
|
|
- &u->manager->unit_name_map,
|
|
- &u->manager->unit_path_cache);
|
|
- if (r < 0)
|
|
- log_error_errno(r, "Failed to rebuild name map: %m");
|
|
-
|
|
r = unit_file_find_fragment(u->manager->unit_id_map,
|
|
u->manager->unit_name_map,
|
|
u->id,
|
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
|
index 5efcf45..8b1ce70 100644
|
|
--- a/src/core/manager.c
|
|
+++ b/src/core/manager.c
|
|
@@ -693,7 +693,6 @@ static void manager_free_unit_name_maps(Manager *m) {
|
|
m->unit_id_map = hashmap_free(m->unit_id_map);
|
|
m->unit_name_map = hashmap_free(m->unit_name_map);
|
|
m->unit_path_cache = set_free_free(m->unit_path_cache);
|
|
- m->unit_cache_mtime = 0;
|
|
}
|
|
|
|
static int manager_setup_run_queue(Manager *m) {
|
|
@@ -1642,6 +1641,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
|
|
|
|
lookup_paths_log(&m->lookup_paths);
|
|
|
|
+ manager_free_unit_name_maps(m);
|
|
+ r = unit_file_build_name_map(&m->lookup_paths, &m->unit_id_map, &m->unit_name_map, &m->unit_path_cache);
|
|
+ if (r < 0)
|
|
+ return log_error_errno(r, "Failed to build name map: %m");
|
|
+
|
|
{
|
|
/* This block is (optionally) done with the reloading counter bumped */
|
|
_cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
|
|
@@ -2858,6 +2862,10 @@ int manager_loop(Manager *m) {
|
|
assert(m);
|
|
assert(m->objective == MANAGER_OK); /* Ensure manager_startup() has been called */
|
|
|
|
+ /* Release the path and unit name caches */
|
|
+ manager_free_unit_name_maps(m);
|
|
+ // FIXME: once this happens, we cannot load any more units
|
|
+
|
|
manager_check_finished(m);
|
|
|
|
/* There might still be some zombies hanging around from before we were exec()'ed. Let's reap them. */
|
|
@@ -3531,8 +3539,10 @@ int manager_reload(Manager *m) {
|
|
|
|
lookup_paths_log(&m->lookup_paths);
|
|
|
|
- /* We flushed out generated files, for which we don't watch mtime, so we should flush the old map. */
|
|
manager_free_unit_name_maps(m);
|
|
+ r = unit_file_build_name_map(&m->lookup_paths, &m->unit_id_map, &m->unit_name_map, &m->unit_path_cache);
|
|
+ if (r < 0)
|
|
+ log_warning_errno(r, "Failed to build name map: %m");
|
|
|
|
/* First, enumerate what we can from kernel and suchlike */
|
|
manager_enumerate_perpetual(m);
|
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
|
index 815c5ec..9ca82ac 100644
|
|
--- a/src/core/manager.h
|
|
+++ b/src/core/manager.h
|
|
@@ -223,7 +223,6 @@ struct Manager {
|
|
Hashmap *unit_id_map;
|
|
Hashmap *unit_name_map;
|
|
Set *unit_path_cache;
|
|
- usec_t unit_cache_mtime;
|
|
|
|
char **transient_environment; /* The environment, as determined from config files, kernel cmdline and environment generators */
|
|
char **client_environment; /* Environment variables created by clients through the bus API */
|
|
diff --git a/src/shared/unit-file.c b/src/shared/unit-file.c
|
|
index 4a5f23e..bad92a3 100644
|
|
--- a/src/shared/unit-file.c
|
|
+++ b/src/shared/unit-file.c
|
|
@@ -152,47 +152,8 @@ 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) {
|
|
@@ -210,12 +171,6 @@ 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);
|
|
@@ -226,7 +181,6 @@ 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) {
|
|
@@ -235,13 +189,6 @@ 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_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
|
|
char *filename;
|
|
_cleanup_free_ char *_filename_free = NULL, *simplified = NULL;
|
|
@@ -378,14 +325,12 @@ 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 1;
|
|
+ return 0;
|
|
}
|
|
|
|
int unit_file_find_fragment(
|
|
diff --git a/src/shared/unit-file.h b/src/shared/unit-file.h
|
|
index 54cc787..52e17f7 100644
|
|
--- a/src/shared/unit-file.h
|
|
+++ b/src/shared/unit-file.h
|
|
@@ -4,7 +4,6 @@
|
|
#include <stdbool.h>
|
|
|
|
#include "hashmap.h"
|
|
-#include "time-util.h"
|
|
#include "unit-name.h"
|
|
|
|
typedef enum UnitFileState UnitFileState;
|
|
@@ -43,7 +42,6 @@ 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);
|
|
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
|
index dcf76be..69063ee 100644
|
|
--- a/src/systemctl/systemctl.c
|
|
+++ b/src/systemctl/systemctl.c
|
|
@@ -2594,7 +2594,7 @@ static int unit_find_paths(
|
|
_cleanup_set_free_free_ Set *names = NULL;
|
|
|
|
if (!cached_name_map) {
|
|
- r = unit_file_build_name_map(lp, NULL, &cached_id_map, &cached_name_map, NULL);
|
|
+ r = unit_file_build_name_map(lp, &cached_id_map, &cached_name_map, NULL);
|
|
if (r < 0)
|
|
return r;
|
|
}
|
|
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
|
|
index 8bc5bf6..988ac15 100644
|
|
--- a/src/test/test-unit-file.c
|
|
+++ b/src/test/test-unit-file.c
|
|
@@ -32,12 +32,10 @@ static void test_unit_file_build_name_map(char **ids) {
|
|
Iterator i;
|
|
const char *k, *dst;
|
|
char **v;
|
|
- usec_t mtime = 0;
|
|
- int r;
|
|
|
|
assert_se(lookup_paths_init(&lp, UNIT_FILE_SYSTEM, 0, NULL) >= 0);
|
|
|
|
- assert_se(unit_file_build_name_map(&lp, &mtime, &unit_ids, &unit_names, NULL) == 1);
|
|
+ assert_se(unit_file_build_name_map(&lp, &unit_ids, &unit_names, NULL) == 0);
|
|
|
|
HASHMAP_FOREACH_KEY(dst, k, unit_ids, i)
|
|
log_info("ids: %s → %s", k, dst);
|
|
@@ -47,15 +45,6 @@ static void test_unit_file_build_name_map(char **ids) {
|
|
log_info("aliases: %s ← %s", k, j);
|
|
}
|
|
|
|
- char buf[FORMAT_TIMESTAMP_MAX];
|
|
- log_debug("Last modification time: %s", format_timestamp(buf, sizeof buf, mtime));
|
|
-
|
|
- r = unit_file_build_name_map(&lp, &mtime, &unit_ids, &unit_names, NULL);
|
|
- assert_se(IN_SET(r, 0, 1));
|
|
- if (r == 0)
|
|
- log_debug("Cache rebuild skipped based on mtime.");
|
|
-
|
|
-
|
|
char **id;
|
|
STRV_FOREACH(id, ids) {
|
|
const char *fragment, *name;
|
|
--
|
|
1.8.3.1
|
|
|