ct: give criu informations about cgroup mounts
Actually cgroup mounts are bind-mounts, so they should be handled by the same way. Reported-by: Ross Boucher <rboucher@gmail.com> Signed-off-by: Andrey Vagin <avagin@openvz.org>
This commit is contained in:
parent
1eeb86fbf2
commit
af4a5e708a
|
@ -293,6 +293,19 @@ func (c *linuxContainer) checkCriuVersion() error {
|
|||
|
||||
const descriptors_filename = "descriptors.json"
|
||||
|
||||
func (c *linuxContainer) addCriuDumpMount(req *criurpc.CriuReq, m *configs.Mount) {
|
||||
mountDest := m.Destination
|
||||
if strings.HasPrefix(mountDest, c.config.Rootfs) {
|
||||
mountDest = mountDest[len(c.config.Rootfs):]
|
||||
}
|
||||
|
||||
extMnt := &criurpc.ExtMountMap{
|
||||
Key: proto.String(mountDest),
|
||||
Val: proto.String(mountDest),
|
||||
}
|
||||
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
@ -356,22 +369,25 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
|||
}
|
||||
|
||||
t := criurpc.CriuReqType_DUMP
|
||||
req := criurpc.CriuReq{
|
||||
req := &criurpc.CriuReq{
|
||||
Type: &t,
|
||||
Opts: &rpcOpts,
|
||||
}
|
||||
|
||||
for _, m := range c.config.Mounts {
|
||||
if m.Device == "bind" {
|
||||
mountDest := m.Destination
|
||||
if strings.HasPrefix(mountDest, c.config.Rootfs) {
|
||||
mountDest = mountDest[len(c.config.Rootfs):]
|
||||
switch m.Device {
|
||||
case "bind":
|
||||
c.addCriuDumpMount(req, m)
|
||||
break
|
||||
case "cgroup":
|
||||
binds, err := getCgroupMounts(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
extMnt := new(criurpc.ExtMountMap)
|
||||
extMnt.Key = proto.String(mountDest)
|
||||
extMnt.Val = proto.String(mountDest)
|
||||
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
|
||||
for _, b := range binds {
|
||||
c.addCriuDumpMount(req, b)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -387,13 +403,26 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = c.criuSwrk(nil, &req, criuOpts)
|
||||
err = c.criuSwrk(nil, req, criuOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *linuxContainer) addCriuRestoreMount(req *criurpc.CriuReq, m *configs.Mount) {
|
||||
mountDest := m.Destination
|
||||
if strings.HasPrefix(mountDest, c.config.Rootfs) {
|
||||
mountDest = mountDest[len(c.config.Rootfs):]
|
||||
}
|
||||
|
||||
extMnt := &criurpc.ExtMountMap{
|
||||
Key: proto.String(mountDest),
|
||||
Val: proto.String(m.Source),
|
||||
}
|
||||
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
|
||||
}
|
||||
|
||||
func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
@ -449,7 +478,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
|||
defer syscall.Unmount(root, syscall.MNT_DETACH)
|
||||
|
||||
t := criurpc.CriuReqType_RESTORE
|
||||
req := criurpc.CriuReq{
|
||||
req := &criurpc.CriuReq{
|
||||
Type: &t,
|
||||
Opts: &criurpc.CriuOpts{
|
||||
ImagesDirFd: proto.Int32(int32(imageDir.Fd())),
|
||||
|
@ -468,16 +497,19 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
|||
},
|
||||
}
|
||||
for _, m := range c.config.Mounts {
|
||||
if m.Device == "bind" {
|
||||
mountDest := m.Destination
|
||||
if strings.HasPrefix(mountDest, c.config.Rootfs) {
|
||||
mountDest = mountDest[len(c.config.Rootfs):]
|
||||
switch m.Device {
|
||||
case "bind":
|
||||
c.addCriuRestoreMount(req, m)
|
||||
break
|
||||
case "cgroup":
|
||||
binds, err := getCgroupMounts(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
extMnt := new(criurpc.ExtMountMap)
|
||||
extMnt.Key = proto.String(mountDest)
|
||||
extMnt.Val = proto.String(m.Source)
|
||||
req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
|
||||
for _, b := range binds {
|
||||
c.addCriuRestoreMount(req, b)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, iface := range c.config.Networks {
|
||||
|
@ -515,7 +547,7 @@ func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
|
|||
}
|
||||
}
|
||||
|
||||
err = c.criuSwrk(process, &req, criuOpts)
|
||||
err = c.criuSwrk(process, req, criuOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -170,27 +170,10 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
|
|||
}
|
||||
}
|
||||
case "cgroup":
|
||||
mounts, err := cgroups.GetCgroupMounts()
|
||||
binds, err := getCgroupMounts(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var binds []*configs.Mount
|
||||
for _, mm := range mounts {
|
||||
dir, err := mm.GetThisCgroupDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
relDir, err := filepath.Rel(mm.Root, dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
binds = append(binds, &configs.Mount{
|
||||
Device: "bind",
|
||||
Source: filepath.Join(mm.Mountpoint, relDir),
|
||||
Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")),
|
||||
Flags: syscall.MS_BIND | syscall.MS_REC | m.Flags,
|
||||
})
|
||||
}
|
||||
tmpfs := &configs.Mount{
|
||||
Source: "tmpfs",
|
||||
Device: "tmpfs",
|
||||
|
@ -211,6 +194,34 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
|
||||
mounts, err := cgroups.GetCgroupMounts()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var binds []*configs.Mount
|
||||
|
||||
for _, mm := range mounts {
|
||||
dir, err := mm.GetThisCgroupDir()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
relDir, err := filepath.Rel(mm.Root, dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
binds = append(binds, &configs.Mount{
|
||||
Device: "bind",
|
||||
Source: filepath.Join(mm.Mountpoint, relDir),
|
||||
Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")),
|
||||
Flags: syscall.MS_BIND | syscall.MS_REC | m.Flags,
|
||||
})
|
||||
}
|
||||
|
||||
return binds, nil
|
||||
}
|
||||
|
||||
// checkMountDestination checks to ensure that the mount destination is not over the
|
||||
// top of /proc or /sys.
|
||||
// dest is required to be an abs path and have any symlinks resolved before calling this function.
|
||||
|
|
Loading…
Reference in New Issue