diff options
author | Michael Biebl <biebl@debian.org> | 2017-10-10 00:22:57 +0200 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2017-10-10 00:22:57 +0200 |
commit | f5e65279187b6aa0c0c5a00b14dca9eab441ffb2 (patch) | |
tree | b834735b2b8fabf24499bb8cc12d4f24870436f7 /src/shared/install.c | |
parent | 81c583552ee1c3355cdef1b11a33737dd98e6971 (diff) | |
download | systemd-f5e65279187b6aa0c0c5a00b14dca9eab441ffb2.tar.gz |
New upstream version 235
Diffstat (limited to 'src/shared/install.c')
-rw-r--r-- | src/shared/install.c | 127 |
1 files changed, 100 insertions, 27 deletions
diff --git a/src/shared/install.c b/src/shared/install.c index d0a291b819..7598bf6a23 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -83,6 +83,20 @@ typedef struct { size_t n_rules; } Presets; +static inline bool unit_file_install_info_has_rules(UnitFileInstallInfo *i) { + assert(i); + + return !strv_isempty(i->aliases) || + !strv_isempty(i->wanted_by) || + !strv_isempty(i->required_by); +} + +static inline bool unit_file_install_info_has_also(UnitFileInstallInfo *i) { + assert(i); + + return !strv_isempty(i->also); +} + static inline void presets_freep(Presets *p) { size_t i; @@ -272,7 +286,7 @@ static int path_is_vendor(const LookupPaths *p, const char *path) { if (path_startswith(rpath, "/usr")) return true; -#ifdef HAVE_SPLIT_USR +#if HAVE_SPLIT_USR if (path_startswith(rpath, "/lib")) return true; #endif @@ -685,9 +699,35 @@ static int remove_marked_symlinks( return r; } +static bool is_symlink_with_known_name(const UnitFileInstallInfo *i, const char *name) { + int r; + + if (streq(name, i->name)) + return true; + + if (strv_contains(i->aliases, name)) + return true; + + /* Look for template symlink matching DefaultInstance */ + if (i->default_instance && unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE)) { + _cleanup_free_ char *s = NULL; + + r = unit_name_replace_instance(i->name, i->default_instance, &s); + if (r < 0) { + if (r != -EINVAL) + return r; + + } else if (streq(name, s)) + return true; + } + + return false; +} + static int find_symlinks_fd( const char *root_dir, - const char *name, + UnitFileInstallInfo *i, + bool match_aliases, int fd, const char *path, const char *config_path, @@ -697,7 +737,7 @@ static int find_symlinks_fd( struct dirent *de; int r = 0; - assert(name); + assert(i); assert(fd >= 0); assert(path); assert(config_path); @@ -734,7 +774,8 @@ static int find_symlinks_fd( } /* This will close nfd, regardless whether it succeeds or not */ - q = find_symlinks_fd(root_dir, name, nfd, p, config_path, same_name_link); + q = find_symlinks_fd(root_dir, i, match_aliases, nfd, + p, config_path, same_name_link); if (q > 0) return 1; if (r == 0) @@ -774,24 +815,24 @@ static int find_symlinks_fd( /* Check if the symlink itself matches what we * are looking for */ - if (path_is_absolute(name)) - found_path = path_equal(p, name); + if (path_is_absolute(i->name)) + found_path = path_equal(p, i->name); else - found_path = streq(de->d_name, name); + found_path = streq(de->d_name, i->name); /* Check if what the symlink points to * matches what we are looking for */ - if (path_is_absolute(name)) - found_dest = path_equal(dest, name); + if (path_is_absolute(i->name)) + found_dest = path_equal(dest, i->name); else - found_dest = streq(basename(dest), name); + found_dest = streq(basename(dest), i->name); if (found_path && found_dest) { _cleanup_free_ char *t = NULL; /* Filter out same name links in the main * config path */ - t = path_make_absolute(name, config_path); + t = path_make_absolute(i->name, config_path); if (!t) return -ENOMEM; @@ -800,8 +841,17 @@ static int find_symlinks_fd( if (b) *same_name_link = true; - else if (found_path || found_dest) - return 1; + else if (found_path || found_dest) { + if (!match_aliases) + return 1; + + /* Check if symlink name is in the set of names used by [Install] */ + q = is_symlink_with_known_name(i, de->d_name); + if (q < 0) + return q; + if (q > 0) + return 1; + } } } @@ -810,13 +860,14 @@ static int find_symlinks_fd( static int find_symlinks( const char *root_dir, - const char *name, + UnitFileInstallInfo *i, + bool match_name, const char *config_path, bool *same_name_link) { int fd; - assert(name); + assert(i); assert(config_path); assert(same_name_link); @@ -828,12 +879,15 @@ static int find_symlinks( } /* This takes possession of fd and closes it */ - return find_symlinks_fd(root_dir, name, fd, config_path, config_path, same_name_link); + return find_symlinks_fd(root_dir, i, match_name, fd, + config_path, config_path, same_name_link); } static int find_symlinks_in_scope( + UnitFileScope scope, const LookupPaths *paths, - const char *name, + UnitFileInstallInfo *i, + bool match_name, UnitFileState *state) { bool same_name_link_runtime = false, same_name_link_config = false; @@ -842,12 +896,12 @@ static int find_symlinks_in_scope( int r; assert(paths); - assert(name); + assert(i); STRV_FOREACH(p, paths->search_path) { bool same_name_link = false; - r = find_symlinks(paths->root_dir, name, *p, &same_name_link); + r = find_symlinks(paths->root_dir, i, match_name, *p, &same_name_link); if (r < 0) return r; if (r > 0) { @@ -862,6 +916,12 @@ static int find_symlinks_in_scope( return 1; } + /* look for globally enablement of user units */ + if (scope == UNIT_FILE_USER && path_is_user_config_dir(*p)) { + *state = UNIT_FILE_ENABLED; + return 1; + } + r = path_is_runtime(paths, *p, false); if (r < 0) return r; @@ -896,7 +956,7 @@ static int find_symlinks_in_scope( * outside of runtime and configuration directory, then we consider it statically enabled. Note we do that only * for instance, not for regular names, as those are merely aliases, while instances explicitly instantiate * something, and hence are a much stronger concept. */ - if (enabled_at_all && unit_name_is_valid(name, UNIT_NAME_INSTANCE)) { + if (enabled_at_all && unit_name_is_valid(i->name, UNIT_NAME_INSTANCE)) { *state = UNIT_FILE_STATIC; return 1; } @@ -2589,13 +2649,26 @@ static int unit_file_lookup_state( break; } - r = find_symlinks_in_scope(paths, i->name, &state); + /* Check if any of the Alias= symlinks have been created. + * We ignore other aliases, and only check those that would + * be created by systemctl enable for this unit. */ + r = find_symlinks_in_scope(scope, paths, i, true, &state); + if (r < 0) + return r; + if (r > 0) + break; + + /* Check if the file is known under other names. If it is, + * it might be in use. Report that as UNIT_FILE_INDIRECT. */ + r = find_symlinks_in_scope(scope, paths, i, false, &state); if (r < 0) return r; - if (r == 0) { - if (UNIT_FILE_INSTALL_INFO_HAS_RULES(i)) + if (r > 0) + state = UNIT_FILE_INDIRECT; + else { + if (unit_file_install_info_has_rules(i)) state = UNIT_FILE_DISABLED; - else if (UNIT_FILE_INSTALL_INFO_HAS_ALSO(i)) + else if (unit_file_install_info_has_also(i)) state = UNIT_FILE_INDIRECT; else state = UNIT_FILE_STATIC; @@ -2662,16 +2735,16 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres assert(presets); if (scope == UNIT_FILE_SYSTEM) - r = conf_files_list(&files, ".preset", root_dir, + r = conf_files_list(&files, ".preset", root_dir, 0, "/etc/systemd/system-preset", "/usr/local/lib/systemd/system-preset", "/usr/lib/systemd/system-preset", -#ifdef HAVE_SPLIT_USR +#if HAVE_SPLIT_USR "/lib/systemd/system-preset", #endif NULL); else if (scope == UNIT_FILE_GLOBAL) - r = conf_files_list(&files, ".preset", root_dir, + r = conf_files_list(&files, ".preset", root_dir, 0, "/etc/systemd/user-preset", "/usr/local/lib/systemd/user-preset", "/usr/lib/systemd/user-preset", |