mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
import-common: when mangling OS trees, propagate ownership/mode from subdir to parent
After all we want to remove the top-level dir, and make it look like the only subdir, hence propagate the attributes from the subdir to the top-level dir.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "process-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -195,10 +196,10 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
}
|
||||
|
||||
int import_mangle_os_tree(const char *path) {
|
||||
_cleanup_free_ char *child = NULL, *t = NULL, *joined = NULL;
|
||||
_cleanup_closedir_ DIR *d = NULL, *cd = NULL;
|
||||
_cleanup_free_ char *child = NULL, *t = NULL;
|
||||
const char *joined;
|
||||
struct dirent *de;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
@@ -244,7 +245,17 @@ int import_mangle_os_tree(const char *path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
joined = prefix_roota(path, child);
|
||||
if (fstatat(dirfd(d), child, &st, AT_SYMLINK_NOFOLLOW) < 0)
|
||||
return log_debug_errno(errno, "Failed to stat file '%s/%s': %m", path, child);
|
||||
r = stat_verify_directory(&st);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Child '%s' of directory '%s' is not a directory, leaving things as they are.", child, path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
joined = path_join(path, child);
|
||||
if (!joined)
|
||||
return log_oom();
|
||||
r = path_is_os_tree(joined);
|
||||
if (r == -ENOTDIR) {
|
||||
log_debug("Directory '%s' does not look like an OS tree, and contains a single regular file only, leaving as it is.", path);
|
||||
@@ -293,6 +304,14 @@ int import_mangle_os_tree(const char *path) {
|
||||
if (unlinkat(dirfd(d), t, AT_REMOVEDIR) < 0)
|
||||
return log_error_errno(errno, "Failed to remove temporary directory '%s/%s': %m", path, t);
|
||||
|
||||
r = futimens(dirfd(d), (struct timespec[2]) { st.st_atim, st.st_mtim });
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to adjust top-level timestamps '%s', ignoring: %m", path);
|
||||
|
||||
r = fchmod_and_chown(dirfd(d), st.st_mode, st.st_uid, st.st_gid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to adjust top-level directory mode/ownership '%s': %m", path);
|
||||
|
||||
log_info("Successfully rearranged OS tree.");
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user