X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fload-dropin.c;h=d869ee0c7650cd347d840be325433574e82aa873;hp=bdf3dd2c2e36f3f1e7a844a7e904425650ba296a;hb=ac155bb885f9ea8aac3979a6b2686f0c8a9cc6e3;hpb=84e3543ef4c4758621f8a304b14642072303ef82 diff --git a/src/load-dropin.c b/src/load-dropin.c index bdf3dd2c2..d869ee0c7 100644 --- a/src/load-dropin.c +++ b/src/load-dropin.c @@ -1,4 +1,4 @@ -/*-*- Mode: C; c-basic-offset: 8 -*-*/ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ /*** This file is part of systemd. @@ -28,12 +28,16 @@ #include "strv.h" #include "unit-name.h" -static int iterate_dir(Unit *u, const char *path) { +static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { DIR *d; struct dirent *de; int r; - if (!(d = opendir(path))) { + assert(u); + assert(path); + + d = opendir(path); + if (!d) { if (errno == ENOENT) return 0; @@ -47,16 +51,17 @@ static int iterate_dir(Unit *u, const char *path) { if (ignore_file(de->d_name)) continue; - if (asprintf(&f, "%s/%s", path, de->d_name) < 0) { + f = join(path, "/", de->d_name, NULL); + if (!f) { r = -ENOMEM; goto finish; } - r = unit_add_dependency_by_name(u, UNIT_WANTS, de->d_name, f, true); + r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true); free(f); if (r < 0) - goto finish; + log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r)); } r = 0; @@ -66,50 +71,78 @@ finish: return r; } -int unit_load_dropin(Unit *u) { - Iterator i; +static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) { int r; - char *t; + char *path; assert(u); + assert(unit_path); + assert(name); + assert(suffix); - /* Load dependencies from supplementary drop-in directories */ + path = join(unit_path, "/", name, suffix, NULL); + if (!path) + return -ENOMEM; - SET_FOREACH(t, u->meta.names, i) { - char *path; - char **p; + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); - STRV_FOREACH(p, u->meta.manager->lookup_paths.unit_path) { + if (r < 0) + return r; - if (asprintf(&path, "%s/%s.wants", *p, t) < 0) - return -ENOMEM; + if (u->instance) { + char *template; + /* Also try the template dir */ - r = iterate_dir(u, path); - free(path); + template = unit_name_template(name); + if (!template) + return -ENOMEM; - if (r < 0) - return r; + path = join(unit_path, "/", template, suffix, NULL); + free(template); + + if (!path) + return -ENOMEM; + + if (u->manager->unit_path_cache && + !set_get(u->manager->unit_path_cache, path)) + r = 0; + else + r = iterate_dir(u, path, dependency); + free(path); + + if (r < 0) + return r; + } + + return 0; +} - if (u->meta.instance) { - char *template; - /* Also try the template dir */ +int unit_load_dropin(Unit *u) { + Iterator i; + char *t; - if (!(template = unit_name_template(t))) - return -ENOMEM; + assert(u); - r = asprintf(&path, "%s/%s.wants", *p, template); - free(template); + /* Load dependencies from supplementary drop-in directories */ - if (r < 0) - return -ENOMEM; + SET_FOREACH(t, u->names, i) { + char **p; - r = iterate_dir(u, path); - free(path); + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + int r; - if (r < 0) - return r; - } + r = process_dir(u, *p, t, ".wants", UNIT_WANTS); + if (r < 0) + return r; + r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES); + if (r < 0) + return r; } }