LCOV - code coverage report
Current view: top level - core - load-dropin.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 26 70 37.1 %
Date: 2019-08-22 15:41:25 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include "conf-parser.h"
       4             : #include "fs-util.h"
       5             : #include "load-dropin.h"
       6             : #include "load-fragment.h"
       7             : #include "log.h"
       8             : #include "stat-util.h"
       9             : #include "string-util.h"
      10             : #include "strv.h"
      11             : #include "unit-name.h"
      12             : #include "unit.h"
      13             : 
      14           0 : static int unit_name_compatible(const char *a, const char *b) {
      15           0 :         _cleanup_free_ char *template = NULL;
      16             :         int r;
      17             : 
      18             :         /* The straightforward case: the symlink name matches the target */
      19           0 :         if (streq(a, b))
      20           0 :                 return 1;
      21             : 
      22           0 :         r = unit_name_template(a, &template);
      23           0 :         if (r == -EINVAL)
      24           0 :                 return 0; /* Not a template */
      25           0 :         if (r < 0)
      26           0 :                 return r; /* OOM, or some other failure. Just skip the warning. */
      27             : 
      28             :         /* An instance name points to a target that is just the template name */
      29           0 :         return streq(template, b);
      30             : }
      31             : 
      32        3586 : static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suffix) {
      33        3586 :         _cleanup_strv_free_ char **paths = NULL;
      34             :         char **p;
      35             :         int r;
      36             : 
      37        7172 :         r = unit_file_find_dropin_paths(NULL,
      38        3586 :                                         u->manager->lookup_paths.search_path,
      39        3586 :                                         u->manager->unit_path_cache,
      40             :                                         dir_suffix,
      41             :                                         NULL,
      42        3586 :                                         u->names,
      43             :                                         &paths);
      44        3586 :         if (r < 0)
      45           0 :                 return r;
      46             : 
      47        3586 :         STRV_FOREACH(p, paths) {
      48           0 :                 _cleanup_free_ char *target = NULL;
      49             :                 const char *entry;
      50             : 
      51           0 :                 entry = basename(*p);
      52             : 
      53           0 :                 if (null_or_empty_path(*p) > 0) {
      54             :                         /* an error usually means an invalid symlink, which is not a mask */
      55           0 :                         log_unit_debug(u, "%s dependency on %s is masked by %s, ignoring.",
      56             :                                        unit_dependency_to_string(dependency), entry, *p);
      57           0 :                         continue;
      58             :                 }
      59             : 
      60           0 :                 r = is_symlink(*p);
      61           0 :                 if (r < 0) {
      62           0 :                         log_unit_warning_errno(u, r, "%s dropin %s unreadable, ignoring: %m",
      63             :                                                unit_dependency_to_string(dependency), *p);
      64           0 :                         continue;
      65             :                 }
      66           0 :                 if (r == 0) {
      67           0 :                         log_unit_warning(u, "%s dependency dropin %s is not a symlink, ignoring.",
      68             :                                          unit_dependency_to_string(dependency), *p);
      69           0 :                         continue;
      70             :                 }
      71             : 
      72           0 :                 if (!unit_name_is_valid(entry, UNIT_NAME_ANY)) {
      73           0 :                         log_unit_warning(u, "%s dependency dropin %s is not a valid unit name, ignoring.",
      74             :                                          unit_dependency_to_string(dependency), *p);
      75           0 :                         continue;
      76             :                 }
      77             : 
      78           0 :                 r = readlink_malloc(*p, &target);
      79           0 :                 if (r < 0) {
      80           0 :                         log_unit_warning_errno(u, r, "readlink(\"%s\") failed, ignoring: %m", *p);
      81           0 :                         continue;
      82             :                 }
      83             : 
      84             :                 /* We don't treat this as an error, especially because we didn't check this for a
      85             :                  * long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
      86           0 :                 r = unit_name_compatible(entry, basename(target));
      87           0 :                 if (r < 0) {
      88           0 :                         log_unit_warning_errno(u, r, "Can't check if names %s and %s are compatible, ignoring: %m", entry, basename(target));
      89           0 :                         continue;
      90             :                 }
      91           0 :                 if (r == 0)
      92           0 :                         log_unit_warning(u, "%s dependency dropin %s target %s has different name",
      93             :                                          unit_dependency_to_string(dependency), *p, target);
      94             : 
      95           0 :                 r = unit_add_dependency_by_name(u, dependency, entry, true, UNIT_DEPENDENCY_FILE);
      96           0 :                 if (r < 0)
      97           0 :                         log_unit_warning_errno(u, r, "Cannot add %s dependency on %s, ignoring: %m",
      98             :                                                unit_dependency_to_string(dependency), entry);
      99             :         }
     100             : 
     101        3586 :         return 0;
     102             : }
     103             : 
     104        1793 : int unit_load_dropin(Unit *u) {
     105        1793 :         _cleanup_strv_free_ char **l = NULL;
     106             :         char **f;
     107             :         int r;
     108             : 
     109        1793 :         assert(u);
     110             : 
     111             :         /* Load dependencies from .wants and .requires directories */
     112        1793 :         r = process_deps(u, UNIT_WANTS, ".wants");
     113        1793 :         if (r < 0)
     114           0 :                 return r;
     115             : 
     116        1793 :         r = process_deps(u, UNIT_REQUIRES, ".requires");
     117        1793 :         if (r < 0)
     118           0 :                 return r;
     119             : 
     120             :         /* Load .conf dropins */
     121        1793 :         r = unit_find_dropin_paths(u, &l);
     122        1793 :         if (r <= 0)
     123        1792 :                 return 0;
     124             : 
     125           1 :         if (!u->dropin_paths)
     126           1 :                 u->dropin_paths = TAKE_PTR(l);
     127             :         else {
     128           0 :                 r = strv_extend_strv(&u->dropin_paths, l, true);
     129           0 :                 if (r < 0)
     130           0 :                         return log_oom();
     131             :         }
     132             : 
     133           4 :         STRV_FOREACH(f, u->dropin_paths)
     134           3 :                 (void) config_parse(u->id, *f, NULL,
     135           3 :                                     UNIT_VTABLE(u)->sections,
     136             :                                     config_item_perf_lookup, load_fragment_gperf_lookup,
     137             :                                     0, u);
     138             : 
     139           1 :         u->dropin_mtime = now(CLOCK_REALTIME);
     140             : 
     141           1 :         return 0;
     142             : }

Generated by: LCOV version 1.14