copy: return immediately on fs-verity failures
Since 8065d02e26 ("copy: Fix error handling in fd_copy_directory()")
we immediately abort recursive copy operations on ENOSPC. Let's also
abort on the common case of filesystems not supporting fs-verity: if
it's unsupported for one file, it's unlikely to work for the 1000s that
follow it.
We do this by mapping the two fs-verity "not supported" errors (ENOTTY,
EOPNOTSUPP) to ESOCKTNOSUPPORT as a special "fs-verity not supported
here" error. When we see that error at the top level we exit
immediately.
This prevents us from having to see the same error message literally
thousands of time when using fsverity=copy with systemd-repart on a
filesystem which lacks the proper support.
Adjust the test-copy test case to expect the new errno. Previously this
test case would output multiple failure lines per `copy_tree_at()`
invocation (for the failing cases) but now it only outputs one.
This commit is contained in:
committed by
Yu Watanabe
parent
959d7f1759
commit
137a2b1208
+14
-4
@@ -817,7 +817,11 @@ static int copy_fs_verity(int fdf, int *fdt) {
|
||||
* so the correct thing to do is to do nothing at all. */
|
||||
if (errno == ENODATA)
|
||||
return 0;
|
||||
return log_error_errno(errno, "Failed to read fs-verity metadata from source file: %m");
|
||||
log_error_errno(errno, "Failed to read fs-verity metadata from source file: %m");
|
||||
/* For cases where fs-verity is unsupported we return a special error code */
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
return -ESOCKTNOSUPPORT;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* Make sure that the descriptor is completely initialized */
|
||||
@@ -844,8 +848,13 @@ static int copy_fs_verity(int fdf, int *fdt) {
|
||||
.salt_ptr = (uintptr_t) &desc.salt,
|
||||
};
|
||||
|
||||
if (ioctl(*fdt, FS_IOC_ENABLE_VERITY, &enable_arg) < 0)
|
||||
return log_error_errno(errno, "Failed to set fs-verity metadata: %m");
|
||||
if (ioctl(*fdt, FS_IOC_ENABLE_VERITY, &enable_arg) < 0) {
|
||||
log_error_errno(errno, "Failed to set fs-verity metadata: %m");
|
||||
/* For cases where fs-verity is unsupported we return a special error code */
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
return -ESOCKTNOSUPPORT;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1222,7 +1231,8 @@ static int fd_copy_directory(
|
||||
denylist, subvolumes, hardlink_context, child_display_path, progress_path,
|
||||
progress_bytes, userdata);
|
||||
|
||||
if (IN_SET(r, -EINTR, -ENOSPC)) /* Propagate SIGINT/SIGTERM and ENOSPC up instantly */
|
||||
/* Propagate SIGINT/SIGTERM, ENOSPC, and fs-verity fails up instantly */
|
||||
if (IN_SET(r, -EINTR, -ENOSPC, -ESOCKTNOSUPPORT))
|
||||
return r;
|
||||
if (r == -EEXIST && (copy_flags & COPY_MERGE))
|
||||
r = 0;
|
||||
|
||||
@@ -676,7 +676,7 @@ TEST_RET(copy_with_verity) {
|
||||
|
||||
/* Copy *with* fs-verity enabled and make sure it works properly */
|
||||
int r = copy_tree_at(src, ".", dst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL);
|
||||
if (r == -ENOTTY)
|
||||
if (r == -ESOCKTNOSUPPORT)
|
||||
/* This can happen on some versions of btrfs, for example */
|
||||
return log_tests_skipped_errno(errno, "/var/tmp: fs-verity supported, but not reading metadata");
|
||||
ASSERT_OK(r);
|
||||
@@ -697,14 +697,14 @@ TEST_RET(copy_with_verity) {
|
||||
|
||||
/* Copy from our non-verity filesystem into dst, requesting verity and making sure we notice that
|
||||
* we failed to read verity from the source. */
|
||||
ASSERT_ERROR(copy_tree_at(badsrc, ".", dst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ENOTTY);
|
||||
ASSERT_ERROR(copy_tree_at(badsrc, ".", dst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ESOCKTNOSUPPORT);
|
||||
|
||||
/* Copy from our verity filesystem into our baddst, requesting verity and making sure we notice that
|
||||
* we failed to set verity on the destination. */
|
||||
ASSERT_ERROR(copy_tree_at(src, ".", baddst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ENOTTY);
|
||||
ASSERT_ERROR(copy_tree_at(src, ".", baddst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ESOCKTNOSUPPORT);
|
||||
|
||||
/* Of course this should fail too... */
|
||||
ASSERT_ERROR(copy_tree_at(badsrc, ".", baddst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ENOTTY);
|
||||
ASSERT_ERROR(copy_tree_at(badsrc, ".", baddst, ".", UID_INVALID, GID_INVALID, COPY_REFLINK|COPY_REPLACE|COPY_MERGE|COPY_PRESERVE_FS_VERITY, NULL, NULL), ESOCKTNOSUPPORT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user