Commit fe51822e authored by Lennart Poettering's avatar Lennart Poettering
Browse files

manager: introduce unit path cache to minimize disk accesses

parent 9014a8bd
......@@ -84,7 +84,11 @@ int unit_load_dropin(Unit *u) {
if (asprintf(&path, "%s/%s.wants", *p, t) < 0)
return -ENOMEM;
r = iterate_dir(u, path);
if (u->meta.manager->unit_path_cache &&
!set_get(u->meta.manager->unit_path_cache, path))
r = 0;
else
r = iterate_dir(u, path);
free(path);
if (r < 0)
......@@ -103,7 +107,11 @@ int unit_load_dropin(Unit *u) {
if (r < 0)
return -ENOMEM;
r = iterate_dir(u, path);
if (u->meta.manager->unit_path_cache &&
!set_get(u->meta.manager->unit_path_cache, path))
r = 0;
else
r = iterate_dir(u, path);
free(path);
if (r < 0)
......
......@@ -1690,7 +1690,13 @@ static int load_from_path(Unit *u, const char *path) {
goto finish;
}
if ((r = open_follow(&filename, &f, symlink_names, &id)) < 0) {
if (u->meta.manager->unit_path_cache &&
!set_get(u->meta.manager->unit_path_cache, filename))
r = -ENOENT;
else
r = open_follow(&filename, &f, symlink_names, &id);
if (r < 0) {
char *sn;
free(filename);
......
......@@ -36,6 +36,7 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include "manager.h"
#include "hashmap.h"
......@@ -478,11 +479,71 @@ int manager_coldplug(Manager *m) {
return r;
}
static void manager_build_unit_path_cache(Manager *m) {
char **i;
DIR *d = NULL;
int r;
assert(m);
set_free_free(m->unit_path_cache);
if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
log_error("Failed to allocate unit path cache.");
return;
}
/* This simply builds a list of files we know exist, so that
* we don't always have to go to disk */
STRV_FOREACH(i, m->lookup_paths.unit_path) {
struct dirent *de;
if (!(d = opendir(*i))) {
log_error("Failed to open directory: %m");
continue;
}
while ((de = readdir(d))) {
char *p;
if (ignore_file(de->d_name))
continue;
if (asprintf(&p, "%s/%s", streq(*i, "/") ? "" : *i, de->d_name) < 0) {
r = -ENOMEM;
goto fail;
}
if ((r = set_put(m->unit_path_cache, p)) < 0) {
free(p);
goto fail;
}
}
closedir(d);
d = NULL;
}
return;
fail:
log_error("Failed to build unit path cache: %s", strerror(-r));
set_free_free(m->unit_path_cache);
m->unit_path_cache = NULL;
if (d)
closedir(d);
}
int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
int r, q;
assert(m);
manager_build_unit_path_cache(m);
/* First, enumerate what we can from all config files */
r = manager_enumerate(m);
......@@ -1993,6 +2054,10 @@ int manager_loop(Manager *m) {
assert(m);
m->exit_code = MANAGER_RUNNING;
/* Release the path cache */
set_free_free(m->unit_path_cache);
m->unit_path_cache = NULL;
/* There might still be some zombies hanging around from
* before we were exec()'ed. Leat's reap them */
if ((r = manager_dispatch_sigchld(m)) < 0)
......
......@@ -134,6 +134,7 @@ struct Manager {
unsigned n_snapshots;
LookupPaths lookup_paths;
Set *unit_path_cache;
char **environment;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment