mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-02 06:43:00 +00:00
test/zdtmp: add a test to C/R shared memory file descriptors
Any shared memory region can be openned via /proc/self/map_files. Signed-off-by: Andrei Vagin <avagin@gmail.com>
This commit is contained in:
parent
10b1d46f67
commit
c40c09cbbf
5 changed files with 195 additions and 0 deletions
|
|
@ -224,6 +224,8 @@ TST_NOFILE := \
|
|||
memfd01 \
|
||||
memfd02 \
|
||||
memfd03 \
|
||||
shmemfd \
|
||||
shmemfd-priv \
|
||||
# jobctl00 \
|
||||
|
||||
ifneq ($(ARCH),arm)
|
||||
|
|
|
|||
84
test/zdtm/static/shmemfd-priv.c
Normal file
84
test/zdtm/static/shmemfd-priv.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
const char *test_doc = "Test C/R of shared memory file descriptors";
|
||||
const char *test_author = "Andrei Vagin <avagin@gmail.com>";
|
||||
|
||||
#define err(exitcode, msg, ...) ({ pr_perror(msg, ##__VA_ARGS__); exit(exitcode); })
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *addr, *priv_addr, *addr2;
|
||||
char path[4096];
|
||||
int fd;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
addr = mmap(NULL, 5 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
pr_perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*(int *) addr = 1;
|
||||
*(int *) (addr + PAGE_SIZE) = 11;
|
||||
*(int *) (addr + 2 * PAGE_SIZE) = 111;
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/self/map_files/%lx-%lx",
|
||||
(long)addr, (long)addr + 5 * PAGE_SIZE);
|
||||
fd = open(path, O_RDWR | O_LARGEFILE);
|
||||
if (fd < 0)
|
||||
err(1, "Can't open %s", path);
|
||||
|
||||
priv_addr = mmap(NULL, 5 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, PAGE_SIZE);
|
||||
if (priv_addr == MAP_FAILED) {
|
||||
pr_perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr2 = mmap(NULL, 5 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 2 * PAGE_SIZE);
|
||||
if (addr2 == MAP_FAILED) {
|
||||
pr_perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*(int *) (priv_addr + PAGE_SIZE) = 22;
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
if (*(int *) (priv_addr + PAGE_SIZE) != 22) {
|
||||
fail("the second page of the private mapping is corrupted");
|
||||
return 1;
|
||||
}
|
||||
if (*(int *) (priv_addr) != 11) {
|
||||
fail("the first page of the private mapping is corrupted");
|
||||
return 1;
|
||||
}
|
||||
if (*(int *) (addr2) != 111) {
|
||||
fail("the first page of the second shared mapping is corrupted");
|
||||
return 1;
|
||||
}
|
||||
*(int *) (addr2) = 333;
|
||||
if (*(int *) (addr + 2 * PAGE_SIZE) != 333) {
|
||||
fail("the first page of the second shared mapping isn't shared");
|
||||
return 1;
|
||||
}
|
||||
*(int *) (addr + 3 * PAGE_SIZE) = 444;
|
||||
if (*(int *) (priv_addr + 2 * PAGE_SIZE) != 444) {
|
||||
fail("the third page of the private mapping is corrupted");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pass();
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
test/zdtm/static/shmemfd-priv.desc
Normal file
1
test/zdtm/static/shmemfd-priv.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{'flavor': 'h ns', 'flags': 'suid'}
|
||||
107
test/zdtm/static/shmemfd.c
Normal file
107
test/zdtm/static/shmemfd.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "zdtmtst.h"
|
||||
|
||||
const char *test_doc = "Test C/R of shared memory file descriptors";
|
||||
const char *test_author = "Andrei Vagin <avagin@gmail.com>";
|
||||
|
||||
#define err(exitcode, msg, ...) ({ pr_perror(msg, ##__VA_ARGS__); exit(exitcode); })
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd, fl_flags1, fl_flags2, fd_flags1, fd_flags2;
|
||||
struct statfs statfs1, statfs2;
|
||||
off_t pos1, pos2;
|
||||
char path[4096];
|
||||
char buf[5];
|
||||
void *addr;
|
||||
|
||||
test_init(argc, argv);
|
||||
|
||||
addr = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
pr_perror("mmap");
|
||||
return 1;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), "/proc/self/map_files/%lx-%lx",
|
||||
(long)addr, (long)addr + PAGE_SIZE);
|
||||
fd = open(path, O_RDWR | O_LARGEFILE);
|
||||
if (fd < 0)
|
||||
err(1, "Can't open %s", path);
|
||||
ftruncate(fd, 0);
|
||||
munmap(addr, PAGE_SIZE);
|
||||
|
||||
if (fcntl(fd, F_SETFL, O_APPEND) < 0)
|
||||
err(1, "Can't get fl flags");
|
||||
|
||||
if ((fl_flags1 = fcntl(fd, F_GETFL)) == -1)
|
||||
err(1, "Can't get fl flags");
|
||||
|
||||
if ((fd_flags1 = fcntl(fd, F_GETFD)) == -1)
|
||||
err(1, "Can't get fd flags");
|
||||
|
||||
if (fstatfs(fd, &statfs1) < 0)
|
||||
err(1, "statfs issue");
|
||||
|
||||
if (write(fd, "hello", 5) != 5)
|
||||
err(1, "write error");
|
||||
|
||||
pos1 = 3;
|
||||
if (lseek(fd, pos1, SEEK_SET) < 0)
|
||||
err(1, "seek error");
|
||||
|
||||
test_daemon();
|
||||
test_waitsig();
|
||||
|
||||
if ((fl_flags2 = fcntl(fd, F_GETFL)) == -1)
|
||||
err(1, "Can't get fl flags");
|
||||
|
||||
if (fl_flags1 != fl_flags2) {
|
||||
fail("fl flags differs %x %x", fl_flags1, fl_flags2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((fd_flags2 = fcntl(fd, F_GETFD)) == -1)
|
||||
err(1, "Can't get fd flags");
|
||||
|
||||
if (fd_flags1 != fd_flags2) {
|
||||
fail("fd flags differs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fstatfs(fd, &statfs2) < 0)
|
||||
err(1, "statfs issue");
|
||||
|
||||
if (statfs1.f_type != statfs2.f_type) {
|
||||
fail("statfs.f_type differs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pos2 = lseek(fd, 0, SEEK_CUR);
|
||||
if (pos1 != pos2) {
|
||||
fail("position differs");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pread(fd, buf, sizeof(buf), 0) != sizeof(buf)) {
|
||||
fail("read problem");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf, "hello", sizeof(buf))) {
|
||||
fail("content mismatch");
|
||||
return 1;
|
||||
}
|
||||
|
||||
pass();
|
||||
|
||||
return 0;
|
||||
}
|
||||
1
test/zdtm/static/shmemfd.desc
Normal file
1
test/zdtm/static/shmemfd.desc
Normal file
|
|
@ -0,0 +1 @@
|
|||
{'flavor': 'h ns', 'flags': 'suid'}
|
||||
Loading…
Add table
Add a link
Reference in a new issue