diff --git a/server.go b/server.go index b3d0732..1da87a6 100644 --- a/server.go +++ b/server.go @@ -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+"/") { diff --git a/store/session.go b/store/session.go index 87a0a61..4f47793 100644 --- a/store/session.go +++ b/store/session.go @@ -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) }