fix: deadlock in session rename (lock ordering inversion)
This commit is contained in:
parent
4cf8a666e3
commit
d9622dfc7a
|
|
@ -283,7 +283,10 @@ func New(sink *olog.Sink, opts ...ServerOption) *Server {
|
|||
s.AddGroup("agent", newID)
|
||||
oldPrefix := "/s/" + oldID
|
||||
newPrefix := "/s/" + newID
|
||||
for _, c := range s.conns {
|
||||
s.mu.RLock()
|
||||
conns := s.conns
|
||||
s.mu.RUnlock()
|
||||
for _, c := range conns {
|
||||
c.mu.Lock()
|
||||
for _, f := range c.fids {
|
||||
if f.path == oldPrefix || strings.HasPrefix(f.path, oldPrefix+"/") {
|
||||
|
|
|
|||
|
|
@ -465,27 +465,34 @@ func (s *SessionStore) createSession(args []string) error {
|
|||
|
||||
func (s *SessionStore) renameSession(oldID, newID string) error {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
sess, ok := s.sessions[oldID]
|
||||
if !ok {
|
||||
s.mu.Unlock()
|
||||
return fmt.Errorf("session not found: %s", oldID)
|
||||
}
|
||||
if _, exists := s.sessions[newID]; exists {
|
||||
s.mu.Unlock()
|
||||
return fmt.Errorf("session already exists: %s", newID)
|
||||
}
|
||||
if sess.Core.IsRunning() {
|
||||
s.mu.Unlock()
|
||||
return fmt.Errorf("cannot rename while agent is running")
|
||||
}
|
||||
|
||||
if err := sess.Core.SetSessionID(newID); err != nil {
|
||||
s.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
sess.id = newID
|
||||
s.sessions[newID] = sess
|
||||
delete(s.sessions, oldID)
|
||||
s.mu.Unlock()
|
||||
|
||||
// OnRename must be called without holding s.mu to avoid deadlock
|
||||
// with connection handlers that hold connState.mu and call into
|
||||
// SessionStore (e.g. SessionByUname during Tattach).
|
||||
if s.cfg.OnRename != nil {
|
||||
s.cfg.OnRename(oldID, newID)
|
||||
}
|
||||
|
|
|
|||
Reference in New Issue