diff --git a/runsc/boot/restore.go b/runsc/boot/restore.go index 3451f58adc..efc38d6c4f 100644 --- a/runsc/boot/restore.go +++ b/runsc/boot/restore.go @@ -132,7 +132,7 @@ func (r *restorer) restoreContainerInfo(l *Loader, info *containerInfo) error { if len(r.containers) == r.totalContainers { // Trigger the restore if this is the last container. - return r.restore(l) + return r.restore(l, info.conf.SkipRestoreSpecValidationUnsafe) } return nil } @@ -544,7 +544,7 @@ func validateSpecs(oldSpecs, newSpecs map[string]*specs.Spec) error { return nil } -func (r *restorer) restore(l *Loader) error { +func (r *restorer) restore(l *Loader, unsafeSkipRestoreSpecValidation bool) error { log.Infof("Starting to restore %d containers", len(r.containers)) // Create a new root network namespace with the network stack of the @@ -650,8 +650,10 @@ func (r *restorer) restore(l *Loader) error { if err != nil { return fmt.Errorf("failed to pop container specs from checkpoint: %w", err) } - if err := validateSpecs(oldSpecs, l.containerSpecs); err != nil { - return fmt.Errorf("failed to validate restore spec: %w", err) + if !unsafeSkipRestoreSpecValidation { + if err := validateSpecs(oldSpecs, l.containerSpecs); err != nil { + return fmt.Errorf("failed to validate restore spec: %w", err) + } } // Since we have a new kernel we also must make a new watchdog. diff --git a/runsc/config/config.go b/runsc/config/config.go index 3783c6c5f4..5dfabc208b 100644 --- a/runsc/config/config.go +++ b/runsc/config/config.go @@ -384,6 +384,10 @@ type Config struct { // TestOnlySaveRestoreNetstack indicates netstack should be saved and restored. TestOnlySaveRestoreNetstack bool `flag:"TESTONLY-save-restore-netstack"` + + // UnsafeSkipRestoreSpecValidation optionally skips validation of the container spec for restored + // containers. + UnsafeSkipRestoreSpecValidation bool `flag:"unsafe-skip-restore-spec-validation"` } func (c *Config) validate() error { diff --git a/runsc/config/flags.go b/runsc/config/flags.go index 9ca2ff9ec4..32afbcbaec 100644 --- a/runsc/config/flags.go +++ b/runsc/config/flags.go @@ -105,6 +105,7 @@ func RegisterFlags(flagSet *flag.FlagSet) { flagSet.Bool("enable-core-tags", false, "enables core tagging. Requires host linux kernel >= 5.14.") flagSet.String("pod-init-config", "", "path to configuration file with additional steps to take during pod creation.") flagSet.Var(HostSettingsCheck.Ptr(), "host-settings", "how to handle non-optimal host kernel settings: check (default, advisory-only), ignore (do not check), adjust (best-effort auto-adjustment), or enforce (auto-adjustment must succeed).") + flagSet.Bool("unsafe-skip-restore-spec-validation", false, "Enables skipping validation of the restore-time container spec when restoring checkpoints.") // Flags that control sandbox runtime behavior: MM related. flagSet.Bool("app-huge-pages", true, "enable use of huge pages for application memory; requires /sys/kernel/mm/transparent_hugepage/shmem_enabled = advise")