diff --git a/pkg/port/iscsit/conn.go b/pkg/port/iscsit/conn.go index 19fb165..be6f6a0 100644 --- a/pkg/port/iscsit/conn.go +++ b/pkg/port/iscsit/conn.go @@ -88,7 +88,8 @@ type iscsiConnection struct { rxTask *iscsiTask txTask *iscsiTask - readLock *sync.RWMutex + readLock *sync.RWMutex + cleanupOnce sync.Once } type taskState int diff --git a/pkg/port/iscsit/session.go b/pkg/port/iscsit/session.go index faf49ef..d3bb8ea 100644 --- a/pkg/port/iscsit/session.go +++ b/pkg/port/iscsit/session.go @@ -340,21 +340,24 @@ func (s *ISCSITargetDriver) UnBindISCSISession(sess *ISCSISession) { // removeConnectionFromSession removes a connection from its session. // If the session has no remaining connections, the session is unbound. +// This is safe to call concurrently; cleanup runs at most once per connection. func (s *ISCSITargetDriver) removeConnectionFromSession(conn *iscsiConnection) { - sess := conn.session - if sess == nil { - return - } + conn.cleanupOnce.Do(func() { + sess := conn.session + if sess == nil { + return + } - sess.ConnectionsRWMutex.Lock() - delete(sess.Connections, conn.cid) - remaining := len(sess.Connections) - sess.ConnectionsRWMutex.Unlock() + sess.ConnectionsRWMutex.Lock() + delete(sess.Connections, conn.cid) + remaining := len(sess.Connections) + sess.ConnectionsRWMutex.Unlock() - if remaining == 0 { - s.UnBindISCSISession(sess) - } - conn.session = nil + if remaining == 0 { + s.UnBindISCSISession(sess) + } + conn.session = nil + }) } func (s *ISCSITargetDriver) BindISCSISession(conn *iscsiConnection) error { @@ -433,7 +436,13 @@ func (s *ISCSITargetDriver) BindISCSISession(conn *iscsiConnection) error { if conn.loginParam.tsih == ISCSI_UNSPEC_TSIH { log.Infof("Session Reinstatement initiator name:%v,target name:%v,ISID:0x%x", conn.loginParam.initiator, conn.loginParam.target, conn.loginParam.isid) - newSess, err = s.ReInstatement(existConn.session, conn) + if existConn != nil { + newSess, err = s.ReInstatement(existConn.session, conn) + } else { + // Old connection already closed; unbind the stale session and create new + s.UnBindISCSISession(existSess) + newSess, err = s.NewISCSISession(conn) + } if err != nil { return err }