From 6908ab439e1f35043affc2b490c407a7de11a04b Mon Sep 17 00:00:00 2001 From: Adrian Reber Date: Tue, 12 Mar 2024 09:09:31 +0000 Subject: [PATCH] Add functions which are used in Podman, CRI-O and containerd Convenience functions to check if CRIU is available and at least a certain version are now used in containerd, CRI-O and Podman. This change moves those functions to go-criu. Signed-off-by: Adrian Reber --- test/main.go | 27 +++++++++++++++++++++++++ utils/criu.go | 8 ++++++++ utils/criu_linux.go | 42 +++++++++++++++++++++++++++++++++++++++ utils/criu_unsupported.go | 18 +++++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 utils/criu.go create mode 100644 utils/criu_linux.go create mode 100644 utils/criu_unsupported.go diff --git a/test/main.go b/test/main.go index 1f77fb5a5..4ec864858 100644 --- a/test/main.go +++ b/test/main.go @@ -3,11 +3,13 @@ package main import ( "fmt" "log" + "math" "os" "strconv" "github.com/checkpoint-restore/go-criu/v7" "github.com/checkpoint-restore/go-criu/v7/rpc" + "github.com/checkpoint-restore/go-criu/v7/utils" "google.golang.org/protobuf/proto" ) @@ -126,6 +128,15 @@ func featureCheck(c *criu.Criu) error { ) } + isMemTrack := utils.IsMemTrack() + if isMemTrack != featuresToCompare.GetMemTrack() { + return fmt.Errorf( + "unexpected MemTrack FeatureCheck result %v:%v", + isMemTrack, + featuresToCompare.GetMemTrack(), + ) + } + return nil } @@ -139,6 +150,14 @@ func main() { os.Exit(1) } log.Println("CRIU version", version) + // Compare if version from convenience function matches + version2, err := utils.GetCriuVersion() + if err != nil { + log.Fatalln(err) + } + if version != version2 { + log.Fatalf("Detected versions do not match (%d != %d)", version, version2) + } // Check if version at least 3.2 result, err := c.IsCriuAtLeast(30200) if err != nil { @@ -148,6 +167,14 @@ func main() { log.Fatalln("CRIU version to old") } + if err := utils.CheckForCriu(30200); err != nil { + log.Fatalln(err) + } + + if err := utils.CheckForCriu(math.MaxInt); err == nil { + log.Fatalf("Checking for CRIU version %d should have failed.", math.MaxInt) + } + if err = featureCheck(c); err != nil { log.Fatalln(err) } diff --git a/utils/criu.go b/utils/criu.go new file mode 100644 index 000000000..4daf9af80 --- /dev/null +++ b/utils/criu.go @@ -0,0 +1,8 @@ +package utils + +// MinCriuVersion for Podman at least CRIU 3.11 is required +const MinCriuVersionPodman = 31100 + +// PodCriuVersion is the version of CRIU needed for +// checkpointing and restoring containers out of and into Pods. +const PodCriuVersion = 31600 diff --git a/utils/criu_linux.go b/utils/criu_linux.go new file mode 100644 index 000000000..1c3fe5141 --- /dev/null +++ b/utils/criu_linux.go @@ -0,0 +1,42 @@ +package utils + +import ( + "fmt" + + "github.com/checkpoint-restore/go-criu/v7" + "github.com/checkpoint-restore/go-criu/v7/rpc" + "google.golang.org/protobuf/proto" +) + +// CheckForCRIU checks if CRIU is available and if it is as least the +// version as specified in the "version" parameter. +func CheckForCriu(version int) error { + criuVersion, err := GetCriuVersion() + if err != nil { + return fmt.Errorf("failed to check for criu version: %w", err) + } + + if criuVersion >= version { + return nil + } + return fmt.Errorf("checkpoint/restore requires at least CRIU %d, current version is %d", version, criuVersion) +} + +// Convenience function to easily check if memory tracking is supported. +func IsMemTrack() bool { + features, err := criu.MakeCriu().FeatureCheck( + &rpc.CriuFeatures{ + MemTrack: proto.Bool(true), + }, + ) + if err != nil { + return false + } + + return features.GetMemTrack() +} + +func GetCriuVersion() (int, error) { + c := criu.MakeCriu() + return c.GetCriuVersion() +} diff --git a/utils/criu_unsupported.go b/utils/criu_unsupported.go new file mode 100644 index 000000000..739da0ada --- /dev/null +++ b/utils/criu_unsupported.go @@ -0,0 +1,18 @@ +//go:build !linux +// +build !linux + +package utils + +import "fmt" + +func CheckForCriu(version int) error { + return fmt.Errorf("CRIU not supported on this platform") +} + +func IsMemTrack() bool { + return false +} + +func GetCriuVersion() (int, error) { + return 0, fmt.Errorf("CRIU not supported in this platform") +}