Restoring a complex process tree is a multi-step operation coordinated by a central CRIU process and executed across the newly created process tree. Each stage is synchronized to ensure that dependencies (such as shared files and parent-child relationships) are met and security invariants are maintained.
CRIU uses a global state machine (defined as CR_STATE_* constants) to coordinate between the main CRIU process and the tasks being restored. Tasks use futexes in shared memory to signal the completion of their work in each stage and wait for the coordinator to signal the transition to the next stage.
CR_STATE_ROOT_TASK)The main CRIU process performs initial image analysis, resolves shared resources, and prepares the restorer code blobs. It then forks the root task of the tree being restored. The root task performs initial pre-checks and begins its environmental setup.
CR_STATE_PREPARE_NAMESPACES)The root task (and specialized helpers) initializes the required namespaces (Mount, Network, IPC, UTS, Time). This ensures that all subsequent processes in the tree are created within the correct containerized environment from the moment of their birth.
CR_STATE_FORKING)The process tree is recursively forked until all processes are recreated.
clone3() system call or the ns_last_pid interface.CR_STATE_RESTORE)This is the primary stage where the bulk of the application state is reconstructed:
SCM_RIGHTS.mmap().CR_STATE_RESTORE_SIGCHLD)Tasks restore their original SIGCHLD handlers. This stage serves as a critical synchronization point to transition from CRIU’s internal error-tracking (which relies on SIGCHLD to detect failed restoration steps in children) to the application’s original signal handling logic.
CR_STATE_RESTORE_CREDS)For security reasons, this is the final stage before the application resumes execution. CRIU ensures that sensitive attributes are restored in a specific order:
pdeath_sig) are re-established.By delaying these steps until the very end, CRIU prevents potential security vulnerabilities where a partially-restored process could be intercepted or manipulated while in a transitional state.
CR_STATE_COMPLETE)The tasks execute their final sigreturn() call from within the Restorer PIE. This restores the original register state (including the instruction pointer) and jumps the CPU back into the application’s code. The process tree is now fully restored and running.