mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-29 00:37:24 +00:00
persist: save and restore state from persist.json
Save and restore state from persist.json instead of state.json Signed-off-by: Wei Zhang <zhangwei555@huawei.com>
This commit is contained in:
parent
039ed4eeb8
commit
6e4149d86c
@ -442,6 +442,9 @@ func (c *Container) setContainerState(state types.StateString) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.sandbox.newStore.Dump(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -683,9 +686,14 @@ func newContainer(sandbox *Sandbox, contConfig ContainerConfig) (*Container, err
|
||||
|
||||
c.store = ctrStore
|
||||
|
||||
state, err := c.store.LoadContainerState()
|
||||
/*state, err := c.store.LoadContainerState()
|
||||
if err == nil {
|
||||
c.state = state
|
||||
}*/
|
||||
|
||||
if err := c.Restore(); err != nil &&
|
||||
!os.IsNotExist(err) && err != errContainerPersistNotExist {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var process Process
|
||||
@ -693,6 +701,18 @@ func newContainer(sandbox *Sandbox, contConfig ContainerConfig) (*Container, err
|
||||
c.process = process
|
||||
}
|
||||
|
||||
if err = c.createMounts(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = c.createDevices(contConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Container) createMounts() error {
|
||||
mounts, err := c.loadMounts()
|
||||
if err == nil {
|
||||
// restore mounts from disk
|
||||
@ -700,10 +720,14 @@ func newContainer(sandbox *Sandbox, contConfig ContainerConfig) (*Container, err
|
||||
} else {
|
||||
// Create block devices for newly created container
|
||||
if err := c.createBlockDevices(); err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) createDevices(contConfig ContainerConfig) error {
|
||||
// Devices will be found in storage after create stage has completed.
|
||||
// We load devices from storage at all other stages.
|
||||
storedDevices, err := c.loadDevices()
|
||||
@ -713,9 +737,9 @@ func newContainer(sandbox *Sandbox, contConfig ContainerConfig) (*Container, err
|
||||
// If devices were not found in storage, create Device implementations
|
||||
// from the configuration. This should happen at create.
|
||||
for _, info := range contConfig.DeviceInfos {
|
||||
dev, err := sandbox.devManager.NewDevice(info)
|
||||
dev, err := c.sandbox.devManager.NewDevice(info)
|
||||
if err != nil {
|
||||
return &Container{}, err
|
||||
return err
|
||||
}
|
||||
|
||||
storedDevices = append(storedDevices, ContainerDevice{
|
||||
@ -726,10 +750,9 @@ func newContainer(sandbox *Sandbox, contConfig ContainerConfig) (*Container, err
|
||||
GID: info.GID,
|
||||
})
|
||||
}
|
||||
c.devices = filterDevices(sandbox, c, storedDevices)
|
||||
c.devices = filterDevices(c.sandbox, c, storedDevices)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// rollbackFailingContainerCreation rolls back important steps that might have
|
||||
|
@ -6,19 +6,23 @@
|
||||
package virtcontainers
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
|
||||
//"github.com/sirupsen/logrus"
|
||||
"errors"
|
||||
|
||||
"github.com/kata-containers/runtime/virtcontainers/device/api"
|
||||
persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
|
||||
"github.com/kata-containers/runtime/virtcontainers/types"
|
||||
)
|
||||
|
||||
var (
|
||||
errSandboxPersistNotExist = errors.New("sandbox doesn't exist in persist data")
|
||||
errContainerPersistNotExist = errors.New("container doesn't exist in persist data")
|
||||
)
|
||||
|
||||
func (s *Sandbox) dumpState(ss *persistapi.SandboxState, cs map[string]persistapi.ContainerState) error {
|
||||
ss.SandboxContainer = s.id
|
||||
ss.GuestMemoryBlockSizeMB = s.state.GuestMemoryBlockSizeMB
|
||||
ss.State = string(s.state.State)
|
||||
ss.CgroupPath = s.state.CgroupPath
|
||||
|
||||
for id, cont := range s.containers {
|
||||
state := persistapi.ContainerState{}
|
||||
@ -30,6 +34,7 @@ func (s *Sandbox) dumpState(ss *persistapi.SandboxState, cs map[string]persistap
|
||||
BlockDeviceID: cont.state.BlockDeviceID,
|
||||
FsType: cont.state.Fstype,
|
||||
}
|
||||
state.CgroupPath = cont.state.CgroupPath
|
||||
cs[id] = state
|
||||
}
|
||||
|
||||
@ -111,43 +116,61 @@ func (s *Sandbox) persistDevices() {
|
||||
s.newStore.RegisterHook("devices", s.dumpDevices)
|
||||
}
|
||||
|
||||
// Restore will restore data from persist disk on disk
|
||||
func (s *Sandbox) Restore() error {
|
||||
if err := s.newStore.Restore(s.id); err != nil {
|
||||
return err
|
||||
func (s *Sandbox) getSbxAndCntStates() (*persistapi.SandboxState, map[string]persistapi.ContainerState, error) {
|
||||
ss, cs, err := s.newStore.GetStates()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ss, _, err := s.newStore.GetStates()
|
||||
if len(cs) == 0 {
|
||||
if err := s.newStore.Restore(s.id); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ss, cs, err = s.newStore.GetStates()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if len(cs) == 0 {
|
||||
return nil, nil, errSandboxPersistNotExist
|
||||
}
|
||||
}
|
||||
return ss, cs, nil
|
||||
}
|
||||
|
||||
// Restore will restore sandbox data from persist file on disk
|
||||
func (s *Sandbox) Restore() error {
|
||||
ss, _, err := s.getSbxAndCntStates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: need more modifications, restoring containers
|
||||
// will make sandbox.addContainer failing
|
||||
if s.containers == nil {
|
||||
s.containers = make(map[string]*Container)
|
||||
}
|
||||
|
||||
for id, cont := range cs {
|
||||
s.containers[id] = &Container{
|
||||
state: State{
|
||||
State: stateString(cont.State),
|
||||
BlockDeviceID: cont.Rootfs.BlockDeviceID,
|
||||
Fstype: cont.Rootfs.FsType,
|
||||
Pid: cont.ShimPid,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
sbxCont, ok := s.containers[ss.SandboxContainer]
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get sandbox container state")
|
||||
}
|
||||
*/
|
||||
s.state.GuestMemoryBlockSizeMB = ss.GuestMemoryBlockSizeMB
|
||||
s.state.BlockIndex = ss.HypervisorState.BlockIndex
|
||||
s.state.State = types.StateString(ss.State)
|
||||
s.state.CgroupPath = ss.CgroupPath
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Restore will restore container data from persist file on disk
|
||||
func (c *Container) Restore() error {
|
||||
_, cs, err := c.sandbox.getSbxAndCntStates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := cs[c.id]; !ok {
|
||||
return errContainerPersistNotExist
|
||||
}
|
||||
|
||||
c.state = types.ContainerState{
|
||||
State: types.StateString(cs[c.id].State),
|
||||
BlockDeviceID: cs[c.id].Rootfs.BlockDeviceID,
|
||||
Fstype: cs[c.id].Rootfs.FsType,
|
||||
CgroupPath: cs[c.id].CgroupPath,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ type ContainerState struct {
|
||||
|
||||
// CgroupPath is the cgroup hierarchy where sandbox's processes
|
||||
// including the hypervisor are placed.
|
||||
CgroupPath string `json:"cgroupPath,omitempty"`
|
||||
CgroupPath string
|
||||
|
||||
// DeviceMaps is mapping between sandbox device to dest in container
|
||||
DeviceMaps []DeviceMap
|
||||
|
@ -68,11 +68,12 @@ type SandboxState struct {
|
||||
SandboxContainer string
|
||||
|
||||
// GuestMemoryHotplugProbe determines whether guest kernel supports memory hotplug probe interface
|
||||
GuestMemoryHotplugProbe bool `json:"guestMemoryHotplugProbe"`
|
||||
GuestMemoryHotplugProbe bool
|
||||
|
||||
// CgroupPath is the cgroup hierarchy where sandbox's processes
|
||||
// including the hypervisor are placed.
|
||||
CgroupPath string `json:"cgroupPath,omitempty"`
|
||||
// FIXME: sandbox can reuse "SandboxContainer"'s CgroupPath so we can remove this field.
|
||||
CgroupPath string
|
||||
|
||||
// GuestMemoryBlockSizeMB is the size of memory block of guestos
|
||||
GuestMemoryBlockSizeMB uint32
|
||||
|
@ -9,6 +9,7 @@ package fs
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
@ -139,15 +140,12 @@ func (fs *FS) Restore(sid string) error {
|
||||
}
|
||||
|
||||
fs.sandboxState.SandboxContainer = sid
|
||||
|
||||
sandboxDir, err := fs.sandboxDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(sandboxDir, dirMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := fs.lock(); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -166,13 +164,7 @@ func (fs *FS) Restore(sid string) error {
|
||||
}
|
||||
|
||||
// walk sandbox dir and find container
|
||||
d, err := os.OpenFile(sandboxDir, os.O_RDONLY, fileMode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer d.Close()
|
||||
|
||||
files, err := d.Readdir(-1)
|
||||
files, err := ioutil.ReadDir(sandboxDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user