9static int resize_backend(
int backend) {
11 struct rp_file file = {.fd = -1};
13 unsigned char* mapping = MAP_FAILED;
14 unsigned char* alias = MAP_FAILED;
15 const size_t boundary = rp_page + 137;
16 CHECK(rp_create(&file, backend) == 0);
17 alias_fd = rp_open_alias(&file);
19 mapping = mmap(NULL, 4 * rp_page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
20 alias = mmap(NULL, 2 * rp_page, PROT_READ | PROT_WRITE, MAP_SHARED, alias_fd, 0);
21 CHECK(mapping != MAP_FAILED && alias != MAP_FAILED);
22 CHECK(remap_file_pages(mapping, rp_page, 0, 6, 0) == 0);
23 CHECK(remap_file_pages(mapping + 2 * rp_page, rp_page, 0, 6, 0) == 0);
24 CHECK(remap_file_pages(mapping + 3 * rp_page, rp_page, 0, 0, 0) == 0);
25 CHECK(remap_file_pages(alias, rp_page, 0, 6, 0) == 0);
26 CHECK(rp_matches(mapping, 6 * rp_page, rp_page, 0));
27 CHECK(rp_matches(mapping + rp_page, rp_page, rp_page, 0));
28 CHECK(rp_matches(mapping + 2 * rp_page, 6 * rp_page, rp_page, 0));
29 CHECK(rp_matches(mapping + 3 * rp_page, 0, rp_page, 0));
30 CHECK(rp_matches(alias, 6 * rp_page, rp_page, 0));
31 CHECK(rp_matches(alias + rp_page, rp_page, rp_page, 0));
33 CHECK(mapping[2 * rp_page + 19] == 0xa1 && alias[19] == 0xa1);
35 CHECK(ftruncate(alias_fd, boundary) == 0);
36 CHECK(rp_size(file.fd, boundary) == 0 && rp_size(alias_fd, boundary) == 0);
38 CHECK(rp_resident(mapping, 4, 0xa,
"rebiased shrink main") == 0);
39 CHECK(rp_resident(alias, 2, 0x2,
"rebiased shrink alias") == 0);
40 CHECK(rp_fault(mapping, SIGBUS, 0) == 0);
41 CHECK(rp_fault(mapping + 2 * rp_page, SIGBUS, 0) == 0);
42 CHECK(rp_fault(alias, SIGBUS, 0) == 0);
43 CHECK(rp_matches(mapping + 3 * rp_page, 0, rp_page, 0));
44 CHECK(rp_matches(mapping + rp_page, rp_page, 137, 0));
45 CHECK(rp_matches(alias + rp_page, rp_page, 137, 0));
46 CHECK(rp_matches(mapping + boundary, boundary, rp_page - 137, 1));
47 CHECK(rp_matches(alias + boundary, boundary, rp_page - 137, 1));
48 CHECK(rp_contents(file.fd, 0, boundary, 0) == 0);
50 CHECK(ftruncate(alias_fd, 8 * rp_page) == 0 && rp_size(file.fd, 8 * rp_page) == 0);
51 CHECK(rp_contents(file.fd, boundary, 8 * rp_page - boundary, 1) == 0);
52 CHECK(rp_matches(mapping, 6 * rp_page, rp_page, 1));
53 CHECK(rp_matches(mapping + 2 * rp_page, 6 * rp_page, rp_page, 1));
54 CHECK(rp_matches(alias, 6 * rp_page, rp_page, 1));
55 CHECK(rp_matches(mapping + 3 * rp_page, 0, rp_page, 0));
56 CHECK(rp_matches(mapping + rp_page, rp_page, 137, 0));
57 CHECK(rp_matches(mapping + boundary, boundary, rp_page - 137, 1));
58 mapping[2 * rp_page + 73] = 0xd4;
59 CHECK(mapping[73] == 0xd4 && alias[73] == 0xd4);
61 CHECK(mapping[74] == 0x9a && mapping[2 * rp_page + 74] == 0x9a);
62 unsigned char bytes[2] = {0};
63 CHECK(pread(alias_fd, bytes,
sizeof(bytes), 6 * rp_page + 73) == (ssize_t)
sizeof(bytes));
64 CHECK(bytes[0] == 0xd4 && bytes[1] == 0x9a);
65 CHECK(msync(mapping, 4 * rp_page, MS_SYNC) == 0);
67 if (alias != MAP_FAILED)
68 munmap(alias, 2 * rp_page);
69 if (mapping != MAP_FAILED)
70 munmap(mapping, 4 * rp_page);
75 fprintf(stderr,
"REMAP-FILE-PAGES-CONTRACT: resize backend=%d\n", backend);
79static int sealed_shrink(
void) {
81 struct rp_file file = {.fd = -1};
82 unsigned char* mapping = MAP_FAILED;
83 CHECK(rp_create(&file, RP_MEMFD) == 0);
84 mapping = mmap(NULL, 2 * rp_page, PROT_READ, MAP_SHARED, file.fd, 0);
85 CHECK(mapping != MAP_FAILED && remap_file_pages(mapping, 2 * rp_page, 0, 6, 0) == 0);
86 CHECK(rp_matches(mapping, 6 * rp_page, 2 * rp_page, 0));
87 CHECK(fcntl(file.fd, F_ADD_SEALS, F_SEAL_SHRINK) == 0);
89 CHECK(ftruncate(file.fd, rp_page) == -1 && errno == EPERM);
90 CHECK(rp_size(file.fd, 8 * rp_page) == 0);
91 CHECK(rp_resident(mapping, 2, 3,
"sealed shrink preserved aliases") == 0);
92 CHECK(rp_matches(mapping, 6 * rp_page, 2 * rp_page, 0));
94 if (mapping != MAP_FAILED)
95 munmap(mapping, 2 * rp_page);
101 for (
int backend = RP_MEMFD; backend <= RP_EXT2; ++backend) {
102 if (resize_backend(backend))
105 return sealed_shrink();