[FIXED] Locking issue around account lookup/updates

Ensure that lookupAccount does not hold server lock during
updateAccount and fetchAccount.
Updating the account cannot have the server lock because it is
possible that during updateAccountClaims(), clients are being
removed, which would try to get the server lock (deep down in
closeConnection/s.removeClient).
Added a test that would have show the deadlock prior to changes
in this PR.

Signed-off-by: Ivan Kozlovic <ivan@synadia.com>
This commit is contained in:
Ivan Kozlovic
2019-09-17 18:41:25 -06:00
parent b98b75b166
commit 150d47cab3
7 changed files with 141 additions and 72 deletions

View File

@@ -912,6 +912,8 @@ func (s *Server) reloadAuthorization() {
acc.mu.RLock()
accName := acc.Name
acc.mu.RUnlock()
// Release server lock for following actions
s.mu.Unlock()
accClaims, claimJWT, _ := s.fetchAccountClaims(accName)
if accClaims != nil {
err := s.updateAccountWithClaimJWT(acc, claimJWT)
@@ -923,9 +925,10 @@ func (s *Server) reloadAuthorization() {
s.Noticef("Reloaded: deleting account [removed]: %q", accName)
s.accounts.Delete(k)
}
// Regrab server lock.
s.mu.Lock()
return true
})
}
}