fix data race

Since state.Checks() returns a shallow copy
its elements must not be modified. Copying
the elements in the handler does not guarantee
consistency since that list is guarded by a different
lock. Therefore, the only solution is to have state.Checks()
return a deep copy.
This commit is contained in:
Frank Schroeder 2017-09-26 13:42:10 +02:00
parent 1530f12f56
commit 94fbae4732
No known key found for this signature in database
GPG Key ID: 4D65C6EAEC87DECD
2 changed files with 6 additions and 3 deletions

View File

@ -152,6 +152,7 @@ func (s *HTTPServer) AgentChecks(resp http.ResponseWriter, req *http.Request) (i
}
// Use empty list instead of nil
// checks needs to be a deep copy for this not be racy
for _, c := range checks {
if c.ServiceTags == nil {
c.ServiceTags = make([]string, 0)

View File

@ -341,12 +341,14 @@ func (l *localState) UpdateCheck(checkID types.CheckID, status, output string) {
// Checks returns the locally registered checks that the
// agent is aware of and are being kept in sync with the server
func (l *localState) Checks() map[types.CheckID]*structs.HealthCheck {
checks := make(map[types.CheckID]*structs.HealthCheck)
l.RLock()
defer l.RUnlock()
for checkID, check := range l.checks {
checks[checkID] = check
checks := make(map[types.CheckID]*structs.HealthCheck)
for id, c := range l.checks {
c2 := new(structs.HealthCheck)
*c2 = *c
checks[id] = c2
}
return checks
}