criu/test/zdtm/static/maps01.c
Dmitry Safonov ab33ae2d95 test/maps01: document mmap() failures
Arm32 devices often have poor amount of RAM. E.g., RPI2 board
has only 1Gb memory. This lead to failures with maps01 test,
which tries to mmap() 1Gb of memory. The failures of test is
not very evident - let's document mmap() errors here to
blow some light on the situation.

Acked-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Dmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
2017-04-17 18:35:58 +03:00

183 lines
3.8 KiB
C

#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <linux/limits.h>
#include "zdtmtst.h"
#define MEM_SIZE (1LU << 30)
#define MEM_OFFSET (1LU << 29)
#define MEM_OFFSET2 (MEM_SIZE - PAGE_SIZE)
#define MEM_OFFSET3 (20LU * PAGE_SIZE)
const char *test_doc = "Test shared memory";
const char *test_author = "Andrew Vagin <avagin@openvz.org";
int main(int argc, char ** argv)
{
void *m, *m2, *p, *p2;
char path[PATH_MAX];
uint32_t crc;
pid_t pid = -1;
int status, fd;
task_waiter_t t;
test_init(argc, argv);
task_waiter_init(&t);
m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (m == MAP_FAILED) {
pr_err("Failed to mmap %lu Mb shared anonymous R/W memory\n",
MEM_SIZE >> 20);
goto err;
}
p = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) {
pr_err("Failed to mmap %ld Mb shared anonymous R/W memory\n",
MEM_SIZE >> 20);
goto err;
}
p2 = mmap(NULL, MEM_OFFSET, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p2 == MAP_FAILED) {
pr_err("Failed to mmap %lu Mb anonymous memory\n",
MEM_OFFSET >> 20);
goto err;
}
pid = test_fork();
if (pid < 0) {
pr_err("Fork failed with %d\n", pid);
goto err;
} else if (pid == 0) {
void *p3;
p3 = mmap(NULL, MEM_OFFSET3, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (p3 == MAP_FAILED) {
pr_err("Failed to mmap %lu Mb anonymous R/W memory\n",
MEM_OFFSET3 >> 20);
goto err;
}
crc = ~0;
datagen(m + MEM_OFFSET, PAGE_SIZE, &crc);
crc = ~0;
datagen(m + MEM_OFFSET2, PAGE_SIZE, &crc);
crc = ~0;
datagen(p + MEM_OFFSET + MEM_OFFSET3, PAGE_SIZE, &crc);
crc = ~0;
datagen(p + MEM_OFFSET + 2 * MEM_OFFSET3, PAGE_SIZE, &crc);
crc = ~0;
datagen(p + MEM_OFFSET3, PAGE_SIZE, &crc);
crc = ~0;
datagen(p3, PAGE_SIZE, &crc);
task_waiter_complete(&t, 1);
test_waitsig();
crc = ~0;
status = datachk(m + MEM_OFFSET, PAGE_SIZE, &crc);
if (status)
return 1;
crc = ~0;
status = datachk(m + MEM_OFFSET2, PAGE_SIZE, &crc);
if (status)
return 1;
crc = ~0;
status = datachk(m + PAGE_SIZE, PAGE_SIZE, &crc);
if (status)
return 1;
crc = ~0;
status = datachk(p + MEM_OFFSET + 2 * MEM_OFFSET3, PAGE_SIZE, &crc);
if (status)
return 1;
crc = ~0;
status = datachk(p + MEM_OFFSET3, PAGE_SIZE, &crc);
if (status)
return 1;
crc = ~0;
status = datachk(p3, PAGE_SIZE, &crc);
if (status)
return 1;
return 0;
}
task_waiter_wait4(&t, 1);
munmap(p, MEM_OFFSET);
p2 = mremap(p + MEM_OFFSET, MEM_OFFSET, MEM_OFFSET, MREMAP_FIXED | MREMAP_MAYMOVE, p2);
if (p2 == MAP_FAILED)
goto err;
snprintf(path, PATH_MAX, "/proc/self/map_files/%lx-%lx",
(unsigned long) m,
(unsigned long) m + MEM_SIZE);
fd = open(path, O_RDWR);
if (fd == -1) {
pr_perror("Can't open file %s", path);
goto err;
}
m2 = mmap(NULL, PAGE_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, MEM_OFFSET3);
if (m2 == MAP_FAILED) {
pr_perror("Can't map file %s", path);
goto err;
}
close(fd);
munmap(m, PAGE_SIZE);
munmap(m + PAGE_SIZE * 10, PAGE_SIZE);
munmap(m + MEM_OFFSET2, PAGE_SIZE);
crc = ~0;
datagen(m + PAGE_SIZE, PAGE_SIZE, &crc);
crc = ~0;
datagen(m2, PAGE_SIZE, &crc);
test_daemon();
test_waitsig();
kill(pid, SIGTERM);
wait(&status);
if (WIFEXITED(status)) {
if (WEXITSTATUS(status))
goto err;
} else
goto err;
crc = ~0;
if (datachk(m + MEM_OFFSET, PAGE_SIZE, &crc))
goto err;
crc = ~0;
if (datachk(m2, PAGE_SIZE, &crc))
goto err;
crc = ~0;
if (datachk(p2 + MEM_OFFSET3, PAGE_SIZE, &crc))
goto err;
pass();
return 0;
err:
if (waitpid(-1, NULL, WNOHANG) == 0) {
kill(pid, SIGTERM);
wait(NULL);
}
return 1;
}