Merge pull request #849 from avagin/emptyns
checkpoint: add the empty-ns option
This commit is contained in:
commit
3b447f8da5
|
@ -6,9 +6,11 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/codegangsta/cli"
|
||||
"github.com/opencontainers/runc/libcontainer"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
var checkpointCommand = cli.Command{
|
||||
|
@ -29,6 +31,7 @@ checkpointed.`,
|
|||
cli.StringFlag{Name: "page-server", Value: "", Usage: "ADDRESS:PORT of the page server"},
|
||||
cli.BoolFlag{Name: "file-locks", Usage: "handle file locks, for safety"},
|
||||
cli.StringFlag{Name: "manage-cgroups-mode", Value: "", Usage: "cgroups mode: 'soft' (default), 'full' and 'strict'."},
|
||||
cli.StringSliceFlag{Name: "empty-ns", Usage: "create a namespace, but don't restore its properies"},
|
||||
},
|
||||
Action: func(context *cli.Context) error {
|
||||
container, err := getContainer(context)
|
||||
|
@ -40,6 +43,9 @@ checkpointed.`,
|
|||
// these are the mandatory criu options for a container
|
||||
setPageServer(context, options)
|
||||
setManageCgroupsMode(context, options)
|
||||
if err := setEmptyNsMask(context, options); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := container.Checkpoint(options); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -88,3 +94,22 @@ func setManageCgroupsMode(context *cli.Context, options *libcontainer.CriuOpts)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
var namespaceMapping = map[specs.NamespaceType]int{
|
||||
specs.NetworkNamespace: syscall.CLONE_NEWNET,
|
||||
}
|
||||
|
||||
func setEmptyNsMask(context *cli.Context, options *libcontainer.CriuOpts) error {
|
||||
var nsmask int
|
||||
|
||||
for _, ns := range context.StringSlice("empty-ns") {
|
||||
f, exists := namespaceMapping[specs.NamespaceType(ns)]
|
||||
if !exists {
|
||||
return fmt.Errorf("namespace %q is not supported", ns)
|
||||
}
|
||||
nsmask |= f
|
||||
}
|
||||
|
||||
options.EmptyNs = uint32(nsmask)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -607,6 +607,27 @@ func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mo
|
|||
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
|
||||
}
|
||||
|
||||
func (c *linuxContainer) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) {
|
||||
for _, iface := range c.config.Networks {
|
||||
switch iface.Type {
|
||||
case "veth":
|
||||
veth := new(criurpc.CriuVethPair)
|
||||
veth.IfOut = proto.String(iface.HostInterfaceName)
|
||||
veth.IfIn = proto.String(iface.Name)
|
||||
req.Opts.Veths = append(req.Opts.Veths, veth)
|
||||
break
|
||||
case "loopback":
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, i := range criuOpts.VethPairs {
|
||||
veth := new(criurpc.CriuVethPair)
|
||||
veth.IfOut = proto.String(i.HostInterfaceName)
|
||||
veth.IfIn = proto.String(i.ContainerInterfaceName)
|
||||
req.Opts.Veths = append(req.Opts.Veths, veth)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
@ -690,23 +711,9 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
for _, iface := range c.config.Networks {
|
||||
switch iface.Type {
|
||||
case "veth":
|
||||
veth := new(criurpc.CriuVethPair)
|
||||
veth.IfOut = proto.String(iface.HostInterfaceName)
|
||||
veth.IfIn = proto.String(iface.Name)
|
||||
req.Opts.Veths = append(req.Opts.Veths, veth)
|
||||
break
|
||||
case "loopback":
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, i := range criuOpts.VethPairs {
|
||||
veth := new(criurpc.CriuVethPair)
|
||||
veth.IfOut = proto.String(i.HostInterfaceName)
|
||||
veth.IfIn = proto.String(i.ContainerInterfaceName)
|
||||
req.Opts.Veths = append(req.Opts.Veths, veth)
|
||||
|
||||
if criuOpts.EmptyNs&syscall.CLONE_NEWNET == 0 {
|
||||
c.restoreNetwork(req, criuOpts)
|
||||
}
|
||||
|
||||
// append optional manage cgroups mode
|
||||
|
|
Loading…
Reference in New Issue