diff --git a/src/shared/install.c b/src/shared/install.c index 23397f7990..58fd75b5f8 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -251,6 +251,7 @@ static int path_is_runtime(const LookupPaths *lp, const char *path, bool check_p static int path_is_vendor_or_generator(const LookupPaths *lp, const char *path) { const char *rpath; + int r; assert(lp); assert(path); @@ -262,8 +263,10 @@ static int path_is_vendor_or_generator(const LookupPaths *lp, const char *path) if (path_startswith(rpath, "/usr")) return true; - if (path_is_generator(lp, rpath)) - return true; + /* The lookup paths are root prefixed, so we have to pass in a root prefixed path. */ + r = path_is_generator(lp, path); + if (r != 0) + return r; return path_equal(rpath, SYSTEM_DATA_UNIT_DIR); } diff --git a/src/test/test-install-root.c b/src/test/test-install-root.c index 9786675b4c..245407a47a 100644 --- a/src/test/test-install-root.c +++ b/src/test/test-install-root.c @@ -777,6 +777,23 @@ TEST(revert) { ASSERT_STREQ(changes[1].path, p); install_changes_free(changes, n_changes); changes = NULL; n_changes = 0; + + /* Reverting only removes a unit file in /etc/ if there's another copy to fall back to, either below + * /usr/ or written by a generator. Check that a generated copy counts too, when --root= is specified. */ + p = strjoina(root, "/run/systemd/generator/zz.service"); + ASSERT_OK(write_string_file(p, "# Empty\n", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MKDIR_0755)); + + p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/zz.service"); + ASSERT_OK(write_string_file(p, "# Empty override\n", WRITE_STRING_FILE_CREATE)); + + ASSERT_OK(unit_file_revert(RUNTIME_SCOPE_SYSTEM, root, STRV_MAKE("zz.service"), &changes, &n_changes)); + ASSERT_EQ(n_changes, 1u); + ASSERT_EQ(changes[0].type, INSTALL_CHANGE_UNLINK); + ASSERT_STREQ(changes[0].path, p); + install_changes_free(changes, n_changes); + changes = NULL; n_changes = 0; + + ASSERT_OK_ERRNO(unlink(strjoina(root, "/run/systemd/generator/zz.service"))); } TEST(preset_order) {