fix: remove dead sessions from target session list - #132
Merged
Conversation
When an iSCSI connection closes or a logout occurs, the associated session was never removed from the target's Sessions map, and the TSIH was never released back to the bitmap allocator. This caused session and TSIH leaks over repeated connect/disconnect cycles. Changes: - Add removeConnectionFromSession() to properly clean up session when its last connection is closed - Call session cleanup from handler() on CONN_STATE_CLOSE - Convert iscsiExecLogout to a method and add session cleanup on logout - Release TSIH in UnBindISCSISession to prevent TSIH bitmap exhaustion Fixes #42 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move session cleanup out of iscsiExecLogout() and keep it only in the CONN_STATE_CLOSE handler. The logout response must be fully sent before the session is removed; cleaning up during logout causes the daemon to hang because subsequent operations reference a nil session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a new login arrives while the previous connection's async cleanup is still running, LookupISCSISession finds the stale session but LookupConnection returns nil (old connection already closed). This caused a nil pointer dereference when accessing existConn.session during session reinstatement. Fix by checking existConn != nil before reinstatement. If the old connection is already gone, unbind the stale session and create a fresh one instead. Also add sync.Once to removeConnectionFromSession to prevent concurrent goroutine and main-path cleanup from racing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restore CurrentHostIP cleanup on connection close (needed for blockMultipleHostLogin feature). Extract to clearHostIP helper to reduce duplication. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Discovery sessions have nil Target and nil ITNexus. The cleanup path crashed with nil pointer dereference when trying to remove ITNexus or access Target.Sessions for discovery sessions. Guard against nil Target (just release TSIH) and nil ITNexus. Also add nil safety to clearHostIP helper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #42
When an iSCSI connection closes or a logout request is received, the associated session was never removed from the target's
Sessionsmap, theITNexuswas never cleaned up, and the TSIH was never released. This caused resource leaks on every connect/disconnect cycle.Root Cause Analysis
UnBindISCSISession()was only called fromReInstatement()(session replacement). It was never called from:handler()when connection entersCONN_STATE_CLOSE(normal disconnect, error, etc.)iscsiExecLogout()when initiator sends a logout requestAdditionally,
ReleaseTSIH()existed but was never called anywhere, so TSIHs were allocated but never freed.Impact
target.SessionsmapITNexusentries leak intarget.ITNexusmapChanges
pkg/port/iscsit/session.go:UnBindISCSISession(): Now also callsReleaseTSIH()to free the TSIHremoveConnectionFromSession(): Removes a connection from its session; if no connections remain, unbinds the session entirely. Usesconn.session = nilguard to prevent double-cleanup.pkg/port/iscsit/iscsid.go:handler(): CallsremoveConnectionFromSession(conn)before closing the TCP connection onCONN_STATE_CLOSEiscsiExecLogout(): Converted from free function toISCSITargetDrivermethod; now callsremoveConnectionFromSession()to clean up session on logoutTest plan
go build ./...passesgo test ./pkg/... ./mock/...all pass🤖 Generated with Claude Code