diff --git a/.travis.yml b/.travis.yml index b762b632..5bbcf6eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,8 @@ matrix: - ssh default sudo dnf install -y podman script: - ssh default sudo podman build -t test /vagrant - - ssh default sudo podman run --privileged --cgroupns=private test make localunittest + # Mounting /lib/modules into the container is necessary as CRIU wants to load (via iptables) additional modules + - ssh default sudo podman run --privileged --cgroupns=private -v /lib/modules:/lib/modules:ro test make localunittest allow_failures: - go: tip - name: "cgroup-v2" diff --git a/Dockerfile b/Dockerfile index d3e91bc7..94be151e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG GO_VERSION=1.13 ARG BATS_VERSION=03608115df2071fff4eaaff1605768c275e5f81f -ARG CRIU_VERSION=v3.12 +ARG CRIU_VERSION=v3.13 FROM golang:${GO_VERSION}-buster ARG DEBIAN_FRONTEND=noninteractive @@ -62,7 +62,13 @@ ARG CRIU_VERSION RUN mkdir -p /usr/src/criu \ && curl -fsSL https://github.com/checkpoint-restore/criu/archive/${CRIU_VERSION}.tar.gz | tar -C /usr/src/criu/ -xz --strip-components=1 \ && cd /usr/src/criu \ + && echo 1 > .gitid \ + && curl -sSL https://github.com/checkpoint-restore/criu/commit/4c27b3db4f4325a311d8bfa9a50ea3efb4d6e377.patch | patch -p1 \ + && curl -sSL https://github.com/checkpoint-restore/criu/commit/aac41164b2cd7f0d2047f207b32844524682e43f.patch | patch -p1 \ + && curl -sSL https://github.com/checkpoint-restore/criu/commit/6f19249b2565f3f7c0a1f8f65b4ae180e8f7f34b.patch | patch -p1 \ + && curl -sSL https://github.com/checkpoint-restore/criu/commit/378337a496ca759848180bc5411e4446298c5e4e.patch | patch -p1 \ && make install-criu \ + && cd - \ && rm -rf /usr/src/criu COPY script/tmpmount / diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index b74f3f4d..aa150244 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -1015,9 +1015,14 @@ func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error { } } - fcg := c.cgroupManager.GetPaths()["freezer"] - if fcg != "" { - rpcOpts.FreezeCgroup = proto.String(fcg) + if !cgroups.IsCgroup2UnifiedMode() && c.checkCriuVersion(31400) == nil { + // CRIU currently cannot handle the v2 freezer correctly + // before release 3.14. For older releases we are telling + // CRIU to not use the cgroup v2 freezer. CRIU will pause + // each process manually using ptrace(). + if fcg := c.cgroupManager.GetPaths()["freezer"]; fcg != "" { + rpcOpts.FreezeCgroup = proto.String(fcg) + } } // append optional criu opts, e.g., page-server and port diff --git a/libcontainer/integration/checkpoint_test.go b/libcontainer/integration/checkpoint_test.go index 51ed401f..2f6990f8 100644 --- a/libcontainer/integration/checkpoint_test.go +++ b/libcontainer/integration/checkpoint_test.go @@ -60,9 +60,6 @@ func testCheckpoint(t *testing.T, userns bool) { if testing.Short() { return } - if cgroups.IsCgroup2UnifiedMode() { - t.Skip("cgroup v2 is not supported") - } root, err := newTestRoot() if err != nil { @@ -78,16 +75,24 @@ func testCheckpoint(t *testing.T, userns bool) { config := newTemplateConfig(rootfs) - config.Mounts = append(config.Mounts, &configs.Mount{ - Destination: "/sys/fs/cgroup", - Device: "cgroup", - Flags: defaultMountFlags | unix.MS_RDONLY, - }) - if userns { config.UidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}} config.GidMappings = []configs.IDMap{{HostID: 0, ContainerID: 0, Size: 1000}} config.Namespaces = append(config.Namespaces, configs.Namespace{Type: configs.NEWUSER}) + } else { + var cgroupDevice string + + if cgroups.IsCgroup2UnifiedMode() { + cgroupDevice = "cgroup2" + } else { + cgroupDevice = "cgroup" + } + + config.Mounts = append(config.Mounts, &configs.Mount{ + Destination: "/sys/fs/cgroup", + Device: cgroupDevice, + Flags: defaultMountFlags | unix.MS_RDONLY, + }) } factory, err := libcontainer.New(root, libcontainer.Cgroupfs)