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