From 1fbfbe81b5b7ae9be4775623cd6f6c43f0f4e7d9 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 5 May 2025 12:05:15 +0200 Subject: [PATCH] tree-wide: Get rid of prefix_roota() in favor of path_join() We deprecated prefix_roota() in favor of chase() and path_join(). Let's finish the removal by replacing the few remaining call sites with path_join(). --- TODO | 3 -- src/basic/path-util.h | 26 --------------- src/bootctl/bootctl-install.c | 18 ++++++---- src/network/generator/main.c | 4 ++- src/nspawn/nspawn-mount.c | 26 ++++++++++----- src/nspawn/nspawn.c | 63 ++++++++++++++++++++++++++--------- src/shared/install.c | 6 ++-- src/shared/tests.h | 5 ++- src/shared/vpick.c | 19 +++++++---- src/sysusers/sysusers.c | 20 ++++++++--- src/test/test-cgroup.c | 8 ++--- src/test/test-dev-setup.c | 22 +++++++----- src/test/test-path-util.c | 3 +- src/tmpfiles/tmpfiles.c | 6 ++-- 14 files changed, 136 insertions(+), 93 deletions(-) diff --git a/TODO b/TODO index dfc3e97ba62..d91dbcee286 100644 --- a/TODO +++ b/TODO @@ -66,9 +66,6 @@ Janitorial Clean-ups: * rework mount.c and swap.c to follow proper state enumeration/deserialization semantics, like we do for device.c now -* get rid of prefix_roota() and similar, only use chase() and related - calls instead. - * get rid of basename() and replace by path_extract_filename() * Replace our fstype_is_network() with a call to libmount's mnt_fstype_is_netfs()? diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 436bd5d8927..74406d7698a 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -154,32 +154,6 @@ int fsck_exists_for_fstype(const char *fstype); _slash && ((*_slash = 0), true); \ _slash = strrchr((prefix), '/')) -/* Similar to path_join(), but only works for two components, and only the first one may be NULL and returns - * an alloca() buffer, or possibly a const pointer into the path parameter. */ -/* DEPRECATED: use path_join() instead */ -#define prefix_roota(root, path) \ - ({ \ - const char* _path = (path), *_root = (root), *_ret; \ - char *_p, *_n; \ - size_t _l; \ - while (_path[0] == '/' && _path[1] == '/') \ - _path++; \ - if (isempty(_root)) \ - _ret = _path; \ - else { \ - _l = strlen(_root) + 1 + strlen(_path) + 1; \ - _n = newa(char, _l); \ - _p = stpcpy(_n, _root); \ - while (_p > _n && _p[-1] == '/') \ - _p--; \ - if (_path[0] != '/') \ - *(_p++) = '/'; \ - strcpy(_p, _path); \ - _ret = _n; \ - } \ - _ret; \ - }) - int path_find_first_component(const char **p, bool accept_dot_dot, const char **ret); int path_find_last_component(const char *path, bool accept_dot_dot, const char **next, const char **ret); const char* last_path_component(const char *path); diff --git a/src/bootctl/bootctl-install.c b/src/bootctl/bootctl-install.c index 16ae5de99f6..20c3336009f 100644 --- a/src/bootctl/bootctl-install.c +++ b/src/bootctl/bootctl-install.c @@ -1118,9 +1118,10 @@ static int remove_boot_efi(const char *esp_path) { } static int rmdir_one(const char *prefix, const char *suffix) { - const char *p; + _cleanup_free_ char *p = path_join(prefix, suffix); + if (!p) + return log_oom(); - p = prefix_roota(prefix, suffix); if (rmdir(p) < 0) { bool ignore = IN_SET(errno, ENOENT, ENOTEMPTY); @@ -1160,10 +1161,12 @@ static int remove_entry_directory(const char *root) { } static int remove_binaries(const char *esp_path) { - const char *p; int r, q; - p = prefix_roota(esp_path, "/EFI/systemd"); + _cleanup_free_ char *p = path_join(esp_path, "/EFI/systemd"); + if (!p) + return log_oom(); + r = rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL); q = remove_boot_efi(esp_path); @@ -1174,12 +1177,13 @@ static int remove_binaries(const char *esp_path) { } static int remove_file(const char *root, const char *file) { - const char *p; - assert(root); assert(file); - p = prefix_roota(root, file); + _cleanup_free_ char *p = path_join(root, file); + if (!p) + return log_oom(); + if (unlink(p) < 0) { log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to unlink file \"%s\": %m", p); diff --git a/src/network/generator/main.c b/src/network/generator/main.c index 0911656e889..c15dfa16cd7 100644 --- a/src/network/generator/main.c +++ b/src/network/generator/main.c @@ -123,7 +123,9 @@ static int context_save(Context *context) { Link *link; int r; - const char *p = prefix_roota(arg_root, NETWORK_UNIT_DIRECTORY); + _cleanup_free_ char *p = path_join(arg_root, NETWORK_UNIT_DIRECTORY); + if (!p) + return log_oom(); r = mkdir_p(p, 0755); if (r < 0) diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 075cf3d45ac..d1a9ced8ea4 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -1091,19 +1091,21 @@ static int setup_volatile_state(const char *directory) { static int setup_volatile_state_after_remount_idmap(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) { _cleanup_free_ char *buf = NULL; - const char *p, *options; int r; assert(directory); /* Then, after remount_idmap(), overmount /var/ with a tmpfs. */ - p = prefix_roota(directory, "/var"); + _cleanup_free_ char *p = path_join(directory, "/var"); + if (!p) + return log_oom(); + r = mkdir(p, 0755); if (r < 0 && errno != EEXIST) return log_error_errno(errno, "Failed to create %s: %m", directory); - options = "mode=0755" TMPFS_LIMITS_VOLATILE_STATE; + const char *options = "mode=0755" TMPFS_LIMITS_VOLATILE_STATE; r = tmpfs_patch_options(options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf); if (r < 0) return log_oom(); @@ -1116,8 +1118,7 @@ static int setup_volatile_state_after_remount_idmap(const char *directory, uid_t static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char *selinux_apifs_context) { bool tmpfs_mounted = false, bind_mounted = false; _cleanup_(rmdir_and_freep) char *template = NULL; - _cleanup_free_ char *buf = NULL, *bindir = NULL; - const char *f, *t, *options; + _cleanup_free_ char *buf = NULL, *bindir = NULL, *f = NULL, *t = NULL; struct stat st; int r; @@ -1148,7 +1149,7 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char if (r < 0) return log_error_errno(r, "Failed to create temporary directory: %m"); - options = "mode=0755" TMPFS_LIMITS_ROOTFS; + const char *options = "mode=0755" TMPFS_LIMITS_ROOTFS; r = tmpfs_patch_options(options, uid_shift == 0 ? UID_INVALID : uid_shift, selinux_apifs_context, &buf); if (r < 0) goto fail; @@ -1161,8 +1162,17 @@ static int setup_volatile_yes(const char *directory, uid_t uid_shift, const char tmpfs_mounted = true; - f = prefix_roota(directory, "/usr"); - t = prefix_roota(template, "/usr"); + f = path_join(directory, "/usr"); + if (!f) { + r = log_oom(); + goto fail; + } + + t = path_join(template, "/usr"); + if (!t) { + r = log_oom(); + goto fail; + } r = mkdir(t, 0755); if (r < 0 && errno != EEXIST) { diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index bda38db1058..33397fd7597 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2260,7 +2260,6 @@ static int make_extra_nodes(const char *dest) { static int setup_pts(const char *dest, uid_t chown_uid) { _cleanup_free_ char *options = NULL; - const char *p; int r; #if HAVE_SELINUX @@ -2279,7 +2278,10 @@ static int setup_pts(const char *dest, uid_t chown_uid) { return log_oom(); /* Mount /dev/pts itself */ - p = prefix_roota(dest, "/dev/pts"); + _cleanup_free_ char *p = path_join(dest, "/dev/pts"); + if (!p) + return log_oom(); + r = RET_NERRNO(mkdir(p, 0755)); if (r < 0) return log_error_errno(r, "Failed to create /dev/pts: %m"); @@ -2292,7 +2294,11 @@ static int setup_pts(const char *dest, uid_t chown_uid) { return log_error_errno(r, "Failed to chown /dev/pts: %m"); /* Create /dev/ptmx symlink */ - p = prefix_roota(dest, "/dev/ptmx"); + free(p); + p = path_join(dest, "/dev/ptmx"); + if (!p) + return log_oom(); + if (symlink("pts/ptmx", p) < 0) return log_error_errno(errno, "Failed to create /dev/ptmx symlink: %m"); r = userns_lchown(p, 0, 0); @@ -2300,7 +2306,11 @@ static int setup_pts(const char *dest, uid_t chown_uid) { return log_error_errno(r, "Failed to chown /dev/ptmx: %m"); /* And fix /dev/pts/ptmx ownership */ - p = prefix_roota(dest, "/dev/pts/ptmx"); + free(p); + p = path_join(dest, "/dev/pts/ptmx"); + if (!p) + return log_oom(); + r = userns_lchown(p, 0, 0); if (r < 0) return log_error_errno(r, "Failed to chown /dev/pts/ptmx: %m"); @@ -2384,7 +2394,6 @@ int make_run_host(const char *root) { static int setup_credentials(const char *root) { bool world_readable = false; - const char *q; int r; if (arg_credentials.n_credentials == 0) @@ -2411,7 +2420,10 @@ static int setup_credentials(const char *root) { if (r < 0) return log_error_errno(r, "Failed to create /run/host/credentials: %m"); - q = prefix_roota(root, "/run/host/credentials"); + _cleanup_free_ char *q = path_join(root, "/run/host/credentials"); + if (!q) + return log_oom(); + r = mount_nofollow_verbose(LOG_ERR, NULL, q, "ramfs", MS_NOSUID|MS_NOEXEC|MS_NODEV, "mode=0700"); if (r < 0) return r; @@ -2527,7 +2539,6 @@ static int setup_hostname(void) { static int setup_journal(const char *directory) { _cleanup_free_ char *d = NULL; - const char *p, *q; sd_id128_t this_id; bool try; int r; @@ -2563,8 +2574,13 @@ static int setup_journal(const char *directory) { } } - p = strjoina("/var/log/journal/", SD_ID128_TO_STRING(arg_uuid)); - q = prefix_roota(directory, p); + _cleanup_free_ char *p = path_join("/var/log/journal/", SD_ID128_TO_STRING(arg_uuid)); + if (!p) + return log_oom(); + + _cleanup_free_ char *q = path_join(directory, p); + if (!q) + return log_oom(); if (path_is_mount_point(p) > 0) { if (try) @@ -2741,7 +2757,6 @@ static int reset_audit_loginuid(void) { } static int mount_tunnel_dig(const char *root) { - const char *p, *q; int r; if (arg_userns_mode == USER_NAMESPACE_MANAGED) { @@ -2751,7 +2766,10 @@ static int mount_tunnel_dig(const char *root) { (void) mkdir_p("/run/systemd/nspawn/", 0755); (void) mkdir_p("/run/systemd/nspawn/propagate", 0600); - p = strjoina("/run/systemd/nspawn/propagate/", arg_machine); + _cleanup_free_ char *p = path_join("/run/systemd/nspawn/propagate/", arg_machine); + if (!p) + return log_oom(); + (void) mkdir_p(p, 0600); r = make_run_host(root); @@ -2762,7 +2780,10 @@ static int mount_tunnel_dig(const char *root) { if (r < 0) return log_error_errno(r, "Failed to create "NSPAWN_MOUNT_TUNNEL": %m"); - q = prefix_roota(root, NSPAWN_MOUNT_TUNNEL); + _cleanup_free_ char *q = path_join(root, NSPAWN_MOUNT_TUNNEL); + if (!q) + return log_oom(); + r = mount_nofollow_verbose(LOG_ERR, p, q, NULL, MS_BIND, NULL); if (r < 0) return r; @@ -3819,7 +3840,6 @@ static int outer_child( _cleanup_(bind_user_context_freep) BindUserContext *bind_user_context = NULL; _cleanup_strv_free_ char **os_release_pairs = NULL; bool idmap = false; - const char *p; pid_t pid; ssize_t l; int r; @@ -4157,7 +4177,10 @@ static int outer_child( (void) dev_setup(directory, chown_uid, chown_uid); - p = prefix_roota(directory, "/run/host"); + _cleanup_free_ char *p = path_join(directory, "/run/host"); + if (!p) + return log_oom(); + (void) make_inaccessible_nodes(p, chown_uid, chown_uid); r = setup_unix_export_host_inside(directory, unix_export_path); @@ -4212,11 +4235,19 @@ static int outer_child( return r; /* The same stuff as the $container env var, but nicely readable for the entire payload */ - p = prefix_roota(directory, "/run/host/container-manager"); + free(p); + p = path_join(directory, "/run/host/container-manager"); + if (!p) + return log_oom(); + (void) write_string_file(p, arg_container_service_name, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0444); /* The same stuff as the $container_uuid env var */ - p = prefix_roota(directory, "/run/host/container-uuid"); + free(p); + p = path_join(directory, "/run/host/container-uuid"); + if (!p) + return log_oom(); + (void) write_string_filef(p, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0444, SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(arg_uuid)); if (!arg_use_cgns) { diff --git a/src/shared/install.c b/src/shared/install.c index 3b370c854de..30f2de388e0 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -1782,9 +1782,9 @@ static int install_info_add_auto( assert(name_or_path); if (path_is_absolute(name_or_path)) { - const char *pp; - - pp = prefix_roota(lp->root_dir, name_or_path); + _cleanup_free_ char *pp = path_join(lp->root_dir, name_or_path); + if (!pp) + return -ENOMEM; return install_info_add(ctx, NULL, pp, lp->root_dir, /* auxiliary= */ false, ret); } else diff --git a/src/shared/tests.h b/src/shared/tests.h index d19ffcea8c2..b19bad43956 100644 --- a/src/shared/tests.h +++ b/src/shared/tests.h @@ -458,11 +458,14 @@ static inline int run_test_table(void) { #else #define ASSERT_NOT_NULL(expr) \ ({ \ - if ((expr) == NULL) { \ + typeof(expr) _result = (expr); \ + if (_result == NULL) { \ log_error("%s:%i: Assertion failed: expected \"%s\" to be not NULL", \ PROJECT_FILE, __LINE__, #expr); \ abort(); \ } \ + \ + _result; \ }) #endif diff --git a/src/shared/vpick.c b/src/shared/vpick.c index 0319a6f5f88..2652633f372 100644 --- a/src/shared/vpick.c +++ b/src/shared/vpick.c @@ -163,14 +163,15 @@ static int pin_choice( struct stat st; if (fstat(inode_fd, &st) < 0) - return log_debug_errno(errno, "Failed to stat discovered inode '%s': %m", prefix_roota(toplevel_path, inode_path)); + return log_debug_errno(errno, "Failed to stat discovered inode '%s%s': %m", + empty_to_root(toplevel_path), skip_leading_slash(inode_path)); if (filter->type_mask != 0 && !BIT_SET(filter->type_mask, IFTODT(st.st_mode))) return log_debug_errno( SYNTHETIC_ERRNO(errno_from_mode(filter->type_mask, st.st_mode)), - "Inode '%s' has wrong type, found '%s'.", - prefix_roota(toplevel_path, inode_path), + "Inode '%s/%s' has wrong type, found '%s'.", + empty_to_root(toplevel_path), skip_leading_slash(inode_path), inode_type_to_string(st.st_mode)); _cleanup_(pick_result_done) PickResult result = { @@ -297,7 +298,8 @@ static int make_choice( return 0; } if (r < 0) - return log_debug_errno(r, "Failed to open '%s': %m", prefix_roota(toplevel_path, p)); + return log_debug_errno(r, "Failed to open '%s/%s': %m", + empty_to_root(toplevel_path), skip_leading_slash(p)); return pin_choice( toplevel_path, @@ -318,11 +320,13 @@ static int make_choice( /* Convert O_PATH to a regular directory fd */ dir_fd = fd_reopen(inode_fd, O_DIRECTORY|O_RDONLY|O_CLOEXEC); if (dir_fd < 0) - return log_debug_errno(dir_fd, "Failed to reopen '%s' as directory: %m", prefix_roota(toplevel_path, inode_path)); + return log_debug_errno(dir_fd, "Failed to reopen '%s/%s' as directory: %m", + empty_to_root(toplevel_path), skip_leading_slash(inode_path)); r = readdir_all(dir_fd, 0, &de); if (r < 0) - return log_debug_errno(r, "Failed to read directory '%s': %m", prefix_roota(toplevel_path, inode_path)); + return log_debug_errno(r, "Failed to read directory '%s/%s': %m", + empty_to_root(toplevel_path), skip_leading_slash(inode_path)); if (filter->architecture < 0) { architectures = local_architectures; @@ -466,7 +470,8 @@ static int make_choice( object_fd = openat(dir_fd, best_filename, O_CLOEXEC|O_PATH); if (object_fd < 0) - return log_debug_errno(errno, "Failed to open '%s': %m", prefix_roota(toplevel_path, p)); + return log_debug_errno(errno, "Failed to open '%s/%s': %m", + empty_to_root(toplevel_path), skip_leading_slash(inode_path)); return pin_choice( toplevel_path, diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index bef806015e3..3d36b4ff64a 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -944,11 +944,21 @@ static int write_files(Context *c) { _cleanup_(unlink_and_freep) char *passwd_tmp = NULL, *group_tmp = NULL, *shadow_tmp = NULL, *gshadow_tmp = NULL; int r; - const char - *passwd_path = prefix_roota(arg_root, "/etc/passwd"), - *shadow_path = prefix_roota(arg_root, "/etc/shadow"), - *group_path = prefix_roota(arg_root, "/etc/group"), - *gshadow_path = prefix_roota(arg_root, "/etc/gshadow"); + _cleanup_free_ char *passwd_path = path_join(arg_root, "/etc/passwd"); + if (!passwd_path) + return log_oom(); + + _cleanup_free_ char *shadow_path = path_join(arg_root, "/etc/shadow"); + if (!shadow_path) + return log_oom(); + + _cleanup_free_ char *group_path = path_join(arg_root, "/etc/group"); + if (!group_path) + return log_oom(); + + _cleanup_free_ char *gshadow_path = path_join(arg_root, "/etc/gshadow"); + if (!gshadow_path) + return log_oom(); assert(c); diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c index a15b880049c..363a7beeafd 100644 --- a/src/test/test-cgroup.c +++ b/src/test/test-cgroup.c @@ -54,10 +54,10 @@ TEST(cg_create) { _cleanup_free_ char *here = NULL; ASSERT_OK(cg_pid_get_path_shifted(0, NULL, &here)); - const char *test_a = prefix_roota(here, "/test-a"), - *test_b = prefix_roota(here, "/test-b"), - *test_c = prefix_roota(here, "/test-b/test-c"), - *test_d = prefix_roota(here, "/test-b/test-d"); + _cleanup_free_ char *test_a = ASSERT_NOT_NULL(path_join(here, "/test-a")), + *test_b = ASSERT_NOT_NULL(path_join(here, "/test-b")), + *test_c = ASSERT_NOT_NULL(path_join(here, "/test-b/test-c")), + *test_d = ASSERT_NOT_NULL(path_join(here, "/test-b/test-d")); char *path; log_info("Paths for test:\n%s\n%s", test_a, test_b); diff --git a/src/test/test-dev-setup.c b/src/test/test-dev-setup.c index dd6b30079a9..b748809eb15 100644 --- a/src/test/test-dev-setup.c +++ b/src/test/test-dev-setup.c @@ -11,7 +11,7 @@ int main(int argc, char *argv[]) { _cleanup_(rm_rf_physical_and_freep) char *p = NULL; - const char *f; + _cleanup_free_ char *f = NULL; struct stat st; test_setup_logging(LOG_DEBUG); @@ -21,33 +21,38 @@ int main(int argc, char *argv[]) { ASSERT_OK(mkdtemp_malloc("/tmp/test-dev-setupXXXXXX", &p)); - f = prefix_roota(p, "/run/systemd"); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd")); ASSERT_OK(mkdir_p(f, 0755)); ASSERT_OK(make_inaccessible_nodes(f, 1, 1)); ASSERT_OK(make_inaccessible_nodes(f, 1, 1)); /* 2nd call should be a clean NOP */ - f = prefix_roota(p, "/run/systemd/inaccessible/reg"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/reg")); ASSERT_OK_ERRNO(stat(f, &st)); ASSERT_TRUE(S_ISREG(st.st_mode)); ASSERT_EQ(st.st_mode & 07777, 0000U); - f = prefix_roota(p, "/run/systemd/inaccessible/dir"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/dir")); ASSERT_OK_ERRNO(stat(f, &st)); ASSERT_TRUE(S_ISDIR(st.st_mode)); ASSERT_EQ(st.st_mode & 07777, 0000U); - f = prefix_roota(p, "/run/systemd/inaccessible/fifo"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/fifo")); ASSERT_OK_ERRNO(stat(f, &st)); ASSERT_TRUE(S_ISFIFO(st.st_mode)); ASSERT_EQ(st.st_mode & 07777, 0000U); - f = prefix_roota(p, "/run/systemd/inaccessible/sock"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/sock")); ASSERT_OK_ERRNO(stat(f, &st)); ASSERT_TRUE(S_ISSOCK(st.st_mode)); ASSERT_EQ(st.st_mode & 07777, 0000U); - f = prefix_roota(p, "/run/systemd/inaccessible/chr"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/chr")); if (stat(f, &st) < 0) ASSERT_EQ(errno, ENOENT); else { @@ -55,7 +60,8 @@ int main(int argc, char *argv[]) { ASSERT_EQ(st.st_mode & 07777, 0000U); } - f = prefix_roota(p, "/run/systemd/inaccessible/blk"); + free(f); + f = ASSERT_NOT_NULL(path_join(p, "/run/systemd/inaccessible/blk")); if (stat(f, &st) < 0) ASSERT_EQ(errno, ENOENT); else { diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index e02bd8c8575..e11599e1859 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -758,12 +758,11 @@ TEST(path_startswith) { static void test_prefix_root_one(const char *r, const char *p, const char *expected) { _cleanup_free_ char *s = NULL; - const char *t; assert_se(s = path_join(r, p)); assert_se(path_equal(s, expected)); - t = prefix_roota(r, p); + _cleanup_free_ char *t = path_join(r, p); assert_se(t); assert_se(path_equal(t, expected)); } diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 8ac320469a2..9d0d568a4b2 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -2416,11 +2416,13 @@ static int create_symlink(Context *c, Item *i) { r = chase(i->argument, arg_root, CHASE_SAFE|CHASE_PREFIX_ROOT|CHASE_NOFOLLOW, /* ret_path = */ NULL, /* ret_fd = */ NULL); if (r == -ENOENT) { /* Silently skip over lines where the source file is missing. */ - log_info("Symlink source path '%s' does not exist, skipping line.", prefix_roota(arg_root, i->argument)); + log_info("Symlink source path '%s/%s' does not exist, skipping line.", + empty_to_root(arg_root), skip_leading_slash(i->argument)); return 0; } if (r < 0) - return log_error_errno(r, "Failed to check if symlink source path '%s' exists: %m", prefix_roota(arg_root, i->argument)); + return log_error_errno(r, "Failed to check if symlink source path '%s/%s' exists: %m", + empty_to_root(arg_root), skip_leading_slash(i->argument)); } r = path_extract_filename(i->path, &bn); -- 2.47.3