diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-07-11 00:52:00 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-07-11 00:52:00 +0200 |
commit | fe51822e7120e89566cf76278d0b78ec7db4b43a (patch) | |
tree | d54f08b88805dee5604b3dc8d23a67edd956b466 /src/manager.c | |
parent | 9014a8bd7a88aa4794b730e7fccf7838a00ad351 (diff) |
manager: introduce unit path cache to minimize disk accesses
Diffstat (limited to 'src/manager.c')
-rw-r--r-- | src/manager.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/manager.c b/src/manager.c index a7e24eb812..5125db2e9a 100644 --- a/src/manager.c +++ b/src/manager.c @@ -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) |