github.com/nicocha30/gvisor-ligolo@v0.0.0-20230726075806-989fa2c0a413/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/nicocha30/gvisor-ligolo/pkg/abi/linux" 21 "github.com/nicocha30/gvisor-ligolo/pkg/log" 22 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/kernel" 23 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/state" 24 "github.com/nicocha30/gvisor-ligolo/pkg/sentry/watchdog" 25 "github.com/nicocha30/gvisor-ligolo/pkg/urpc" 26 ) 27 28 // ErrInvalidFiles is returned when the urpc call to Save does not include an 29 // appropriate file payload (e.g. there is no output file!). 30 var ErrInvalidFiles = errors.New("exactly one file must be provided") 31 32 // State includes state-related functions. 33 type State struct { 34 Kernel *kernel.Kernel 35 Watchdog *watchdog.Watchdog 36 } 37 38 // SaveOpts contains options for the Save RPC call. 39 type SaveOpts struct { 40 // Key is used for state integrity check. 41 Key []byte `json:"key"` 42 43 // Metadata is the set of metadata to prepend to the state file. 44 Metadata map[string]string `json:"metadata"` 45 46 // FilePayload contains the destination for the state. 47 urpc.FilePayload 48 } 49 50 // Save saves the running system. 51 func (s *State) Save(o *SaveOpts, _ *struct{}) error { 52 // Create an output stream. 53 if len(o.FilePayload.Files) != 1 { 54 return ErrInvalidFiles 55 } 56 defer o.FilePayload.Files[0].Close() 57 58 // Save to the first provided stream. 59 saveOpts := state.SaveOpts{ 60 Destination: o.FilePayload.Files[0], 61 Key: o.Key, 62 Metadata: o.Metadata, 63 Callback: func(err error) { 64 if err == nil { 65 log.Infof("Save succeeded: exiting...") 66 s.Kernel.SetSaveSuccess(false /* autosave */) 67 } else { 68 log.Warningf("Save failed: exiting...") 69 s.Kernel.SetSaveError(err) 70 } 71 s.Kernel.Kill(linux.WaitStatusExit(0)) 72 }, 73 } 74 return saveOpts.Save(s.Kernel.SupervisorContext(), s.Kernel, s.Watchdog) 75 }