mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
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>
This commit is contained in:
committed by
Andrei Vagin
parent
2d34b56024
commit
e62d541bde
@@ -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
|
||||
|
152
test/zdtm/static/ghost_holes_large00.c
Normal file
152
test/zdtm/static/ghost_holes_large00.c
Normal file
@@ -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;
|
||||
}
|
1
test/zdtm/static/ghost_holes_large01.c
Symbolic link
1
test/zdtm/static/ghost_holes_large01.c
Symbolic link
@@ -0,0 +1 @@
|
||||
ghost_holes_large00.c
|
1
test/zdtm/static/ghost_holes_large01.desc
Normal file
1
test/zdtm/static/ghost_holes_large01.desc
Normal file
@@ -0,0 +1 @@
|
||||
{'flags': 'crfail'}
|
Reference in New Issue
Block a user