Skip to content

Commit fb59e6f

Browse files
authored
Merge pull request #2583 from adrianreber/join-more-namespaces
restore: tell CRIU to use existing namespaces
2 parents 27227a9 + 2ccefa6 commit fb59e6f

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

libcontainer/container_linux.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,44 @@ func (c *linuxContainer) handleCheckpointingExternalNamespaces(rpcOpts *criurpc.
866866
return nil
867867
}
868868

869+
func (c *linuxContainer) handleRestoringNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File) error {
870+
for _, ns := range c.config.Namespaces {
871+
switch ns.Type {
872+
case configs.NEWNET, configs.NEWPID:
873+
// If the container is running in a network or PID namespace and has
874+
// a path to the network or PID namespace configured, we will dump
875+
// that network or PID namespace as an external namespace and we
876+
// will expect that the namespace exists during restore.
877+
// This basically means that CRIU will ignore the namespace
878+
// and expect it to be setup correctly.
879+
if err := c.handleRestoringExternalNamespaces(rpcOpts, extraFiles, ns.Type); err != nil {
880+
return err
881+
}
882+
default:
883+
// For all other namespaces except NET and PID CRIU has
884+
// a simpler way of joining the existing namespace if set
885+
nsPath := c.config.Namespaces.PathOf(ns.Type)
886+
if nsPath == "" {
887+
continue
888+
}
889+
if ns.Type == configs.NEWCGROUP {
890+
// CRIU has no code to handle NEWCGROUP
891+
return fmt.Errorf("Do not know how to handle namespace %v", ns.Type)
892+
}
893+
// CRIU has code to handle NEWTIME, but it does not seem to be defined in runc
894+
895+
// CRIU will issue a warning for NEWUSER:
896+
// criu/namespaces.c: 'join-ns with user-namespace is not fully tested and dangerous'
897+
rpcOpts.JoinNs = append(rpcOpts.JoinNs, &criurpc.JoinNamespace{
898+
Ns: proto.String(configs.NsName(ns.Type)),
899+
NsFile: proto.String(nsPath),
900+
})
901+
}
902+
}
903+
904+
return nil
905+
}
906+
869907
func (c *linuxContainer) handleRestoringExternalNamespaces(rpcOpts *criurpc.CriuOpts, extraFiles *[]*os.File, t configs.NamespaceType) error {
870908
if !c.criuSupportsExtNS(t) {
871909
return nil
@@ -1297,15 +1335,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
12971335

12981336
c.handleCriuConfigurationFile(req.Opts)
12991337

1300-
// Same as during checkpointing. If the container has a specific network namespace
1301-
// assigned to it, this now expects that the checkpoint will be restored in a
1302-
// already created network namespace.
1303-
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWNET); err != nil {
1304-
return err
1305-
}
1306-
1307-
// Same for PID namespaces.
1308-
if err := c.handleRestoringExternalNamespaces(req.Opts, &extraFiles, configs.NEWPID); err != nil {
1338+
if err := c.handleRestoringNamespaces(req.Opts, &extraFiles); err != nil {
13091339
return err
13101340
}
13111341

0 commit comments

Comments
 (0)