If I perform a mmap()
on some file or a device in /dev/ that exposes memory, what happens to that mapping if the file is deleted or that device disconnected?
I've written a test program to experiment but I can't find any solid documentation on what should happen. The test program does the following
#include <stdio.h>
#include <fcntl.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
int fd = open("test_file", O_CREAT | O_RDWR);
uint32_t data[10000] = {0};
data[3] = 22;
write(fd, data, sizeof data);
sync();
struct stat s;
fstat(fd, &s);
uint32_t *map = (uint32_t *)mmap(NULL, s.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
sleep(10);
printf("%u\n", *(map+3));
*(map+9000) = 91;
printf("%u\n", *(map+9000));
return 0;
}
My page size is 4096 bytes so I made the file larger than that so the map would span multiple pages. During that 10s sleep I run the following commands:
$ rm test_file
$ sync; echo 3 > /proc/sys/vm/drop_caches
Which I believe should destroy the backing file of the map and remove all pages so that it must seek the backing file out to perform any operations on it. Then after that 10s sleep the program attempts to read from page 1 and w/r to page 3.
Surprisingly the 2 values I get printed back out are 22 and 91
Why does this happen, is this behavior guaranteed or undefined? Is it because I was using a regular file and not a device? What if the mapping was really large, would things change? Should I expect to get a SIGSEGV or a SIGBUS under some conditions?