@@ -24,7 +24,10 @@ import (
2424 pi "knative.dev/security-guard/pkg/pluginterfaces"
2525)
2626
27- var maxPileCount = uint32 (1000 )
27+ const (
28+ pileMergeLimit = uint32 (1000 )
29+ numSamplesLimit = uint32 (1000000 )
30+ )
2831
2932// A cached record kept by guard-service for each deployed service
3033type serviceRecord struct {
@@ -72,7 +75,6 @@ func (s *services) tick() {
7275 // Tick should not include any asynchronous work
7376 // Move all asynchronous work (e.g. KubeApi work) to go routines
7477 s .mutex .Lock ()
75- defer s .mutex .Unlock ()
7678
7779 if len (s .tickerKeys ) == 0 {
7880 // Assign more work to be done now and in future ticks
@@ -90,18 +92,28 @@ func (s *services) tick() {
9092 maxIterations = 100
9193 }
9294
93- // try to learn one record
94- i := 0
95+ // find a record to learn
96+ i := 0 // i is the index of the record to learn
97+ var record * serviceRecord
9598 for ; i < maxIterations ; i ++ {
96- if record , exists := s.cache [s.tickerKeys [i ]]; exists {
97- // we still have this record, lets learn it
98- if s .learnPile (record ) {
99- // we learned one record
99+ r , exists := s.cache [s.tickerKeys [i ]]
100+ if exists {
101+ if r .pile .Count != 0 {
102+ // we will learn this record!
103+ record = r
104+ // (during the next tick we should try the next one)
100105 i ++
101106 break
102107 }
103108 }
104109 }
110+ s .mutex .Unlock ()
111+ // Must unlock s.mutex before s.learnPile
112+
113+ if record != nil {
114+ // lets learn it
115+ s .learnPile (record )
116+ }
105117
106118 // remove the keys we processed from the key slice
107119 s .tickerKeys = s .tickerKeys [i :]
@@ -132,6 +144,7 @@ func (s *services) get(ns string, sid string, cmFlag bool) *serviceRecord {
132144 // try to get from cache
133145 record := s .cache [service ]
134146 s .mutex .Unlock ()
147+ // Must unlock s.mutex before s.kmgr.Watch, s.kmgr.GetGuardian, s.set
135148
136149 // watch any unknown namespace
137150 if ! knownNamespace {
@@ -153,6 +166,7 @@ func (s *services) set(ns string, sid string, cmFlag bool, guardianSpec *spec.Gu
153166 service := serviceKey (ns , sid , cmFlag )
154167
155168 s .mutex .Lock ()
169+ defer s .mutex .Unlock ()
156170 record , exists := s .cache [service ]
157171 if ! exists {
158172 record = new (serviceRecord )
@@ -162,7 +176,6 @@ func (s *services) set(ns string, sid string, cmFlag bool, guardianSpec *spec.Gu
162176 record .cmFlag = cmFlag
163177 s .cache [service ] = record
164178 }
165- s .mutex .Unlock ()
166179
167180 record .guardianSpec = guardianSpec
168181 pi .Log .Debugf ("cache record for %s.%s" , ns , sid )
@@ -184,37 +197,33 @@ func (s *services) merge(record *serviceRecord, pile *spec.SessionDataPile) {
184197 record .pileMutex .Lock ()
185198 record .pile .Merge (pile )
186199 record .pileMutex .Unlock ()
187- if record .pile .Count > maxPileCount {
200+ // Must unlock pileMutex before s.learnPile
201+
202+ if record .pile .Count > pileMergeLimit {
188203 s .learnPile (record )
189204 }
190205}
191206
192207// update the record guardianSpec by learning a new config and fusing with the record existing config
193208// update KubeAPI as well.
194209// return true if we try to learn and access kubeApi, false if count is zero and we have nothing to do
195- func (s * services ) learnPile (record * serviceRecord ) bool {
196- if record .pile . Count == 0 {
197- return false
210+ func (s * services ) learnPile (record * serviceRecord ) {
211+ if record .guardianSpec . Learned == nil {
212+ record . guardianSpec . Learned = new (spec. SessionDataConfig )
198213 }
199- config := new (spec.SessionDataConfig )
200214
201215 record .pileMutex .Lock ()
202- config .Learn (& record .pile )
216+ record .guardianSpec .Learned .Learn (& record .pile )
217+ record .guardianSpec .NumSamples += record .pile .Count
218+ if record .guardianSpec .NumSamples > numSamplesLimit {
219+ record .guardianSpec .NumSamples = numSamplesLimit
220+ }
203221 record .pile .Clear ()
204222 record .pileMutex .Unlock ()
205-
206- if record .guardianSpec .Learned != nil {
207- config .Fuse (record .guardianSpec .Learned )
208- }
209-
210- // update the cached record
211- record .guardianSpec .Learned = config
212- record .guardianSpec .Learned .Active = true
223+ // Must unlock record.pileMutex before s.persist
213224
214225 // update the kubeApi record
215226 go s .persist (record )
216-
217- return true
218227}
219228
220229func (s * services ) persist (record * serviceRecord ) {
0 commit comments