mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 19:21:53 +03:00
manager: introduce unit path cache to minimize disk accesses
This commit is contained in:
parent
9014a8bd7a
commit
fe51822e71
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user