Merge pull request #34582 from DaanDeMeyer/repart
repart: copy denylist fixes
This commit is contained in:
@@ -5254,6 +5254,9 @@ static int make_copy_files_denylist(
|
||||
}
|
||||
|
||||
STRV_FOREACH(e, override_exclude_src ?: p->exclude_files_source) {
|
||||
if (path_startswith(source, *e))
|
||||
return 1;
|
||||
|
||||
r = add_exclude_path(*e, &denylist, endswith(*e, "/") ? DENY_CONTENTS : DENY_INODE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -5262,6 +5265,9 @@ static int make_copy_files_denylist(
|
||||
STRV_FOREACH(e, override_exclude_tgt ?: p->exclude_files_target) {
|
||||
_cleanup_free_ char *path = NULL;
|
||||
|
||||
if (path_startswith(target, *e))
|
||||
return 1;
|
||||
|
||||
const char *s = path_startswith(*e, target);
|
||||
if (!s)
|
||||
continue;
|
||||
@@ -5440,6 +5446,45 @@ static usec_t epoch_or_infinity(void) {
|
||||
return (cache = USEC_INFINITY);
|
||||
}
|
||||
|
||||
static int file_is_denylisted(const char *source, Hashmap *denylist) {
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
struct stat st, rst;
|
||||
int r;
|
||||
|
||||
r = chase_and_stat(source, arg_copy_source, CHASE_PREFIX_ROOT, /*ret_path=*/ NULL, &st);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to stat source file '%s/%s': %m", strempty(arg_copy_source), source);
|
||||
|
||||
if (PTR_TO_INT(hashmap_get(denylist, &st)) == DENY_INODE)
|
||||
return 1;
|
||||
|
||||
if (stat(arg_copy_source, &rst) < 0)
|
||||
return log_error_errno(errno, "Failed to stat '%s': %m", arg_copy_source);
|
||||
|
||||
pfd = chase_and_open_parent(source, arg_copy_source, CHASE_PREFIX_ROOT, /*ret_filename=*/ NULL);
|
||||
if (pfd < 0)
|
||||
return log_error_errno(pfd, "Failed to chase '%s/%s': %m", strempty(arg_copy_source), source);
|
||||
|
||||
for (;;) {
|
||||
if (fstat(pfd, &st) < 0)
|
||||
return log_error_errno(errno, "Failed to stat parent: %m");
|
||||
|
||||
if (PTR_TO_INT(hashmap_get(denylist, &st)) != DENY_DONT)
|
||||
return 1;
|
||||
|
||||
if (stat_inode_same(&st, &rst))
|
||||
break;
|
||||
|
||||
_cleanup_close_ int new_pfd = openat(pfd, "..", O_DIRECTORY|O_RDONLY);
|
||||
if (new_pfd < 0)
|
||||
return log_error_errno(errno, "Failed to open parent directory: %m");
|
||||
|
||||
close_and_replace(pfd, new_pfd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||
_cleanup_strv_free_ char **subvolumes = NULL;
|
||||
_cleanup_free_ char **override_copy_files = NULL;
|
||||
@@ -5492,6 +5537,8 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||
r = make_copy_files_denylist(context, p, *source, *target, &denylist);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
continue;
|
||||
|
||||
r = make_subvolumes_set(p, *source, *target, &subvolumes_by_source_inode);
|
||||
if (r < 0)
|
||||
@@ -5555,6 +5602,14 @@ static int do_copy_files(Context *context, Partition *p, const char *root) {
|
||||
|
||||
/* We are looking at a regular file */
|
||||
|
||||
r = file_is_denylisted(*source, denylist);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
log_debug("%s is in the denylist, ignoring", *source);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = path_extract_filename(*target, &fn);
|
||||
if (r == -EADDRNOTAVAIL || r == O_DIRECTORY)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EISDIR),
|
||||
|
||||
Reference in New Issue
Block a user