From 12a035408444a3c5888219cf848b32bab1f5ea09 Mon Sep 17 00:00:00 2001 From: Clare Chen Date: Fri, 14 Sep 2018 22:39:13 -0400 Subject: [PATCH] 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 Signed-off-by: Zichang Lin --- virtcontainers/agent.go | 3 +++ virtcontainers/api.go | 5 +++++ virtcontainers/container.go | 22 ++++++++++++---------- virtcontainers/hyperstart_agent.go | 5 +++++ virtcontainers/kata_agent.go | 12 ++++++++++++ virtcontainers/noop_agent.go | 5 +++++ virtcontainers/sandbox.go | 21 +++++++++++++++++++++ 7 files changed, 63 insertions(+), 10 deletions(-) diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go index 954a79955c..01291b994b 100644 --- a/virtcontainers/agent.go +++ b/virtcontainers/agent.go @@ -242,4 +242,7 @@ type agent interface { // listRoutes will tell the agent to list routes of an existed Sandbox listRoutes() ([]*grpc.Route, error) + + // getGuestDetails will tell the agent to get some information of guest + getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) } diff --git a/virtcontainers/api.go b/virtcontainers/api.go index 703ecb5868..3573b3707f 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -122,6 +122,11 @@ func createSandboxFromConfig(ctx context.Context, sandboxConfig SandboxConfig, f return nil, err } + // get and store guest details + if err := s.getAndStoreGuestDetails(); err != nil { + return nil, err + } + return s, nil } diff --git a/virtcontainers/container.go b/virtcontainers/container.go index 073b41da65..2dff28925a 100644 --- a/virtcontainers/container.go +++ b/virtcontainers/container.go @@ -1299,13 +1299,14 @@ func (c *Container) updateVCPUResources(oldResources, newResources ContainerReso return nil } -func (c *Container) memHotplugValid(mem *uint32) error { - // TODO: make memory aligned to correct memory boundary according to different architecture - const memorySectionSizeMB = 128 - // 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 - *mem = uint32(math.Ceil(float64(*mem)/memorySectionSizeMB)) * memorySectionSizeMB +func (c *Container) memHotplugValid(mem uint32) (uint32, error) { + memorySectionSizeMB := c.sandbox.state.GuestMemoryBlockSizeMB + if memorySectionSizeMB == 0 { + return mem, nil + } - 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 { @@ -1323,15 +1324,16 @@ func (c *Container) updateMemoryResources(oldResources, newResources ContainerRe if oldMemMB < newMemMB { // hot add memory addMemMB := newMemMB - oldMemMB - if err := c.memHotplugValid(&addMemMB); err != nil { + memHotplugMB, err := c.memHotplugValid(addMemMB) + if err != nil { return err } - virtLog.Debugf("hot adding %dMB mem", addMemMB) + virtLog.Debugf("hotplug %dMB mem", memHotplugMB) 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 { return err } diff --git a/virtcontainers/hyperstart_agent.go b/virtcontainers/hyperstart_agent.go index 2e36faa1a1..1b8a8cd49c 100644 --- a/virtcontainers/hyperstart_agent.go +++ b/virtcontainers/hyperstart_agent.go @@ -987,3 +987,8 @@ func (h *hyper) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) err return nil } + +func (h *hyper) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) { + // hyperstart-agent does not support getGuestDetails + return nil, nil +} diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 54d79df223..e5c03fdda7 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -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) { 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) { @@ -1522,3 +1525,12 @@ func (k *kataAgent) readProcessStream(containerID, processID string, data []byte 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 +} diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go index 7294198865..5649d81f04 100644 --- a/virtcontainers/noop_agent.go +++ b/virtcontainers/noop_agent.go @@ -197,3 +197,8 @@ func (n *noopAgent) getAgentURL() (string, error) { func (n *noopAgent) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) error { return nil } + +// getGuestDetails is the Noop agent GuestDetails queryer. It does nothing. +func (n *noopAgent) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) { + return nil, nil +} diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index a3d8d783db..073ece5272 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -64,6 +64,9 @@ type State struct { // Pid is the process id of the sandbox container which is the first // container to be started. 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. @@ -710,6 +713,24 @@ func createAssets(ctx context.Context, sandboxConfig *SandboxConfig) error { 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 // and the agent passed through the Config structure. // It will create and store the sandbox structure, and then ask the hypervisor