Skip to content

Commit c7c44e1

Browse files
author
Kathryn Baldauf
authored
Merge pull request microsoft#1126 from katiewasnothere/container_id_to_compute_agent_sync
Update ncproxy compute agent cache map
2 parents a88c293 + 3af4cb6 commit c7c44e1

3 files changed

Lines changed: 58 additions & 19 deletions

File tree

cmd/ncproxy/ncproxy.go

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,42 @@ import (
2424
"google.golang.org/grpc/status"
2525
)
2626

27+
type computeAgentCache struct {
28+
// lock for synchronizing read/write access to `cache`
29+
rw sync.RWMutex
30+
// mapping of container ID to shim compute agent ttrpc service
31+
cache map[string]computeagent.ComputeAgentService
32+
}
33+
34+
func newComputeAgentCache() *computeAgentCache {
35+
return &computeAgentCache{
36+
cache: make(map[string]computeagent.ComputeAgentService),
37+
}
38+
}
39+
40+
func (c *computeAgentCache) get(cid string) (computeagent.ComputeAgentService, bool) {
41+
c.rw.RLock()
42+
defer c.rw.RUnlock()
43+
result, ok := c.cache[cid]
44+
return result, ok
45+
}
46+
47+
func (c *computeAgentCache) put(cid string, agent computeagent.ComputeAgentService) {
48+
c.rw.Lock()
49+
defer c.rw.Unlock()
50+
c.cache[cid] = agent
51+
}
52+
2753
// GRPC service exposed for use by a Node Network Service.
28-
type grpcService struct{}
54+
type grpcService struct {
55+
containerIDToComputeAgent *computeAgentCache
56+
}
57+
58+
func newGRPCService(agentCache *computeAgentCache) *grpcService {
59+
return &grpcService{
60+
containerIDToComputeAgent: agentCache,
61+
}
62+
}
2963

3064
var _ ncproxygrpc.NetworkConfigProxyServer = &grpcService{}
3165

@@ -42,13 +76,13 @@ func (s *grpcService) AddNIC(ctx context.Context, req *ncproxygrpc.AddNICRequest
4276
if req.ContainerID == "" || req.EndpointName == "" || req.NicID == "" {
4377
return nil, status.Errorf(codes.InvalidArgument, "received empty field in request: %+v", req)
4478
}
45-
if client, ok := containerIDToShim[req.ContainerID]; ok {
79+
if agent, ok := s.containerIDToComputeAgent.get(req.ContainerID); ok {
4680
caReq := &computeagent.AddNICInternalRequest{
4781
ContainerID: req.ContainerID,
4882
NicID: req.NicID,
4983
EndpointName: req.EndpointName,
5084
}
51-
if _, err := client.AddNIC(ctx, caReq); err != nil {
85+
if _, err := agent.AddNIC(ctx, caReq); err != nil {
5286
return nil, err
5387
}
5488
return &ncproxygrpc.AddNICResponse{}, nil
@@ -72,7 +106,7 @@ func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICR
72106
return nil, status.Error(codes.InvalidArgument, "received empty field in request")
73107
}
74108

75-
if client, ok := containerIDToShim[req.ContainerID]; ok {
109+
if agent, ok := s.containerIDToComputeAgent.get(req.ContainerID); ok {
76110
caReq := &computeagent.ModifyNICInternalRequest{
77111
NicID: req.NicID,
78112
EndpointName: req.EndpointName,
@@ -112,7 +146,7 @@ func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICR
112146
//
113147
// To turn on iov offload, the reverse order is used.
114148
if req.IovPolicySettings.IovOffloadWeight == 0 {
115-
if _, err := client.ModifyNIC(ctx, caReq); err != nil {
149+
if _, err := agent.ModifyNIC(ctx, caReq); err != nil {
116150
return nil, err
117151
}
118152
if err := modifyEndpoint(ctx, ep.Id, policies, hcn.RequestTypeUpdate); err != nil {
@@ -125,7 +159,7 @@ func (s *grpcService) ModifyNIC(ctx context.Context, req *ncproxygrpc.ModifyNICR
125159
if err := modifyEndpoint(ctx, ep.Id, policies, hcn.RequestTypeUpdate); err != nil {
126160
return nil, errors.Wrap(err, "failed to modify network adapter")
127161
}
128-
if _, err := client.ModifyNIC(ctx, caReq); err != nil {
162+
if _, err := agent.ModifyNIC(ctx, caReq); err != nil {
129163
return nil, err
130164
}
131165
}
@@ -148,13 +182,13 @@ func (s *grpcService) DeleteNIC(ctx context.Context, req *ncproxygrpc.DeleteNICR
148182
if req.ContainerID == "" || req.EndpointName == "" || req.NicID == "" {
149183
return nil, status.Errorf(codes.InvalidArgument, "received empty field in request: %+v", req)
150184
}
151-
if client, ok := containerIDToShim[req.ContainerID]; ok {
185+
if agent, ok := s.containerIDToComputeAgent.get(req.ContainerID); ok {
152186
caReq := &computeagent.DeleteNICInternalRequest{
153187
ContainerID: req.ContainerID,
154188
NicID: req.NicID,
155189
EndpointName: req.EndpointName,
156190
}
157-
if _, err := client.DeleteNIC(ctx, caReq); err != nil {
191+
if _, err := agent.DeleteNIC(ctx, caReq); err != nil {
158192
if err == uvm.ErrNICNotFound || err == uvm.ErrNetNSNotFound {
159193
return nil, status.Errorf(codes.NotFound, "failed to remove endpoint %q from namespace %q", req.EndpointName, req.NicID)
160194
}
@@ -553,10 +587,15 @@ func (s *grpcService) GetNetworks(ctx context.Context, req *ncproxygrpc.GetNetwo
553587
}, nil
554588
}
555589

556-
// TTRPC service exposed for use by the shim. Holds a mutex for updating map of
557-
// client connections.
590+
// TTRPC service exposed for use by the shim.
558591
type ttrpcService struct {
559-
m sync.Mutex
592+
containerIDToComputeAgent *computeAgentCache
593+
}
594+
595+
func newTTRPCService(agentCache *computeAgentCache) *ttrpcService {
596+
return &ttrpcService{
597+
containerIDToComputeAgent: agentCache,
598+
}
560599
}
561600

562601
func (s *ttrpcService) RegisterComputeAgent(ctx context.Context, req *ncproxyttrpc.RegisterComputeAgentRequest) (_ *ncproxyttrpc.RegisterComputeAgentResponse, err error) {
@@ -579,9 +618,8 @@ func (s *ttrpcService) RegisterComputeAgent(ctx context.Context, req *ncproxyttr
579618
)
580619
// Add to global client map if connection succeeds. Don't check if there's already a map entry
581620
// just overwrite as the client may have changed the address of the config agent.
582-
s.m.Lock()
583-
defer s.m.Unlock()
584-
containerIDToShim[req.ContainerID] = computeagent.NewComputeAgentClient(client)
621+
s.containerIDToComputeAgent.put(req.ContainerID, computeagent.NewComputeAgentClient(client))
622+
585623
return &ncproxyttrpc.RegisterComputeAgentResponse{}, nil
586624
}
587625

cmd/ncproxy/run.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/Microsoft/go-winio/pkg/etwlogrus"
1616
"github.com/Microsoft/go-winio/pkg/guid"
1717
"github.com/Microsoft/hcsshim/cmd/ncproxy/nodenetsvc"
18-
"github.com/Microsoft/hcsshim/internal/computeagent"
1918
"github.com/Microsoft/hcsshim/internal/debug"
2019
"github.com/Microsoft/hcsshim/internal/log"
2120
"github.com/Microsoft/hcsshim/internal/oc"
@@ -33,8 +32,6 @@ type nodeNetSvcConn struct {
3332
}
3433

3534
var (
36-
// Global mapping of network namespace ID to shim compute agent ttrpc service.
37-
containerIDToShim = make(map[string]computeagent.ComputeAgentService)
3835
// Global object representing the connection to the node network service that
3936
// ncproxy will be talking to.
4037
nodeNetSvcClient *nodeNetSvcConn

cmd/ncproxy/server.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ func newServer(ctx context.Context, conf *config) (*server, error) {
3636
}
3737

3838
func (s *server) setup(ctx context.Context) (net.Listener, net.Listener, error) {
39-
ncproxygrpc.RegisterNetworkConfigProxyServer(s.grpc, &grpcService{})
40-
ncproxyttrpc.RegisterNetworkConfigProxyService(s.ttrpc, &ttrpcService{})
39+
agentCache := newComputeAgentCache()
40+
gService := newGRPCService(agentCache)
41+
ncproxygrpc.RegisterNetworkConfigProxyServer(s.grpc, gService)
42+
43+
tService := newTTRPCService(agentCache)
44+
ncproxyttrpc.RegisterNetworkConfigProxyService(s.ttrpc, tService)
4145

4246
ttrpcListener, err := winio.ListenPipe(s.conf.TTRPCAddr, nil)
4347
if err != nil {

0 commit comments

Comments
 (0)