diff --git a/src/shared/generator.c b/src/shared/generator.c index f978d43fe8..f7ae848d6e 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -26,6 +26,14 @@ #include "tmpfile-util.h" #include "unit-name.h" +static int symlink_unless_exists(const char *to, const char *from) { + (void) mkdir_parents(from, 0755); + + if (symlink(to, from) < 0 && errno != EEXIST) + return log_error_errno(errno, "Failed to create symlink %s: %m", from); + return 0; +} + int generator_open_unit_file_full( const char *dir, const char *source, @@ -134,12 +142,7 @@ int generator_add_symlink_full( if (!to) return log_oom(); - (void) mkdir_parents_label(to, 0755); - - if (symlink(from, to) < 0 && errno != EEXIST) - return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to); - - return 0; + return symlink_unless_exists(from, to); } static int generator_add_ordering( @@ -331,19 +334,16 @@ int generator_write_fsck_deps( } if (path_equal(where, "/")) { - const char *lnk; - /* We support running the fsck instance for the root fs while it is already mounted, for * compatibility with non-initrd boots. It's ugly, but it is how it is. Since – unlike for * regular file systems – this means the ordering is reversed (i.e. mount *before* fsck) we * have a separate fsck unit for this, independent of systemd-fsck@.service. */ - lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/" SPECIAL_FSCK_ROOT_SERVICE); - - (void) mkdir_parents(lnk, 0755); - if (symlink(SYSTEM_DATA_UNIT_DIR "/" SPECIAL_FSCK_ROOT_SERVICE, lnk) < 0) - return log_error_errno(errno, "Failed to create symlink %s: %m", lnk); + const char *lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/" SPECIAL_FSCK_ROOT_SERVICE); + r = symlink_unless_exists(SYSTEM_DATA_UNIT_DIR "/" SPECIAL_FSCK_ROOT_SERVICE, lnk); + if (r < 0) + return r; } else { _cleanup_free_ char *_fsck = NULL; const char *fsck, *dep;