From d9b4b48f3fee12293cc911929d1d92a01a5c69c9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 21 Sep 2017 19:03:17 +0200 Subject: [PATCH] install: consider non-Alias=/non-DefaultInstance= symlinks as "indirect" enablement I think this matches the spirit of "indirect" well: the unit *might* be active, even though it is not "installed" in the sense of symlinks created based on the [Install] section. The changes to test-install-root touch the same lines as in the previous commit; the change in each case is from assert_se(unit_file_get_state(...) >= 0 && state == UNIT_FILE_ENABLED) to assert_se(unit_file_get_state(...) >= 0 && state == UNIT_FILE_DISABLED) to assert_se(unit_file_get_state(...) >= 0 && state == UNIT_FILE_INDIRECT) in the last two commits. --- man/systemctl.xml | 2 +- src/shared/install.c | 26 +++++++++++++++++++++----- src/test/test-install-root.c | 6 +++--- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index cf9d85c98c3..f514ab64dd6 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -1274,7 +1274,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err indirect - The unit file itself is not enabled, but it has a non-empty Also= setting in the [Install] unit file section, listing other unit files that might be enabled. + The unit file itself is not enabled, but it has a non-empty Also= setting in the [Install] unit file section, listing other unit files that might be enabled, or it has an alias under a different name through a symlink that is not specified in Also=. For template unit file, an instance different than the one specified in DefaultInstance= is enabled. 0 diff --git a/src/shared/install.c b/src/shared/install.c index f6684452825..4141e0402fb 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -727,6 +727,7 @@ static bool is_symlink_with_known_name(const UnitFileInstallInfo *i, const char static int find_symlinks_fd( const char *root_dir, UnitFileInstallInfo *i, + bool match_aliases, int fd, const char *path, const char *config_path, @@ -773,7 +774,7 @@ static int find_symlinks_fd( } /* This will close nfd, regardless whether it succeeds or not */ - q = find_symlinks_fd(root_dir, i, nfd, + q = find_symlinks_fd(root_dir, i, match_aliases, nfd, p, config_path, same_name_link); if (q > 0) return 1; @@ -841,6 +842,9 @@ static int find_symlinks_fd( if (b) *same_name_link = true; 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); log_info("is_symlink_with_known_name(%s, %s) → %d", i->name, de->d_name, q); @@ -858,6 +862,7 @@ static int find_symlinks_fd( static int find_symlinks( const char *root_dir, UnitFileInstallInfo *i, + bool match_name, const char *config_path, bool *same_name_link) { @@ -875,13 +880,14 @@ static int find_symlinks( } /* This takes possession of fd and closes it */ - return find_symlinks_fd(root_dir, i, fd, + return find_symlinks_fd(root_dir, i, match_name, fd, config_path, config_path, same_name_link); } static int find_symlinks_in_scope( const LookupPaths *paths, UnitFileInstallInfo *i, + bool match_name, UnitFileState *state) { bool same_name_link_runtime = false, same_name_link_config = false; @@ -895,7 +901,7 @@ static int find_symlinks_in_scope( STRV_FOREACH(p, paths->search_path) { bool same_name_link = false; - r = find_symlinks(paths->root_dir, i, *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) { @@ -2640,10 +2646,20 @@ static int unit_file_lookup_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(paths, i, &state); + r = find_symlinks_in_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(paths, i, false, &state); if (r < 0) return r; - if (r == 0) { + 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)) diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c index bb61d7fb197..e2754a07736 100644 --- a/src/test/test-install-root.c +++ b/src/test/test-install-root.c @@ -446,7 +446,7 @@ static void test_template_enable(const char *root) { unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; - assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_ENABLED); @@ -479,11 +479,11 @@ static void test_template_enable(const char *root) { unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; - assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED); - assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_DISABLED); + assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@.service", &state) >= 0 && state == UNIT_FILE_INDIRECT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@def.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@foo.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "template-symlink@quux.service", &state) >= 0 && state == UNIT_FILE_ENABLED); -- 2.39.5