diff options
author | Adrian Reber <areber@redhat.com> | 2021-12-21 16:01:53 +0000 |
---|---|---|
committer | Adrian Reber <areber@redhat.com> | 2021-12-23 09:51:38 +0000 |
commit | d669dbfb9fbb4bae56ba90ce9b58352c793eff6e (patch) | |
tree | 60b8c68575360fa10ebb390eea542ce3b2e5b4a7 | |
parent | b746b22564298463ebf322d630488236b7277074 (diff) | |
download | podman-d669dbfb9fbb4bae56ba90ce9b58352c793eff6e.tar.gz podman-d669dbfb9fbb4bae56ba90ce9b58352c793eff6e.tar.bz2 podman-d669dbfb9fbb4bae56ba90ce9b58352c793eff6e.zip |
Error out early if system does not support pre-copy checkpointing
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 <areber@redhat.com>
-rw-r--r-- | cmd/podman/containers/checkpoint.go | 4 | ||||
-rw-r--r-- | docs/source/markdown/podman-container-checkpoint.1.md | 12 | ||||
-rw-r--r-- | go.mod | 1 | ||||
-rw-r--r-- | pkg/criu/criu.go | 22 | ||||
-rw-r--r-- | pkg/criu/criu_unsupported.go | 7 | ||||
-rw-r--r-- | test/e2e/checkpoint_test.go | 6 | ||||
-rw-r--r-- | vendor/modules.txt | 1 |
7 files changed, 53 insertions, 0 deletions
diff --git a/cmd/podman/containers/checkpoint.go b/cmd/podman/containers/checkpoint.go index e8dd25978..43a1b75e5 100644 --- a/cmd/podman/containers/checkpoint.go +++ b/cmd/podman/containers/checkpoint.go @@ -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" @@ -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 diff --git a/docs/source/markdown/podman-container-checkpoint.1.md b/docs/source/markdown/podman-container-checkpoint.1.md index e54274775..00d8f7095 100644 --- a/docs/source/markdown/podman-container-checkpoint.1.md +++ b/docs/source/markdown/podman-container-checkpoint.1.md @@ -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 @@ -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". @@ -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 diff --git a/pkg/criu/criu.go b/pkg/criu/criu.go index 2a6805979..967da0dca 100644 --- a/pkg/criu/criu.go +++ b/pkg/criu/criu.go @@ -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 @@ -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 +} diff --git a/pkg/criu/criu_unsupported.go b/pkg/criu/criu_unsupported.go new file mode 100644 index 000000000..51cd0c1fd --- /dev/null +++ b/pkg/criu/criu_unsupported.go @@ -0,0 +1,7 @@ +// +build !linux + +package criu + +func MemTrack() bool { + return false +} diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index e97503337..4771f8e58 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -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.") } @@ -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.") } diff --git a/vendor/modules.txt b/vendor/modules.txt index e07c2c6b1..45209ff26 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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 |