Tell CRIU to use an external pid namespace if necessary

Trying to checkpoint a container out of pod in cri-o fails with:

  Error (criu/namespaces.c:1081): Can't dump a pid namespace without the process init

Starting with the upcoming CRIU release 3.15, CRIU can be told to ignore
the PID namespace during checkpointing and to restore processes into an
existing network namespace.

With the changes from this commit and CRIU 3.15 it is possible to
checkpoint a container out of a pod in cri-o.

Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
Adrian Reber
2020-07-21 15:33:24 +00:00
committed by Adrian Reber
parent 610c5ad75c
commit 09e103b01e

View File

@@ -837,13 +837,19 @@ func (c *linuxContainer) handleCriuConfigurationFile(rpcOpts *criurpc.CriuOpts)
}
func (c *linuxContainer) criuSupportsExtNS(t configs.NamespaceType) bool {
var minVersion int
switch t {
case configs.NEWNET:
// CRIU supports different external namespace with different released CRIU versions.
// For network namespaces to work we need at least criu 3.11.0 => 31100.
return c.checkCriuVersion(31100) == nil
minVersion = 31100
case configs.NEWPID:
// For PID namespaces criu 31500 is needed.
minVersion = 31500
default:
return false
}
return false
return c.checkCriuVersion(minVersion) == nil
}
func (c *linuxContainer) criuNsToKey(t configs.NamespaceType) string {
@@ -979,6 +985,11 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
return err
}
// Same for possible external PID namespaces
if err := c.handleCheckpointingExternalNamespaces(&rpcOpts, configs.NEWPID); err != nil {
return err
}
// CRIU can use cgroup freezer; when rpcOpts.FreezeCgroup
// is not set, CRIU uses ptrace() to pause the processes.
// Note cgroup v2 freezer is only supported since CRIU release 3.14.
@@ -1304,6 +1315,11 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
return err
}
// Same for PID namespaces.
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWPID); err != nil {
return err
}
// This will modify the rootfs of the container in the same way runc
// modifies the container during initial creation.
if err := c.prepareCriuRestoreMounts(c.config.Mounts); err != nil {