diff options
author | Liang-Chun Chen <featherclc@gmail.com> | 2022-07-28 08:09:29 +0300 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2022-08-04 14:27:41 +0300 |
commit | d9009f6a3f744ba4e0e016532aa01361df29e60f (patch) | |
tree | a004443550d6349739b847c853f29915ed470dcd /test | |
parent | 4cc4d1d1bb802e2108025f3715aff3dffa68b8a5 (diff) |
zdtm: add two tests for large ghost sparse file
ghost_holes_large00 is a test which creates a large ghost sparse file with 1GiB
hole(pwrite can only handle 2GiB maximum on 32-bit system) and 8KiB data, criu
should be able to handle this kind of situation.
ghost_holes_large01 is a test which creates a large ghost sparse file with 1GiB
hole and 2MiB data, since 2MiB is larger than the default ghost_limit(1MiB),
criu should fail on this test.
v2: fix overflow on 32-bit arch.
Signed-off-by: Liang-Chun Chen <featherclc@gmail.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/zdtm/static/Makefile | 3 | ||||
-rw-r--r-- | test/zdtm/static/ghost_holes_large00.c | 152 | ||||
l--------- | test/zdtm/static/ghost_holes_large01.c | 1 | ||||
-rw-r--r-- | test/zdtm/static/ghost_holes_large01.desc | 1 |
4 files changed, 157 insertions, 0 deletions
diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 5a8a5f75c..b28345400 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -306,6 +306,8 @@ TST_FILE = \ ghost_holes00 \ ghost_holes01 \ ghost_holes02 \ + ghost_holes_large00 \ + ghost_holes_large01 \ unlink_largefile \ mtime_mmap \ fifo \ @@ -609,6 +611,7 @@ unlink_fstat04: CFLAGS += -DUNLINK_FSTAT04 unlink_fstat041: CFLAGS += -DUNLINK_FSTAT041 -DUNLINK_FSTAT04 ghost_holes01: CFLAGS += -DTAIL_HOLE ghost_holes02: CFLAGS += -DHEAD_HOLE +ghost_holes_large01: CFLAGS += -DLIMIT sk-freebind-false: CFLAGS += -DZDTM_FREEBIND_FALSE selinux02: CFLAGS += -DUSING_SOCKCREATE stopped01: CFLAGS += -DZDTM_STOPPED_KILL diff --git a/test/zdtm/static/ghost_holes_large00.c b/test/zdtm/static/ghost_holes_large00.c new file mode 100644 index 000000000..1a9739f8e --- /dev/null +++ b/test/zdtm/static/ghost_holes_large00.c @@ -0,0 +1,152 @@ +#include <errno.h> +#include <stdbool.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <linux/limits.h> + +#include "zdtmtst.h" + +const char *test_doc = "Test ghost with one large hole(1GiB) in the middle"; +const char *test_author = "Liang-Chun Chen <featherclc@gmail.com>"; + +char *filename; +TEST_OPTION(filename, string, "file name", 1); + +/* Buffer that is suitable for data size */ +#ifdef LIMIT +#define BUFSIZE 1024 * 1024 +#else +#define BUFSIZE 4096 +#endif +static unsigned char buf[BUFSIZE]; + +#ifndef SEEK_DATA +#define SEEK_DATA 3 +#define SEEK_HOLE 4 +#endif + +#define DATA1_OFF 0 +#define HOLE_SIZE (1LL * 1 * 1024 * 1024 * 1024) +#define DATA2_OFF (BUFSIZE + HOLE_SIZE) +#define FILE_SIZE (2 * BUFSIZE + HOLE_SIZE) +#define ST_UNIT 512 + +int main(int argc, char **argv) +{ + int fd; + struct stat st; + uint32_t crc; + bool chk_hole = true; + + test_init(argc, argv); + + fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd < 0) { + pr_perror("can't open %s", filename); + exit(1); + } + + if (unlink(filename) < 0) { + pr_perror("can't unlink %s", filename); + goto failed; + } + + crc = ~0; + datagen(buf, BUFSIZE, &crc); + if (pwrite(fd, buf, BUFSIZE, DATA1_OFF) != BUFSIZE) { + pr_perror("can't write data1"); + goto failed; + } + + crc = ~0; + datagen(buf, BUFSIZE, &crc); + if (pwrite(fd, buf, BUFSIZE, DATA2_OFF) != BUFSIZE) { + pr_perror("can't write data2"); + goto failed; + } + + if (ftruncate(fd, FILE_SIZE)) { + pr_perror("Can't fixup file size"); + goto failed; + } + + if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) { + test_msg("Won't check for hole\n"); + chk_hole = false; + } + + test_daemon(); + test_waitsig(); + + if (fstat(fd, &st) < 0) { + fail("can't stat after"); + goto failed; + } + + if (st.st_size != FILE_SIZE) { + fail("file size changed to %ld", (long)st.st_size); + goto failed; + } + + test_msg("file size OK\n"); + + if (st.st_blocks * ST_UNIT != 2 * BUFSIZE) { + fail("actual file size changed to %ld", (long)st.st_blocks * ST_UNIT); + goto failed; + } + + test_msg("actual file size OK\n"); + + /* Data 1 */ + if (pread(fd, buf, BUFSIZE, DATA1_OFF) != BUFSIZE) { + fail("pread1 fail"); + goto failed; + } + + crc = ~0; + if (datachk(buf, BUFSIZE, &crc)) { + fail("datachk1 fail"); + goto failed; + } + + test_msg("Data1 OK\n"); + + /* Data 2 */ + if (pread(fd, buf, BUFSIZE, DATA2_OFF) != BUFSIZE) { + fail("pread2 fail"); + goto failed; + } + + crc = ~0; + if (datachk(buf, BUFSIZE, &crc)) { + fail("datachk2 fail"); + goto failed; + } + + test_msg("Data2 OK\n"); + + /* Hole */ + if (chk_hole) { + if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) { + fail("Begin of mid hole not found"); + goto failed; + } + if (lseek(fd, DATA1_OFF + BUFSIZE, SEEK_DATA) != DATA2_OFF) { + fail("End of mid hole not found"); + goto failed; + } + test_msg("Mid hole OK\n"); + } + + close(fd); + pass(); + return 0; + +failed: + close(fd); + return 1; +} diff --git a/test/zdtm/static/ghost_holes_large01.c b/test/zdtm/static/ghost_holes_large01.c new file mode 120000 index 000000000..1b90363d4 --- /dev/null +++ b/test/zdtm/static/ghost_holes_large01.c @@ -0,0 +1 @@ +ghost_holes_large00.c
\ No newline at end of file diff --git a/test/zdtm/static/ghost_holes_large01.desc b/test/zdtm/static/ghost_holes_large01.desc new file mode 100644 index 000000000..8e6a476bd --- /dev/null +++ b/test/zdtm/static/ghost_holes_large01.desc @@ -0,0 +1 @@ +{'flags': 'crfail'}
\ No newline at end of file |