125 Commits

Author SHA1 Message Date
Lei Xue
a7b58b8eb3 fix: handle discovery sessions in UnBindISCSISession
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>
2026-03-17 15:01:22 +08:00
Lei Xue
be3cad5aba fix: extract clearHostIP helper and restore IP cleanup on close
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>
2026-03-17 14:54:08 +08:00
Lei Xue
8ffe5ec5ce fix: prevent nil deref on session reinstatement during cleanup race
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>
2026-03-17 14:37:16 +08:00
Lei Xue
b7e5c4a7d2 fix: defer session cleanup to connection close, not logout
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>
2026-03-17 14:11:27 +08:00
Lei Xue
70e1955487 fix: remove dead sessions from target session list
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>
2026-03-16 17:22:01 +08:00
Lei Xue
76ab15b0df feat: add S3-compatible object storage backend
Add a new backend store that enables iSCSI targets backed by
S3-compatible object storage (AWS S3, MinIO, Ceph RGW, etc.).

The implementation uses a chunked storage strategy where the virtual
block device is divided into fixed-size chunks (default 4 MiB), each
stored as an independent S3 object. This enables efficient random
read/write access on top of object storage.

Key features:
- Chunked storage with configurable chunk size
- Sparse device support (unwritten chunks treated as zeros)
- Concurrent multi-chunk I/O via errgroup
- Per-chunk locking for safe read-modify-write
- AWS SDK v2 with default credential chain
- In-process gofakes3 test server (no Docker needed)
- 12 unit tests + 2 integration tests

Also updates CI workflow to run S3 backend tests and updates
README with S3 backend documentation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 16:22:57 +08:00
Lei Xue
93e1476a0f feat: implement cmd management for targets, LUNs, and TPGTs (fixes #36)
- Fix target delete URL path mismatch (/targets/ -> /target/)
- Implement target create/delete server handlers with proper validation
- Add DeleteTarget method with force flag and mutex locking to SCSITargetService
- Implement full LU management: create/list/delete through CLI, client, and server
- Add TPGT list command to show target portal group tags
- Add unit tests for target/LU router handlers and SCSI service

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 20:30:47 +08:00
Lei Xue
a5628f4ec0 add end-to-end IO benchmarks and fix pprof-identified hotspots
Add comprehensive benchmark suite (io_bench_test.go):
- BenchmarkEndToEndRead/Write: full SCSI stack (512B to 256KB)
- BenchmarkEndToEndReadParallel/WriteParallel: concurrent IO
- BenchmarkFileBackingStoreRead/Write: isolated backing store

pprof-guided optimizations:
- Guard hot-path log.Debugf with log.GetLevel() check in scsi.go,
  sbc.go, backingstore.go — eliminates 22% CPU overhead from logrus
  Entry allocation even when debug logging is disabled
- Add FileBackingStore.ReadAt for zero-copy reads directly into
  caller's buffer, bypassing Read()'s per-call make([]byte, tl)
- Use ReadAt via interface assertion in bsPerformCommand to read
  directly into InSDBBuffer, eliminating allocation + copy

Results (256KB reads): +42% throughput, allocs reduced from 10 to 5

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 19:41:48 +08:00
Lei Xue
16108ced95 optimize performance: reduce allocations, buffered I/O, and zero-copy reads
- Read path: eliminate redundant allocation in bsPerformCommand - remove
  the pre-allocation before bs.Read() and the append loop for zero-fill,
  use direct copy and in-place zero-fill instead
- parseHeader: use command pool (getCommand) instead of direct allocation,
  reducing GC pressure on the hot path
- Unmap: use a shared 1MB zero buffer instead of allocating per-descriptor,
  dramatically reducing allocations for large unmap operations
- Network I/O: add 256KB bufio.Writer to iSCSI connections, batching
  small PDU writes into fewer syscalls. Flush after txHandler completes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 19:03:30 +08:00
Lei Xue
633b84009c fix versionMatcher: use non-capturing group (?:-dirty)? for gorilla/mux
gorilla/mux explicitly rejects capturing groups () in route regexps,
only non-capturing groups (?:) are allowed. The original regex was
missing the ? to make -dirty optional.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 18:51:01 +08:00
Lei Xue
549f0cb460 fix gofmt import ordering
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 18:30:49 +08:00
Lei Xue
f1cec4f5d4 fix regex, remove unsafe pointer usage, and add graceful HTTP shutdown
- Fix versionMatcher regex: gorilla/mux does not support (?:) syntax,
  and -dirty suffix was required instead of optional
- Replace unsafe.Pointer LUN casts with binary.LittleEndian.Uint64
  in sbc.go, scsi.go, and target.go
- Implement graceful HTTP server shutdown with 5s timeout using
  srv.Shutdown() instead of raw listener close
- Replace golang.org/x/net/context with standard library context
- Respect existing req.Cancel value in canceler to avoid overwriting
- Add early context cancellation check in Do() to fail fast

Based on review of PR #120 by @orzhang, with fixes applied.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 18:27:56 +08:00
Lei Xue
36149cd4a9 support more SCSI commands: ReadDefectData, Sanitize, and expanded CI
New SCSI commands implemented:
- READ DEFECT DATA(10/12): returns empty defect list (virtual device)
- SANITIZE: supports OVERWRITE and BLOCK ERASE (zeros all blocks)
- EXTENDED COPY / RECEIVE COPY RESULTS: registered as unsupported

New unit tests for ReadDefectData10/12, Sanitize, and command registration.

New CI libiscsi test cases:
- PersistentReservation (PrinReadKeys, PrinReportCapabilities,
  ProutRegister, ProutReserve)
- ReadDefectData10/12 (Simple)
- CompareAndWrite (Simple)
- OrWrite (Simple, BeyondEol, ZeroBlocks)
- GetLBAStatus (Simple, BeyondEol)
- ReportSupportedOpcodes (OneCommand)

Partial fix for #55

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 13:06:35 +08:00
Lei Xue
3c41cd619b Merge pull request #123 from gostor/fix/unmap-data-corruption
fix UNMAP data corruption by implementing block zeroing
2026-03-14 12:31:48 +08:00
Lei Xue
00d0c3a306 fix UNMAP data corruption by implementing block zeroing
The UNMAP command was a no-op in all backing stores, causing unmapped
blocks to retain stale data instead of returning zeros per SCSI spec.

- Implement Unmap in FileBackingStore to zero out unmapped blocks
- Implement Unmap in IOUringBackingStore to zero out unmapped blocks
- Enable Unmap in RemBackingStore (was commented out)
- Change UnmapBlockDescriptor.TL from uint32 to uint64 to prevent
  integer overflow when converting block count to byte length with
  large block shifts

Fixes #119

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 12:29:12 +08:00
Lei Xue
b2776dc5c2 fix critical bugs and improve iSCSI protocol compliance
- Fix nil pointer dereference in BindISCSISession when existSess is nil
- Fix reversed logic in SPCLuOffline/SPCLuOnline (Online flag was swapped)
- Use negotiated MaxXmitDataSegmentLength for response PDU segmentation (issue #41)
- Fix debug log incorrectly using Warn level in SBCGetLbaStatus

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 12:11:23 +08:00
Lei Xue
00cfac3d24 optimize the perf and support more features 2026-03-14 11:45:35 +08:00
Wenhua Shi
a6cf150e95 fix some issues 2023-04-17 19:29:01 +08:00
Lei Xue
d94641a8d7 add target port as command flag 2022-12-13 09:49:34 +08:00
Lei Xue
1c9f8d3e06 fix part of golint 2022-12-11 09:59:06 +08:00
Lei Xue
8a3e19f0c9 fix daemon 's host flag 2022-12-10 22:05:19 +08:00
Lei Xue
d92d540c52 gofmt -s 2022-12-10 21:05:52 +08:00
Lei Xue
7745d3ae3b compile with 'ceph' flag to enable/disable cephstore 2022-12-08 17:51:02 +08:00
Lei Xue
82b42798ee Merge pull request #103 from jeremy-gill/master
Add support for block device storage endpoints.
2022-12-08 17:22:37 +08:00
prateekpandey14
22c2b95d8f fix(state): reset the CurrentHostIP on closed iscsi connection
Signed-off-by: prateekpandey14 <prateekpandey14@gmail.com>
2021-08-16 20:54:04 +05:30
shubham
b278ab3133 Add flag to disable login on multiple hosts
Signed-off-by: shubham <shubham.bajpai@mayadata.io>
2021-06-29 21:15:54 +05:30
Jeremy Gill
a8468ecec8 Resolve travis-ci / gofmt issue with common.go 2020-12-15 11:26:26 -05:00
Payes Anand
e5e3c09feb nit: remove unnecessary if-else block
Signed-off-by: Payes Anand <payes.anand@mayadata.io>
2020-12-06 13:44:13 +05:30
Payes Anand
ec418673cb fix: concurrent map iteration and map write
Signed-off-by: Payes Anand <payes.anand@mayadata.io>
2020-12-05 14:51:52 +05:30
Jeremy Gill
228e53351d Add support for block device storage endpoints. 2020-09-04 13:28:51 -04:00
Lei Xue
2e5cea1bd0 add version
Signed-off-by: Lei Xue <vfs@live.com>
2020-07-14 22:04:20 +08:00
Chris Koch
6af024c2e3 iscsit: support AuthMethod=None security negotiation
Signed-off-by: Chris Koch <chrisko@google.com>
2020-01-21 22:45:18 -08:00
Utkarsh Mani Tripathi
901974d8c4 remove conn.close
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-28 13:55:36 +05:30
Utkarsh Mani Tripathi
7f31722587 Listen on configured IP
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-26 17:45:09 +05:30
Utkarsh Mani Tripathi
dbb4ad7eb2 fix gofmt error
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-21 19:27:01 +05:30
Utkarsh Mani Tripathi
583e9b3a4a Add option to disable multipath and other fixes
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-21 13:42:32 +05:30
Utkarsh Mani Tripathi
25f0038456 Add tgtNSG to fullfeaturephase and tgtTrans to true
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-20 17:03:58 +05:30
Utkarsh Mani Tripathi
d7891b1f68 Implement stats and resize and fix remote backing store apis
- Convert constant to var so that it can be configured from backend
- Add options to disable persistent reservation and ORWrite16 commands

Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-20 14:34:35 +05:30
Utkarsh Mani Tripathi
d7caf89610 Implement InitSCSILuMap func for jiva
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-19 10:19:58 +05:30
Utkarsh Mani Tripathi
1b02c7897e fix error handling for unsupported commands
- Respond with failure for unsupported task management commands
- Increase MaxRecvDataSegmentLength to 65536, to match FirstBurstLength

Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 18:20:59 +05:30
Utkarsh Mani Tripathi
64deda8106 convert initialR2T to always true for datadigest
tttttt-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 18:10:53 +05:30
Utkarsh Mani Tripathi
3b8e996a6c Reply with LUN busy when there is a read/write error from backend
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 16:30:46 +05:30
Utkarsh Mani Tripathi
a8cc3e6db2 improve logs and add client (initiator) status
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 16:25:55 +05:30
Utkarsh Mani Tripathi
e5339f347a Add nil pointer check for InSDBBuffer
- Gotgt was crashing for few opcodes (sg_inq (sg3-utils)) because InSDBBuffer
  was not initialized for such opcodes (Need help)

Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 15:56:34 +05:30
Utkarsh Mani Tripathi
1dbc82435f iSCSI target fixes for iSCSIResiduals tests causing libiscsi test suite to hang
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 15:16:41 +05:30
Utkarsh Mani Tripathi
f3ef8c973d add initial implementation of remote backing store
This commit implement the BackingStore Interface for remote backing
store.

Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-11-18 14:52:03 +05:30
Utkarsh Mani Tripathi
4f270eb4d8 fix the scsi inquiry command for TPGS
Signed-off-by: Utkarsh Mani Tripathi <utkarsh.tripathi@mayadata.io>
2019-09-29 07:26:53 +05:30
Lei Xue
5f8aa301ff Merge pull request #86 from datomia/max-unmap-descs
set max unmap block descriptor count to a feasible value
2019-07-04 15:14:20 +08:00
chessman
a83e8ce5c0 REPORT LUNS: truncate response by allocation length 2019-07-03 19:34:49 +03:00
Lei Xue
43deee91c0 Merge pull request #85 from datomia/fix-pool-leak
Fix memory leak
2019-06-30 18:57:44 +08:00