diff --git a/pkg/sentry/platform/kvm/kvm.go b/pkg/sentry/platform/kvm/kvm.go index 750d73faf6..512c3826c2 100644 --- a/pkg/sentry/platform/kvm/kvm.go +++ b/pkg/sentry/platform/kvm/kvm.go @@ -187,6 +187,11 @@ func (k *KVM) NewContext(pkgcontext.Context) platform.Context { } } +// Name implements platform.Platform.Name. +func (*KVM) Name() string { + return "kvm" +} + type constructor struct{} func (*constructor) New(opts platform.Options) (platform.Platform, error) { diff --git a/pkg/sentry/platform/platform.go b/pkg/sentry/platform/platform.go index 30cc49886c..3fd3aec83d 100644 --- a/pkg/sentry/platform/platform.go +++ b/pkg/sentry/platform/platform.go @@ -121,6 +121,9 @@ type Platform interface { // in parallel. Concurrent calls to Context.Switch() beyond // ConcurrencyCount() may block until previous calls have returned. ConcurrencyCount() int + + // Name returns the name of the platform. + Name() string } // NoCPUPreemptionDetection implements Platform.DetectsCPUPreemption and diff --git a/pkg/sentry/platform/ptrace/ptrace.go b/pkg/sentry/platform/ptrace/ptrace.go index c1fb127a85..4e09b76977 100644 --- a/pkg/sentry/platform/ptrace/ptrace.go +++ b/pkg/sentry/platform/ptrace/ptrace.go @@ -268,6 +268,11 @@ func (*PTrace) ConcurrencyCount() int { return math.MaxInt } +// Name implements platform.Platform.Name. +func (*PTrace) Name() string { + return "ptrace" +} + type constructor struct{} func (*constructor) New(platform.Options) (platform.Platform, error) { diff --git a/pkg/sentry/platform/systrap/systrap.go b/pkg/sentry/platform/systrap/systrap.go index 3758f46444..dfd56ef344 100644 --- a/pkg/sentry/platform/systrap/systrap.go +++ b/pkg/sentry/platform/systrap/systrap.go @@ -349,6 +349,11 @@ func (*Systrap) ConcurrencyCount() int { return maxSysmsgThreads } +// Name implements platform.Platform.Name. +func (*Systrap) Name() string { + return "systrap" +} + type constructor struct{} func (*constructor) New(opts platform.Options) (platform.Platform, error) { diff --git a/pkg/sentry/state/state.go b/pkg/sentry/state/state.go index 42fd4f9ef4..0ae6dc240e 100644 --- a/pkg/sentry/state/state.go +++ b/pkg/sentry/state/state.go @@ -93,7 +93,7 @@ func (opts SaveOpts) Save(ctx context.Context, k *kernel.Kernel, w *watchdog.Wat if opts.Metadata == nil { opts.Metadata = make(map[string]string) } - addSaveMetadata(opts.Metadata) + addSaveMetadata(opts.Metadata, k.Platform.Name()) // Open the statefile. wc, err := statefile.NewWriter(opts.Destination, opts.Key, opts.Metadata) diff --git a/pkg/sentry/state/state_metadata.go b/pkg/sentry/state/state_metadata.go index a3725790b6..5521599db8 100644 --- a/pkg/sentry/state/state_metadata.go +++ b/pkg/sentry/state/state_metadata.go @@ -24,13 +24,14 @@ import ( "gvisor.dev/gvisor/pkg/log" ) -// The save metadata keys for timestamp. +// The save metadata keys for timestamp and platform. const ( cpuUsage = "cpu_usage" metadataTimestamp = "timestamp" + MetadataPlatform = "platform" ) -func addSaveMetadata(m map[string]string) { +func addSaveMetadata(m map[string]string, platform string) { t, err := CPUTime() if err != nil { log.Warningf("Error getting cpu time: %v", err) @@ -45,4 +46,6 @@ func addSaveMetadata(m map[string]string) { m[cpuUsage] = t.String() m[metadataTimestamp] = fmt.Sprintf("%v", time.Now()) + + m[MetadataPlatform] = platform } diff --git a/runsc/boot/controller.go b/runsc/boot/controller.go index a4f240a3dd..7a3c719886 100644 --- a/runsc/boot/controller.go +++ b/runsc/boot/controller.go @@ -639,6 +639,11 @@ func (cm *containerManager) Restore(o *RestoreOpts, _ *struct{}) error { if checkpointVersion != currentVersion { return fmt.Errorf("runsc version does not match across checkpoint restore, checkpoint: %v current: %v", checkpointVersion, currentVersion) } + checkpointPlatform := metadata[state.MetadataPlatform] + currentPlatform := cm.l.k.Platform.Name() + if checkpointPlatform != currentPlatform { + return fmt.Errorf("platform does not match across checkpoint restore, checkpoint: %v current: %v", checkpointPlatform, currentPlatform) + } return cm.restorer.restoreContainerInfo(cm.l, &cm.l.root, timer.Fork("cont:root")) }