summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-03-14 13:18:14 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-03-15 14:53:31 -0400
commitce33fddad0806f859ff7324527ee0525dd10455e (patch)
tree8223f829ce74a0e48e0ccb4500d01a02515f7d25
parent70e43ee7be6ee8d1e8aa4b2984a72baa25709c2e (diff)
downloadsystemd-ce33fddad0806f859ff7324527ee0525dd10455e.tar.gz
test-copy: add a test shuffling bytes between normal files
I started looking into adding copy_file_range support, and discovered that we can improve the way we call sendfile: - sendfile(2) man page is missing an important bit: the number of bytes to copy cannot be too big (SSIZE_MAX actually), and the description of EINVAL return code does not mention this either, - our implementation works but calls sendfile over and over with a small size, which seems suboptimal. First add a test which (under strace) can be used to see current behaviour.
-rw-r--r--src/test/test-copy.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/test/test-copy.c b/src/test/test-copy.c
index ad57cb0202..622fba777d 100644
--- a/src/test/test-copy.c
+++ b/src/test/test-copy.c
@@ -24,6 +24,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
+#include "log.h"
#include "macro.h"
#include "mkdir.h"
#include "path-util.h"
@@ -39,6 +40,8 @@ static void test_copy_file(void) {
size_t sz = 0;
int fd;
+ log_info("%s", __func__);
+
fd = mkostemp_safe(fn, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
close(fd);
@@ -66,6 +69,8 @@ static void test_copy_file_fd(void) {
char text[] = "boohoo\nfoo\n\tbar\n";
char buf[64] = {0};
+ log_info("%s", __func__);
+
in_fd = mkostemp_safe(in_fn, O_RDWR);
assert_se(in_fd >= 0);
out_fd = mkostemp_safe(out_fn, O_RDWR);
@@ -91,6 +96,8 @@ static void test_copy_tree(void) {
"link2", "dir1/file");
char **p, **link;
+ log_info("%s", __func__);
+
(void) rm_rf(copy_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
(void) rm_rf(original_dir, REMOVE_ROOT|REMOVE_PHYSICAL);
@@ -173,11 +180,50 @@ static void test_copy_bytes(void) {
assert_se(r == -EBADF);
}
+static void test_copy_bytes_regular_file(const char *src, bool try_reflink) {
+ char fn2[] = "/tmp/test-copy-file-XXXXXX";
+ char fn3[] = "/tmp/test-copy-file-XXXXXX";
+ _cleanup_close_ int fd = -1, fd2 = -1, fd3 = -1;
+ int r;
+ struct stat buf, buf2, buf3;
+
+ log_info("%s try_reflink=%s", __func__, yes_no(try_reflink));
+
+ fd = open(src, O_RDONLY | O_CLOEXEC | O_NOCTTY);
+ assert_se(fd >= 0);
+
+ fd2 = mkostemp_safe(fn2, O_RDWR);
+ assert_se(fd2 >= 0);
+
+ fd3 = mkostemp_safe(fn3, O_WRONLY);
+ assert_se(fd3 >= 0);
+
+ r = copy_bytes(fd, fd2, (uint64_t) -1, try_reflink);
+ assert_se(r == 0);
+
+ assert_se(lseek(fd2, 0, SEEK_SET) == 0);
+
+ r = copy_bytes(fd2, fd3, (uint64_t) -1, try_reflink);
+ assert_se(r == 0);
+
+ assert_se(fstat(fd, &buf) == 0);
+ assert_se(fstat(fd2, &buf2) == 0);
+ assert_se(fstat(fd3, &buf3) == 0);
+
+ assert_se(buf.st_size == buf2.st_size);
+ assert_se(buf.st_size == buf3.st_size);
+
+ unlink(fn2);
+ unlink(fn3);
+}
+
int main(int argc, char *argv[]) {
test_copy_file();
test_copy_file_fd();
test_copy_tree();
test_copy_bytes();
+ test_copy_bytes_regular_file(argv[0], false);
+ test_copy_bytes_regular_file(argv[0], true);
return 0;
}