diff --git a/test/main.go b/test/main.go index 1f77fb5a5..2a31d2edc 100644 --- a/test/main.go +++ b/test/main.go @@ -8,6 +8,7 @@ import ( "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 +127,14 @@ func featureCheck(c *criu.Criu) error { ) } + if utils.MemTrack() != featuresToCompare.GetMemTrack() { + return fmt.Errorf( + "unexpected MemTrack FeatureCheck result %v:%v", + utils.MemTrack(), + featuresToCompare.GetMemTrack(), + ) + } + return nil } @@ -139,6 +148,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 +165,10 @@ func main() { log.Fatalln("CRIU version to old") } + if err := utils.CheckForCriu(30200); err != nil { + log.Fatalln(err) + } + 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..74f1cb1a3 --- /dev/null +++ b/utils/criu_linux.go @@ -0,0 +1,45 @@ +//go:build linux +// +build linux + +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 MemTrack() 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..8dac0c7fb --- /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 MemTrack() bool { + return false +} + +func GetCriuVersion() (int, error) { + return 0, fmt.Errorf("CRIU not supported in this platform") +}