summaryrefslogtreecommitdiff
path: root/src/manager.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-07-11 00:52:00 +0200
committerLennart Poettering <lennart@poettering.net>2010-07-11 00:52:00 +0200
commitfe51822e7120e89566cf76278d0b78ec7db4b43a (patch)
treed54f08b88805dee5604b3dc8d23a67edd956b466 /src/manager.c
parent9014a8bd7a88aa4794b730e7fccf7838a00ad351 (diff)
manager: introduce unit path cache to minimize disk accesses
Diffstat (limited to 'src/manager.c')
-rw-r--r--src/manager.c65
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)