criu

Mount V2: Detailed Algorithm

The Mount V2 engine (originally developed by Virtuozzo and later merged into upstream CRIU) is designed to resolve complex issues with restoring sharing groups, over-mounted files, and cross-namespace bind mounts. This document provides a technical breakdown of its operation.

1. Mount Image Processing Stage

During initialization, CRIU processes the mount images for all namespaces to build an internal model of the filesystem state:

2. Pre-Fork Mounting Stage

This stage is executed from the init task in a dedicated “service” mount namespace before the target process tree is forked:

  1. Plain Mounting: CRIU walks the merged mount tree and creates all mounts in a “plain” (unattached) and “private” state.
  2. Source Resolution: For each mount, CRIU identifies its source (a real filesystem, a bind mount from another already-mounted superblock, or an external source).
  3. Cross-Namespace Handling: By maintaining all mounts within a single service namespace during this stage, CRIU can easily handle bind mounts that cross namespace boundaries.

3. Propagation and Shared Group Restoration

CRIU restores complex propagation relationships using modern kernel APIs:

4. Namespace Transition and Final Positioning

For each target mount namespace being restored:

  1. Unshare: CRIU calls unshare(CLONE_NEWNS) to create a fresh, empty mount namespace.
  2. Tree Positioning: Move the “plain” mounts from the root yard into their final hierarchical positions within the new namespace using move_mount().
  3. Pivot Root: Execute pivot_root() to switch to the new namespace root, effectively hiding the temporary “yard” and finalizing the mount hierarchy.

5. Post-Fork Fixups

Certain mounts cannot be fully restored until the process tree is established:

See also