mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
restore: tell CRIU to use existing namespaces
runc already tells CRIU to restore into an existing network or PID namespace if there is a path to a namespace specified in config.json. PID and network have special handling in CRIU using CRIU's inherit_fd interface. For UTS, IPC and MOUNT namespaces CRIU can join those existing namespaces using CRIU's join_ns interface. This is especially interesting for environments where containers are running in a pod which already has running containers (pause for example) with namespaces configured and the restored container needs to join these namespaces. CRIU has no support to join an existing CGROUP namespace (yet?) why restoring a container with a path specified to a CGROUP namespace will be aborted by runc. CRIU would have support to restore a container into an existing time namespace, but runc does not yet seem to support time namespaces. Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
@@ -879,6 +879,44 @@ func (c *linuxContainer) handleCheckpointingExternalNamespaces(rpcOpts *criurpc.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) handleRestoringNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File) error {
|
||||
for _, ns := range c.config.Namespaces {
|
||||
switch ns.Type {
|
||||
case configs.NEWNET, configs.NEWPID:
|
||||
// If the container is running in a network or PID namespace and has
|
||||
// a path to the network or PID namespace configured, we will dump
|
||||
// that network or PID namespace as an external namespace and we
|
||||
// will expect that the namespace exists during restore.
|
||||
// This basically means that CRIU will ignore the namespace
|
||||
// and expect it to be setup correctly.
|
||||
if err := c.handleRestoringExternalNamespaces(rpcOpts, extraFiles, ns.Type); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
// For all other namespaces except NET and PID CRIU has
|
||||
// a simpler way of joining the existing namespace if set
|
||||
nsPath := c.config.Namespaces.PathOf(ns.Type)
|
||||
if nsPath == "" {
|
||||
continue
|
||||
}
|
||||
if ns.Type == configs.NEWCGROUP {
|
||||
// CRIU has no code to handle NEWCGROUP
|
||||
return fmt.Errorf("Do not know how to handle namespace %v", ns.Type)
|
||||
}
|
||||
// CRIU has code to handle NEWTIME, but it does not seem to be defined in runc
|
||||
|
||||
// CRIU will issue a warning for NEWUSER:
|
||||
// criu/namespaces.c: 'join-ns with user-namespace is not fully tested and dangerous'
|
||||
rpcOpts.JoinNs = append(rpcOpts.JoinNs, &criurpc.JoinNamespace{
|
||||
Ns: proto.String(configs.NsName(ns.Type)),
|
||||
NsFile: proto.String(nsPath),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File, t configs.NamespaceType) error {
|
||||
if !c.criuSupportsExtNS(t) {
|
||||
return nil
|
||||
@@ -1310,15 +1348,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
|
||||
c.handleCriuConfigurationFile(req.Opts)
|
||||
|
||||
// Same as during checkpointing. If the container has a specific network namespace
|
||||
// assigned to it, this now expects that the checkpoint will be restored in a
|
||||
// already created network namespace.
|
||||
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWNET); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Same for PID namespaces.
|
||||
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWPID); err != nil {
|
||||
if err := c.handleRestoringNamespaces(req.Opts, &extraFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user