github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/control/state.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package control 16 17 import ( 18 "errors" 19 20 "github.com/SagerNet/gvisor/pkg/log" 21 "github.com/SagerNet/gvisor/pkg/sentry/kernel" 22 "github.com/SagerNet/gvisor/pkg/sentry/state" 23 "github.com/SagerNet/gvisor/pkg/sentry/watchdog" 24 "github.com/SagerNet/gvisor/pkg/urpc" 25 ) 26 27 // ErrInvalidFiles is returned when the urpc call to Save does not include an 28 // appropriate file payload (e.g. there is no output file!). 29 var ErrInvalidFiles = errors.New("exactly one file must be provided") 30 31 // State includes state-related functions. 32 type State struct { 33 Kernel *kernel.Kernel 34 Watchdog *watchdog.Watchdog 35 } 36 37 // SaveOpts contains options for the Save RPC call. 38 type SaveOpts struct { 39 // Key is used for state integrity check. 40 Key []byte `json:"key"` 41 42 // Metadata is the set of metadata to prepend to the state file. 43 Metadata map[string]string `json:"metadata"` 44 45 // FilePayload contains the destination for the state. 46 urpc.FilePayload 47 } 48 49 // Save saves the running system. 50 func (s *State) Save(o *SaveOpts, _ *struct{}) error { 51 // Create an output stream. 52 if len(o.FilePayload.Files) != 1 { 53 return ErrInvalidFiles 54 } 55 defer o.FilePayload.Files[0].Close() 56 57 // Save to the first provided stream. 58 saveOpts := state.SaveOpts{ 59 Destination: o.FilePayload.Files[0], 60 Key: o.Key, 61 Metadata: o.Metadata, 62 Callback: func(err error) { 63 if err == nil { 64 log.Infof("Save succeeded: exiting...") 65 s.Kernel.SetSaveSuccess(false /* autosave */) 66 } else { 67 log.Warningf("Save failed: exiting...") 68 s.Kernel.SetSaveError(err) 69 } 70 s.Kernel.Kill(kernel.ExitStatus{}) 71 }, 72 } 73 return saveOpts.Save(s.Kernel.SupervisorContext(), s.Kernel, s.Watchdog) 74 }