diff options
Diffstat (limited to 'src/shared/install.c')
-rw-r--r-- | src/shared/install.c | 197 |
1 files changed, 51 insertions, 146 deletions
diff --git a/src/shared/install.c b/src/shared/install.c index 1e497d1492..2cec6ba76f 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -85,6 +85,7 @@ static int in_search_path(const char *path, char **search) { static int unit_file_is_generated(const LookupPaths *p, const char *path) { _cleanup_free_ char *parent = NULL; + assert(p); assert(path); parent = dirname_malloc(path); @@ -96,110 +97,27 @@ static int unit_file_is_generated(const LookupPaths *p, const char *path) { path_equal(p->generator_late, parent); } -static int get_config_path(UnitFileScope scope, bool runtime, const char *root_dir, char **ret) { - char *p = NULL; - int r; - - assert(scope >= 0); - assert(scope < _UNIT_FILE_SCOPE_MAX); - assert(ret); - - /* This determines where we shall create or remove our - * installation ("configuration") symlinks */ - - switch (scope) { - - case UNIT_FILE_SYSTEM: - - if (runtime) - p = path_join(root_dir, "/run/systemd/system", NULL); - else - p = path_join(root_dir, SYSTEM_CONFIG_UNIT_PATH, NULL); - break; - - case UNIT_FILE_GLOBAL: - - if (root_dir) - return -EINVAL; - - if (runtime) - p = strdup("/run/systemd/user"); - else - p = strdup(USER_CONFIG_UNIT_PATH); - break; - - case UNIT_FILE_USER: - - if (root_dir) - return -EINVAL; - - if (runtime) - r = user_runtime_dir(&p); - else - r = user_config_home(&p); - if (r < 0) - return r; - if (r == 0) - return -ENOENT; - - break; - - default: - assert_not_reached("Bad scope"); - } - - if (!p) - return -ENOMEM; - - *ret = p; - return 0; -} - -static bool is_config_path(UnitFileScope scope, const char *path) { - int r; +static int path_is_config(const LookupPaths *p, const char *path) { + _cleanup_free_ char *parent = NULL; - assert(scope >= 0); - assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(p); assert(path); - /* Checks whether the specified path is intended for - * configuration or is outside of it */ - - switch (scope) { - - case UNIT_FILE_SYSTEM: - case UNIT_FILE_GLOBAL: - return path_startswith(path, "/etc") || - path_startswith(path, SYSTEM_CONFIG_UNIT_PATH) || - path_startswith(path, "/run"); - - - case UNIT_FILE_USER: { - _cleanup_free_ char *p = NULL; - - r = user_config_home(&p); - if (r < 0) - return r; - if (r > 0 && path_startswith(path, p)) - return true; - - p = mfree(p); + /* Checks whether the specified path is intended for configuration or is outside of it. We check both the + * top-level directory and the one actually configured. The latter is particularly relevant for cases where we + * operate on a root directory. */ - r = user_runtime_dir(&p); - if (r < 0) - return r; - if (r > 0 && path_startswith(path, p)) - return true; + if (path_startswith(path, "/etc") || path_startswith(path, "/run")) + return true; - return false; - } + parent = dirname_malloc(path); + if (!parent) + return -ENOMEM; - default: - assert_not_reached("Bad scope"); - } + return path_equal(parent, p->persistent_config) || + path_equal(parent, p->runtime_config); } - static int verify_root_dir(UnitFileScope scope, const char **root_dir) { int r; @@ -659,24 +577,21 @@ static int find_symlinks( static int find_symlinks_in_scope( UnitFileScope scope, + const LookupPaths *paths, const char *root_dir, const char *name, UnitFileState *state) { - _cleanup_free_ char *normal_path = NULL, *runtime_path = NULL; bool same_name_link_runtime = false, same_name_link = false; int r; assert(scope >= 0); assert(scope < _UNIT_FILE_SCOPE_MAX); + assert(paths); assert(name); - /* First look in the normal config path */ - r = get_config_path(scope, false, root_dir, &normal_path); - if (r < 0) - return r; - - r = find_symlinks(root_dir, name, normal_path, &same_name_link); + /* First look in the persistent config path */ + r = find_symlinks(root_dir, name, paths->persistent_config, &same_name_link); if (r < 0) return r; if (r > 0) { @@ -685,11 +600,7 @@ static int find_symlinks_in_scope( } /* Then look in runtime config path */ - r = get_config_path(scope, true, root_dir, &runtime_path); - if (r < 0) - return r; - - r = find_symlinks(root_dir, name, runtime_path, &same_name_link_runtime); + r = find_symlinks(root_dir, name, paths->runtime_config, &same_name_link_runtime); if (r < 0) return r; if (r > 0) { @@ -1182,8 +1093,13 @@ static int install_info_traverse( if (++k > UNIT_FILE_FOLLOW_SYMLINK_MAX) return -ELOOP; - if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS) && is_config_path(scope, i->path)) - return -ELOOP; + if (!(flags & SEARCH_FOLLOW_CONFIG_SYMLINKS)) { + r = path_is_config(paths, i->path); + if (r < 0) + return r; + if (r > 0) + return -ELOOP; + } r = install_info_follow(c, i, root_dir, flags); if (r < 0) { @@ -1514,7 +1430,8 @@ int unit_file_mask( UnitFileChange **changes, unsigned *n_changes) { - _cleanup_free_ char *prefix = NULL; + _cleanup_lookup_paths_free_ LookupPaths paths = {}; + const char *config_path; char **i; int r; @@ -1525,10 +1442,12 @@ int unit_file_mask( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &prefix); + r = lookup_paths_init_from_scope(&paths, scope, root_dir); if (r < 0) return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; + STRV_FOREACH(i, files) { _cleanup_free_ char *path = NULL; int q; @@ -1539,7 +1458,7 @@ int unit_file_mask( continue; } - path = path_make_absolute(*i, prefix); + path = path_make_absolute(*i, config_path); if (!path) return -ENOMEM; @@ -1559,10 +1478,11 @@ int unit_file_unmask( UnitFileChange **changes, unsigned *n_changes) { + _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; - _cleanup_free_ char *config_path = NULL; _cleanup_free_ char **todo = NULL; size_t n_todo = 0, n_allocated = 0; + const char *config_path; char **i; int r, q; @@ -1573,10 +1493,12 @@ int unit_file_unmask( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); + r = lookup_paths_init_from_scope(&paths, scope, root_dir); if (r < 0) return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; + STRV_FOREACH(i, files) { _cleanup_free_ char *path = NULL; @@ -1640,9 +1562,9 @@ int unit_file_link( unsigned *n_changes) { _cleanup_lookup_paths_free_ LookupPaths paths = {}; - _cleanup_free_ char *config_path = NULL; _cleanup_free_ char **todo = NULL; size_t n_todo = 0, n_allocated = 0; + const char *config_path; char **i; int r, q; @@ -1657,9 +1579,7 @@ int unit_file_link( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; STRV_FOREACH(i, files) { _cleanup_free_ char *full = NULL; @@ -1729,8 +1649,8 @@ int unit_file_add_dependency( _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_(install_context_done) InstallContext c = {}; - _cleanup_free_ char *config_path = NULL; UnitFileInstallInfo *i, *target_info; + const char *config_path; char **f; int r; @@ -1752,9 +1672,7 @@ int unit_file_add_dependency( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; r = install_info_discover(scope, &c, root_dir, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, &target_info); if (r < 0) @@ -1808,7 +1726,7 @@ int unit_file_enable( _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_(install_context_done) InstallContext c = {}; - _cleanup_free_ char *config_path = NULL; + const char *config_path; UnitFileInstallInfo *i; char **f; int r; @@ -1824,9 +1742,7 @@ int unit_file_enable( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; STRV_FOREACH(f, files) { r = install_info_discover(scope, &c, root_dir, &paths, *f, SEARCH_LOAD, &i); @@ -1858,8 +1774,8 @@ int unit_file_disable( _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_(install_context_done) InstallContext c = {}; - _cleanup_free_ char *config_path = NULL; _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; + const char *config_path; char **i; int r; @@ -1874,9 +1790,7 @@ int unit_file_disable( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; STRV_FOREACH(i, files) { if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) @@ -1932,7 +1846,6 @@ int unit_file_set_default( _cleanup_lookup_paths_free_ LookupPaths paths = {}; _cleanup_(install_context_done) InstallContext c = {}; - _cleanup_free_ char *config_path = NULL; UnitFileInstallInfo *i; const char *path; int r; @@ -1954,10 +1867,6 @@ int unit_file_set_default( if (r < 0) return r; - r = get_config_path(scope, false, root_dir, &config_path); - if (r < 0) - return r; - r = install_info_discover(scope, &c, root_dir, &paths, name, 0, &i); if (r < 0) return r; @@ -1966,7 +1875,7 @@ int unit_file_set_default( if (unit_file_is_generated(&paths, i->path)) return -EADDRNOTAVAIL; - path = strjoina(config_path, "/" SPECIAL_DEFAULT_TARGET); + path = strjoina(paths.persistent_config, "/" SPECIAL_DEFAULT_TARGET); return create_symlink(i->path, path, force, changes, n_changes); } @@ -2053,7 +1962,7 @@ int unit_file_lookup_state( break; } - r = find_symlinks_in_scope(scope, root_dir, i->name, &state); + r = find_symlinks_in_scope(scope, paths, root_dir, i->name, &state); if (r < 0) return r; if (r == 0) { @@ -2282,7 +2191,7 @@ int unit_file_preset( _cleanup_(install_context_done) InstallContext plus = {}, minus = {}; _cleanup_lookup_paths_free_ LookupPaths paths = {}; - _cleanup_free_ char *config_path = NULL; + const char *config_path; char **i; int r; @@ -2298,9 +2207,7 @@ int unit_file_preset( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; STRV_FOREACH(i, files) { if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) @@ -2325,7 +2232,7 @@ int unit_file_preset_all( _cleanup_(install_context_done) InstallContext plus = {}, minus = {}; _cleanup_lookup_paths_free_ LookupPaths paths = {}; - _cleanup_free_ char *config_path = NULL; + const char *config_path = NULL; char **i; int r; @@ -2341,9 +2248,7 @@ int unit_file_preset_all( if (r < 0) return r; - r = get_config_path(scope, runtime, root_dir, &config_path); - if (r < 0) - return r; + config_path = runtime ? paths.runtime_config : paths.persistent_config; STRV_FOREACH(i, paths.search_path) { _cleanup_closedir_ DIR *d = NULL; |