diff options
author | Daan De Meyer <daan.j.demeyer@gmail.com> | 2024-08-29 22:59:48 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2024-08-30 16:20:40 +0200 |
commit | d850a544bc1f895decb452160c97a884a20b12b7 (patch) | |
tree | afcba3e4628a628205eb441858171f23ca035b03 /src/shared/copy.c | |
parent | Use correct error code in log message in pkcs11_token_find_x509_certificate (... (diff) | |
download | systemd-d850a544bc1f895decb452160c97a884a20b12b7.tar.xz systemd-d850a544bc1f895decb452160c97a884a20b12b7.zip |
repart: Keep existing directory timestamps intact when copying
Otherwise, when merging multiple directory trees, the output becomes
unreproducible as the directory timestamps will be changed to the current
time when copying identical directories from the second tree.
We introduce a new copy flag to achieve this behavior.
Diffstat (limited to 'src/shared/copy.c')
-rw-r--r-- | src/shared/copy.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/shared/copy.c b/src/shared/copy.c index c5c5cf083d..8e240dc434 100644 --- a/src/shared/copy.c +++ b/src/shared/copy.c @@ -1009,6 +1009,7 @@ static int fd_copy_directory( _cleanup_close_ int fdf = -EBADF, fdt = -EBADF; _cleanup_closedir_ DIR *d = NULL; + struct stat dt_st; bool exists; int r; @@ -1053,6 +1054,9 @@ static int fd_copy_directory( if (fdt < 0) return fdt; + if (exists && FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS) && fstat(fdt, &dt_st) < 0) + return -errno; + r = 0; if (PTR_TO_INT(hashmap_get(denylist, st)) == DENY_CONTENTS) { @@ -1152,7 +1156,9 @@ finish: (void) copy_xattr(dirfd(d), NULL, fdt, NULL, copy_flags); (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim }); - } + } else if (FLAGS_SET(copy_flags, COPY_RESTORE_DIRECTORY_TIMESTAMPS)) + /* If the directory already exists, make sure the timestamps stay the same as before. */ + (void) futimens(fdt, (struct timespec[]) { dt_st.st_atim, dt_st.st_mtim }); if (copy_flags & COPY_FSYNC_FULL) { if (fsync(fdt) < 0) |