Skip to content

Commit 21fbc47

Browse files
authored
Merge pull request #4871 from kolyshkin/1.3-4765
[1.3] Refactor/improve prepareCriuRestoreMounts
2 parents efcfc5d + 02c4128 commit 21fbc47

File tree

1 file changed

+34
-58
lines changed

1 file changed

+34
-58
lines changed

libcontainer/criu_linux.go

Lines changed: 34 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -523,34 +523,9 @@ func (c *Container) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) {
523523
}
524524
}
525525

526-
// makeCriuRestoreMountpoints makes the actual mountpoints for the
527-
// restore using CRIU. This function is inspired from the code in
528-
// rootfs_linux.go.
529-
func (c *Container) makeCriuRestoreMountpoints(m *configs.Mount) error {
530-
if m.Device == "cgroup" {
531-
// No mount point(s) need to be created:
532-
//
533-
// * for v1, mount points are saved by CRIU because
534-
// /sys/fs/cgroup is a tmpfs mount
535-
//
536-
// * for v2, /sys/fs/cgroup is a real mount, but
537-
// the mountpoint appears as soon as /sys is mounted
538-
return nil
539-
}
540-
// TODO: pass srcFD? Not sure if criu is impacted by issue #2484.
541-
me := mountEntry{Mount: m}
542-
// For all other filesystems, just make the target.
543-
if _, err := createMountpoint(c.config.Rootfs, me); err != nil {
544-
return fmt.Errorf("create criu restore mountpoint for %s mount: %w", me.Destination, err)
545-
}
546-
return nil
547-
}
548-
549-
// isPathInPrefixList is a small function for CRIU restore to make sure
550-
// mountpoints, which are on a tmpfs, are not created in the roofs.
551-
func isPathInPrefixList(path string, prefix []string) bool {
552-
for _, p := range prefix {
553-
if strings.HasPrefix(path, p+"/") {
526+
func isOnTmpfs(path string, mounts []*configs.Mount) bool {
527+
for _, m := range mounts {
528+
if m.Device == "tmpfs" && strings.HasPrefix(path, m.Destination+"/") {
554529
return true
555530
}
556531
}
@@ -564,17 +539,6 @@ func isPathInPrefixList(path string, prefix []string) bool {
564539
// This function also creates missing mountpoints as long as they
565540
// are not on top of a tmpfs, as CRIU will restore tmpfs content anyway.
566541
func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error {
567-
// First get a list of a all tmpfs mounts
568-
tmpfs := []string{}
569-
for _, m := range mounts {
570-
switch m.Device {
571-
case "tmpfs":
572-
tmpfs = append(tmpfs, m.Destination)
573-
}
574-
}
575-
// Now go through all mounts and create the mountpoints
576-
// if the mountpoints are not on a tmpfs, as CRIU will
577-
// restore the complete tmpfs content from its checkpoint.
578542
umounts := []string{}
579543
defer func() {
580544
for _, u := range umounts {
@@ -590,28 +554,40 @@ func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error {
590554
})
591555
}
592556
}()
557+
// Now go through all mounts and create the required mountpoints.
593558
for _, m := range mounts {
594-
if !isPathInPrefixList(m.Destination, tmpfs) {
595-
if err := c.makeCriuRestoreMountpoints(m); err != nil {
559+
// No cgroup mount point(s) need to be created:
560+
// * for v1, mount points are saved by CRIU because
561+
// /sys/fs/cgroup is a tmpfs mount;
562+
// * for v2, /sys/fs/cgroup is a real mount, but
563+
// the mountpoint appears as soon as /sys is mounted.
564+
if m.Device == "cgroup" {
565+
continue
566+
}
567+
// If the mountpoint is on a tmpfs, skip it as CRIU will
568+
// restore the complete tmpfs content from its checkpoint.
569+
if isOnTmpfs(m.Destination, mounts) {
570+
continue
571+
}
572+
if _, err := createMountpoint(c.config.Rootfs, mountEntry{Mount: m}); err != nil {
573+
return fmt.Errorf("create criu restore mountpoint for %s mount: %w", m.Destination, err)
574+
}
575+
// If the mount point is a bind mount, we need to mount
576+
// it now so that runc can create the necessary mount
577+
// points for mounts in bind mounts.
578+
// This also happens during initial container creation.
579+
// Without this CRIU restore will fail
580+
// See: https://github.com/opencontainers/runc/issues/2748
581+
// It is also not necessary to order the mount points
582+
// because during initial container creation mounts are
583+
// set up in the order they are configured.
584+
if m.Device == "bind" {
585+
if err := utils.WithProcfd(c.config.Rootfs, m.Destination, func(dstFd string) error {
586+
return mountViaFds(m.Source, nil, m.Destination, dstFd, "", unix.MS_BIND|unix.MS_REC, "")
587+
}); err != nil {
596588
return err
597589
}
598-
// If the mount point is a bind mount, we need to mount
599-
// it now so that runc can create the necessary mount
600-
// points for mounts in bind mounts.
601-
// This also happens during initial container creation.
602-
// Without this CRIU restore will fail
603-
// See: https://github.com/opencontainers/runc/issues/2748
604-
// It is also not necessary to order the mount points
605-
// because during initial container creation mounts are
606-
// set up in the order they are configured.
607-
if m.Device == "bind" {
608-
if err := utils.WithProcfd(c.config.Rootfs, m.Destination, func(dstFd string) error {
609-
return mountViaFds(m.Source, nil, m.Destination, dstFd, "", unix.MS_BIND|unix.MS_REC, "")
610-
}); err != nil {
611-
return err
612-
}
613-
umounts = append(umounts, m.Destination)
614-
}
590+
umounts = append(umounts, m.Destination)
615591
}
616592
}
617593
return nil

0 commit comments

Comments
 (0)