sandbox: get and store guest details.

Get and store guest details after sandbox is completely created.
And get memory block size from sandbox state file when check
hotplug memory valid.

Signed-off-by: Clare Chen <clare.chenhui@huawei.com>
Signed-off-by: Zichang Lin <linzichang@huawei.com>
This commit is contained in:
Clare Chen 2018-09-14 22:39:13 -04:00
parent 13bf7d1bbc
commit 12a0354084
7 changed files with 63 additions and 10 deletions

View File

@ -242,4 +242,7 @@ type agent interface {
// listRoutes will tell the agent to list routes of an existed Sandbox // listRoutes will tell the agent to list routes of an existed Sandbox
listRoutes() ([]*grpc.Route, error) listRoutes() ([]*grpc.Route, error)
// getGuestDetails will tell the agent to get some information of guest
getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error)
} }

View File

@ -122,6 +122,11 @@ func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, f
return nil, err return nil, err
} }
// get and store guest details
if err := s.getAndStoreGuestDetails(); err != nil {
return nil, err
}
return s, nil return s, nil
} }

View File

@ -1299,13 +1299,14 @@ func (c *Container) updateVCPUResources(oldResources, newResources ContainerReso
return nil return nil
} }
func (c *Container) memHotplugValid(mem *uint32) error { func (c *Container) memHotplugValid(mem uint32) (uint32, error) {
// TODO: make memory aligned to correct memory boundary according to different architecture memorySectionSizeMB := c.sandbox.state.GuestMemoryBlockSizeMB
const memorySectionSizeMB = 128 if memorySectionSizeMB == 0 {
// TODO: make hot add memory to be aligned to memory section in more proper way. See https://github.com/kata-containers/runtime/pull/624#issuecomment-419656853 return mem, nil
*mem = uint32(math.Ceil(float64(*mem)/memorySectionSizeMB)) * memorySectionSizeMB }
return nil // TODO: hot add memory aligned to memory section should be more properly. See https://github.com/kata-containers/runtime/pull/624#issuecomment-419656853
return uint32(math.Ceil(float64(mem)/float64(memorySectionSizeMB))) * memorySectionSizeMB, nil
} }
func (c *Container) updateMemoryResources(oldResources, newResources ContainerResources) error { func (c *Container) updateMemoryResources(oldResources, newResources ContainerResources) error {
@ -1323,15 +1324,16 @@ func (c *Container) updateMemoryResources(oldResources, newResources ContainerRe
if oldMemMB < newMemMB { if oldMemMB < newMemMB {
// hot add memory // hot add memory
addMemMB := newMemMB - oldMemMB addMemMB := newMemMB - oldMemMB
if err := c.memHotplugValid(&addMemMB); err != nil { memHotplugMB, err := c.memHotplugValid(addMemMB)
if err != nil {
return err return err
} }
virtLog.Debugf("hot adding %dMB mem", addMemMB) virtLog.Debugf("hotplug %dMB mem", memHotplugMB)
addMemDevice := &memoryDevice{ addMemDevice := &memoryDevice{
sizeMB: int(addMemMB), sizeMB: int(memHotplugMB),
} }
_, err := c.sandbox.hypervisor.hotplugAddDevice(addMemDevice, memoryDev) _, err = c.sandbox.hypervisor.hotplugAddDevice(addMemDevice, memoryDev)
if err != nil { if err != nil {
return err return err
} }

View File

@ -987,3 +987,8 @@ func (h *hyper) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) err
return nil return nil
} }
func (h *hyper) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) {
// hyperstart-agent does not support getGuestDetails
return nil, nil
}

View File

@ -1459,6 +1459,9 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) {
k.reqHandlers["grpc.ReseedRandomDevRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { k.reqHandlers["grpc.ReseedRandomDevRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
return k.client.ReseedRandomDev(ctx, req.(*grpc.ReseedRandomDevRequest), opts...) return k.client.ReseedRandomDev(ctx, req.(*grpc.ReseedRandomDevRequest), opts...)
} }
k.reqHandlers["grpc.GuestDetailsRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) {
return k.client.GetGuestDetails(ctx, req.(*grpc.GuestDetailsRequest), opts...)
}
} }
func (k *kataAgent) sendReq(request interface{}) (interface{}, error) { func (k *kataAgent) sendReq(request interface{}) (interface{}, error) {
@ -1522,3 +1525,12 @@ func (k *kataAgent) readProcessStream(containerID, processID string, data []byte
return 0, err return 0, err
} }
func (k *kataAgent) getGuestDetails(req *grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) {
resp, err := k.sendReq(req)
if err != nil {
return nil, err
}
return resp.(*grpc.GuestDetailsResponse), nil
}

View File

@ -197,3 +197,8 @@ func (n *noopAgent) getAgentURL() (string, error) {
func (n *noopAgent) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) error { func (n *noopAgent) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) error {
return nil return nil
} }
// getGuestDetails is the Noop agent GuestDetails queryer. It does nothing.
func (n *noopAgent) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) {
return nil, nil
}

View File

@ -64,6 +64,9 @@ type State struct {
// Pid is the process id of the sandbox container which is the first // Pid is the process id of the sandbox container which is the first
// container to be started. // container to be started.
Pid int `json:"pid"` Pid int `json:"pid"`
// GuestMemoryBlockSizeMB is the size of memory block of guestos
GuestMemoryBlockSizeMB uint32 `json:"guestMemoryBlockSize"`
} }
// valid checks that the sandbox state is valid. // valid checks that the sandbox state is valid.
@ -710,6 +713,24 @@ func createAssets(ctx context.Context, sandboxConfig *SandboxConfig) error {
return nil return nil
} }
func (s *Sandbox) getAndStoreGuestDetails() error {
guestDetailRes, err := s.agent.getGuestDetails(&grpc.GuestDetailsRequest{
MemBlockSize: true,
})
if err != nil {
return err
}
if guestDetailRes != nil {
s.state.GuestMemoryBlockSizeMB = uint32(guestDetailRes.MemBlockSizeBytes >> 20)
if err = s.storage.storeSandboxResource(s.id, stateFileType, s.state); err != nil {
return err
}
}
return nil
}
// createSandbox creates a sandbox from a sandbox description, the containers list, the hypervisor // createSandbox creates a sandbox from a sandbox description, the containers list, the hypervisor
// and the agent passed through the Config structure. // and the agent passed through the Config structure.
// It will create and store the sandbox structure, and then ask the hypervisor // It will create and store the sandbox structure, and then ask the hypervisor