Checkpoint/Restore
Basic design
Checkpoint
The checkpoint procedure relies heavily on /proc file system (it's a general place where crtools takes all the information it needs). Which includes
- Files descriptors information (via /proc/$pid/fd and /proc/$pid/fdinfo).
- Pipes parameters.
- Memory maps (via /proc/$pid/maps).
The process dumper (lets call it a dumper further) does the following steps during checkpoint stage
- A $pid of a process group leader is obtained from the command line.
- By using this $pid the dumper walks though /proc/$pid/status and gathers children $pids recursively. At the end we will have a process tree.
- Then it takes every $pid from a process tree, sends SIGSTOP to every process found, and performs the following steps on each $pid.
- Collects VMA areas by parsing /proc/$pid/maps.
- Seizes a task via relatively new ptrace interface. Seizing a task means to put it into a special state when the task have no idea if it's being operated by ptrace.
- Core parameters of a task (such as registers and friends) are being dumped via ptrace interface and parsing /proc/$pid/stat entry.
- The dumper injects a parasite code into a task via ptrace interface. This allows us to dump pages of a task right from within the task's address space.
- An injection procedure is pretty simple - the dumper scans executable VMA areas of a task (which were collected previously) and tests if there a place for
syscall
call, then (by ptrace as well) it substitutes an original code withsyscall
instructions and creates a new VMA area inside process address space. - Finally parasite code get copied into the new VMA and the former code which was modified during parasite bootstrap procedure get restored.
- An injection procedure is pretty simple - the dumper scans executable VMA areas of a task (which were collected previously) and tests if there a place for
- Then (by using a parasite code) the dumper flushes contents of a task's pages to the file. And pulls out parasite code block completely, since we don't need it anymore.
- Once parasite removed a task get unseized via ptrace call but it remains stopped still.
- The dumper writes out files and pipes parameter and data.
- The procedure continues for every $pid.
Restore
The restore procedure (aka restorer) proceed in the following steps
- A process tree has been read from a file.
- Every process started with saved (i.e. original) $pid via
clone()
call. - Files and pipes are restored (by restored it's meant - they are opened and positioned).
- A new memory map is created, filled with data the program had at checkpoint time.
- Finally the program is kicked to start with rt_sigreturn system call.