diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go index d1044bd76c..322cd0f471 100644 --- a/virtcontainers/agent.go +++ b/virtcontainers/agent.go @@ -8,6 +8,7 @@ package virtcontainers import ( "fmt" "syscall" + "time" "github.com/kata-containers/agent/protocols/grpc" "github.com/kata-containers/runtime/virtcontainers/pkg/types" @@ -246,4 +247,7 @@ type agent interface { // getGuestDetails will tell the agent to get some information of guest getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) + + // setGuestDateTime asks the agent to set guest time to the provided one + setGuestDateTime(time.Time) error } diff --git a/virtcontainers/factory/factory.go b/virtcontainers/factory/factory.go index cb023a11c2..e11e1632c6 100644 --- a/virtcontainers/factory/factory.go +++ b/virtcontainers/factory/factory.go @@ -248,6 +248,12 @@ func (f *factory) GetVM(ctx context.Context, config vc.VMConfig) (*vc.VM, error) return nil, err } + // sync guest time since we might have paused it for a long time. + err = vm.SyncTime() + if err != nil { + return nil, err + } + online := false baseConfig := f.base.Config().HypervisorConfig if baseConfig.NumVCPUs < hypervisorConfig.NumVCPUs { diff --git a/virtcontainers/hyperstart_agent.go b/virtcontainers/hyperstart_agent.go index b338369c24..67aff379f3 100644 --- a/virtcontainers/hyperstart_agent.go +++ b/virtcontainers/hyperstart_agent.go @@ -1000,3 +1000,8 @@ func (h *hyper) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsRe // hyperstart-agent does not support getGuestDetails return nil, nil } + +func (h *hyper) setGuestDateTime(time.Time) error { + // hyperstart-agent does not support setGuestDateTime + return nil +} diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 335a0a7812..333a2d7426 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -1490,6 +1490,9 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) { k.reqHandlers["grpc.GuestDetailsRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { return k.client.GetGuestDetails(ctx, req.(*grpc.GuestDetailsRequest), opts...) } + k.reqHandlers["grpc.SetGuestDateTimeRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { + return k.client.SetGuestDateTime(ctx, req.(*grpc.SetGuestDateTimeRequest), opts...) + } } func (k *kataAgent) sendReq(request interface{}) (interface{}, error) { @@ -1563,6 +1566,15 @@ func (k *kataAgent) getGuestDetails(req *grpc.GuestDetailsRequest) (*grpc.GuestD return resp.(*grpc.GuestDetailsResponse), nil } +func (k *kataAgent) setGuestDateTime(tv time.Time) error { + _, err := k.sendReq(&grpc.SetGuestDateTimeRequest{ + Sec: tv.Unix(), + Usec: int64(tv.Nanosecond() / 1e3), + }) + + return err +} + func (k *kataAgent) convertToKataAgentIPFamily(ipFamily int) aTypes.IPFamily { switch ipFamily { case netlink.FAMILY_V4: diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index b57b13f610..b65b4086d5 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -243,6 +243,10 @@ func (p *gRPCProxy) GetGuestDetails(ctx context.Context, req *pb.GuestDetailsReq return &pb.GuestDetailsResponse{}, nil } +func (p *gRPCProxy) SetGuestDateTime(ctx context.Context, req *pb.SetGuestDateTimeRequest) (*gpb.Empty, error) { + return &gpb.Empty{}, nil +} + func gRPCRegister(s *grpc.Server, srv interface{}) { switch g := srv.(type) { case *gRPCProxy: @@ -262,6 +266,7 @@ var reqList = []interface{}{ &pb.CheckRequest{}, &pb.WaitProcessRequest{}, &pb.StatsContainerRequest{}, + &pb.SetGuestDateTimeRequest{}, } func TestKataAgentSendReq(t *testing.T) { diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go index 86d5abe5a9..faaacd0ebc 100644 --- a/virtcontainers/noop_agent.go +++ b/virtcontainers/noop_agent.go @@ -7,6 +7,7 @@ package virtcontainers import ( "syscall" + "time" "github.com/kata-containers/agent/protocols/grpc" "github.com/kata-containers/runtime/virtcontainers/pkg/types" @@ -203,3 +204,8 @@ func (n *noopAgent) setProxy(sandbox *Sandbox, proxy proxy, pid int, url string) func (n *noopAgent) getGuestDetails(*grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) { return nil, nil } + +// setGuestDateTime is the Noop agent guest time setter. It does nothing. +func (n *noopAgent) setGuestDateTime(time.Time) error { + return nil +} diff --git a/virtcontainers/vm.go b/virtcontainers/vm.go index ac22d92835..147a876d5f 100644 --- a/virtcontainers/vm.go +++ b/virtcontainers/vm.go @@ -9,6 +9,7 @@ import ( "context" "os" "path/filepath" + "time" "github.com/kata-containers/runtime/virtcontainers/pkg/uuid" "github.com/sirupsen/logrus" @@ -296,6 +297,13 @@ func (v *VM) ReseedRNG() error { return v.agent.reseedRNG(data) } +// SyncTime syncs guest time with host time. +func (v *VM) SyncTime() error { + now := time.Now() + v.logger().WithField("time", now).Infof("sync guest time") + return v.agent.setGuestDateTime(now) +} + func (v *VM) assignSandbox(s *Sandbox) error { // add vm symlinks // - link vm socket from sandbox dir (/run/vc/vm/sbid/) to vm dir (/run/vc/vm/vmid/)