summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Reber <areber@redhat.com>2021-12-21 16:01:53 +0000
committerAdrian Reber <areber@redhat.com>2021-12-23 09:51:38 +0000
commitd669dbfb9fbb4bae56ba90ce9b58352c793eff6e (patch)
tree60b8c68575360fa10ebb390eea542ce3b2e5b4a7
parentb746b22564298463ebf322d630488236b7277074 (diff)
downloadpodman-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.go4
-rw-r--r--docs/source/markdown/podman-container-checkpoint.1.md12
-rw-r--r--go.mod1
-rw-r--r--pkg/criu/criu.go22
-rw-r--r--pkg/criu/criu_unsupported.go7
-rw-r--r--test/e2e/checkpoint_test.go6
-rw-r--r--vendor/modules.txt1
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".
diff --git a/go.mod b/go.mod
index 9ae49eff0..2a8902a1a 100644
--- a/go.mod
+++ b/go.mod
@@ -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