Line 1: |
Line 1: |
− | This articles describes some intricacies of handling shared memory mappings,
| + | Every process has one or more memory mappings, i.e. regions of virtual memory it allows to use. |
− | i.e. anonymous (not file-based) mappings that are shared between a few processes. | + | Some such mappings can be shared between a few processes, and they are called shared mappings. |
| + | In other words, these are shared '''anonymous (not file-based) memory mappings'''. |
| + | The article describes some intricacies of handling such mappings. |
| | | |
| == Checkpoint == | | == Checkpoint == |
| | | |
− | Every process has one or more so called mmapings -- regions of virtual memory which it's allowed to use. Some mappings can be shared between a few processes.
| + | During the checkpointing, CRIU needs to figure out all the shared mappings in order to dump them as such. |
− | During the checkpointing, CRIU need to figure out all the shared mappings in order to dump them as such. | |
| | | |
− | It does so by performing <code>fstatat()</code> for each entry in <code>/proc/$PID/map_files/</code>, | + | It does so by calling <code>fstatat()</code> on each entry found in the <code>/proc/$PID/map_files/</code>, |
− | noting the ''device'' and ''inode'' fields of the structure returned by fstatat(). This information | + | noting the ''device:inode'' pair of the structure returned by <code>fstatat()</code>. Now, if some processes |
− | is collected and sorted. Now, if any few processes have a mapping with same ''device'' and ''inode'',
| + | have a mapping with the same ''device:inode'' pair, this mapping is marked as shared between these processes |
− | this mapping is a shared one and should be dumped as such. | + | and dumped as such. |
| | | |
− | It's important to note that the above mechanism works not just for the file-based mappings,
| + | Note that <code>fstatat()</code> works because the kernel actually creates a hidden |
− | but also for the anonymous ones. For an anonymous mapping, kernel actually creates a hidden
| + | tmpfs file, not visible from any tmpfs mounts, but accessible via its |
− | tmpfs file, and so <code>fstatat()</code> on the <code>/proc/$PID/map_files/</code> entry | + | <code>/proc/$PID/map_files/</code> entry. |
− | works the same way as for other files. The tmpfs file itself is not visible from any tmpfs
| + | |
− | mounts, but can be opened via its <code>map_files</code> entry.
| + | Dumping a mapping means two things: |
| + | * writing an entry into process' mm.img file; |
| + | * storing the actual mapping data (contents). |
| + | For shared mappings, the contents is stored into a pair of image files: pagemap-shmem.img and pages.img. |
| + | For details, see [[Memory dumps]]. |
| + | |
| + | Note that different processes can map different parts of a shared memory segment. |
| + | In this case, CRIU first collects mapping offsets and lengths from all the processes |
| + | to determine the total segment size, then reads all the parts contents |
| + | from the respective processes. |
| | | |
| == Restore == | | == Restore == |
Line 80: |
Line 90: |
| [[Category:Memory]] | | [[Category:Memory]] |
| [[Category:Under the hood]] | | [[Category:Under the hood]] |
| + | [[Category:Editor help needed]] |