Skip to content

Commit

Permalink
Error out early if system does not support pre-copy checkpointing
Browse files Browse the repository at this point in the history
CRIU's pre-copy migration support relies on the soft dirty page tracking
in the Linux kernel:

 https://www.kernel.org/doc/Documentation/vm/soft-dirty.txt

This functionality is not implemented for all architectures and it can
also be turned off in the kernel.

CRIU can check if the combination of architecture/kernel/CRIU supports
the soft dirty page tracking and exports this feature checking
functionality in go-criu.

This commit adds an early check if the user selects pre-copy
checkpointing to error out if the system does not support it.

Signed-off-by: Adrian Reber <[email protected]>
  • Loading branch information
adrianreber committed Dec 23, 2021
1 parent b746b22 commit d669dbf
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/podman/containers/checkpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/criu"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/storage/pkg/archive"
Expand Down Expand Up @@ -113,6 +114,9 @@ func checkpoint(cmd *cobra.Command, args []string) error {
if checkpointOptions.WithPrevious && checkpointOptions.PreCheckPoint {
return errors.Errorf("--with-previous can not be used with --pre-checkpoint")
}
if (checkpointOptions.WithPrevious || checkpointOptions.PreCheckPoint) && !criu.MemTrack() {
return errors.New("system (architecture/kernel/CRIU) does not support memory tracking")
}
responses, err := registry.ContainerEngine().ContainerCheckpoint(context.Background(), args, checkpointOptions)
if err != nil {
return err
Expand Down
12 changes: 12 additions & 0 deletions docs/source/markdown/podman-container-checkpoint.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ Dump the *container's* memory information only, leaving the *container* running.
operations will supersede prior dumps. It only works on `runc 1.0-rc3` or `higher`.\
The default is **false**.

The functionality to only checkpoint the memory of the container and in a second
checkpoint only write out the memory pages which have changed since the first
checkpoint relies on the Linux kernel's soft-dirty bit, which is not available
on all systems as it depends on the system architecture and the configuration
of the Linux kernel. Podman will verify if the current system supports this
functionality and return an error if the current system does not support it.

#### **--print-stats**

Print out statistics about checkpointing the container(s). The output is
Expand Down Expand Up @@ -126,6 +133,11 @@ Check out the *container* with previous criu image files in pre-dump. It only wo
The default is **false**.\
*IMPORTANT: This OPTION is not available with __--pre-checkpoint__*.

This option requires that the option __--pre-checkpoint__ has been used before on the
same container. Without an existing pre-checkpoint, this option will fail.

Also see __--pre-checkpoint__ for additional information about __--pre-checkpoint__
availability on different systems.

## EXAMPLES
Make a checkpoint for the container "mywebserver".
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ require (
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d
google.golang.org/protobuf v1.27.1
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
k8s.io/api v0.22.4
Expand Down
22 changes: 22 additions & 0 deletions pkg/criu/criu.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// +build linux

package criu

import (
"github.com/checkpoint-restore/go-criu/v5"
"github.com/checkpoint-restore/go-criu/v5/rpc"

"google.golang.org/protobuf/proto"
)

// MinCriuVersion for Podman at least CRIU 3.11 is required
Expand All @@ -21,3 +26,20 @@ func CheckForCriu(version int) bool {
}
return result
}

func MemTrack() bool {
features, err := criu.MakeCriu().FeatureCheck(
&rpc.CriuFeatures{
MemTrack: proto.Bool(true),
},
)
if err != nil {
return false
}

if features == nil || features.MemTrack == nil {
return false
}

return *features.MemTrack
}
7 changes: 7 additions & 0 deletions pkg/criu/criu_unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !linux

package criu

func MemTrack() bool {
return false
}
6 changes: 6 additions & 0 deletions test/e2e/checkpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,9 @@ var _ = Describe("Podman checkpoint", func() {
})

It("podman checkpoint container with --pre-checkpoint", func() {
if !criu.MemTrack() {
Skip("system (architecture/kernel/CRIU) does not support memory tracking")
}
if !strings.Contains(podmanTest.OCIRuntime, "runc") {
Skip("Test only works on runc 1.0-rc3 or higher.")
}
Expand Down Expand Up @@ -972,6 +975,9 @@ var _ = Describe("Podman checkpoint", func() {

It("podman checkpoint container with --pre-checkpoint and export (migration)", func() {
SkipIfRemote("--import-previous is not yet supported on the remote client")
if !criu.MemTrack() {
Skip("system (architecture/kernel/CRIU) does not support memory tracking")
}
if !strings.Contains(podmanTest.OCIRuntime, "runc") {
Skip("Test only works on runc 1.0-rc3 or higher.")
}
Expand Down
1 change: 1 addition & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ google.golang.org/grpc/stats
google.golang.org/grpc/status
google.golang.org/grpc/tap
# google.golang.org/protobuf v1.27.1
## explicit
google.golang.org/protobuf/encoding/prototext
google.golang.org/protobuf/encoding/protowire
google.golang.org/protobuf/internal/descfmt
Expand Down

0 comments on commit d669dbf

Please sign in to comment.