Files
seaweedfs/weed/storage/blockvol/iscsi/discovery.go
T
Ping QiuandClaude Opus 4.6 09c7e40d29 feat: Phase 4A CP4a -- simulated master, assignment sequence tests, BlockVolumeStatus
Add SimulatedMaster test helper + 20 assignment sequence tests (8 sequence,
5 failover, 5 adversarial, 2 status). Add BlockVolumeStatus struct and
Status() method. Includes QA test files for CP1-CP4a. 940 total unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 09:33:45 -08:00

69 lines
1.8 KiB
Go

package iscsi
// HandleTextRequest processes a Text Request PDU.
// Currently supports SendTargets discovery (RFC 7143, Section 12.3).
func HandleTextRequest(req *PDU, targets []DiscoveryTarget) *PDU {
resp := &PDU{}
resp.SetOpcode(OpTextResp)
resp.SetOpSpecific1(FlagF) // Final
resp.SetInitiatorTaskTag(req.InitiatorTaskTag())
resp.SetTargetTransferTag(0xFFFFFFFF) // no continuation
params, err := ParseParams(req.DataSegment)
if err != nil {
// Malformed -- return empty response
return resp
}
val, ok := params.Get("SendTargets")
if !ok {
return resp
}
// Discovery responses can have duplicate keys (TargetName appears
// for each target), so we use EncodeDiscoveryTargets directly.
var matched []DiscoveryTarget
switch val {
case "All":
matched = targets
default:
for _, tgt := range targets {
if tgt.Name == val {
matched = append(matched, tgt)
break
}
}
}
if data := EncodeDiscoveryTargets(matched); len(data) > 0 {
resp.DataSegment = data
}
return resp
}
// DiscoveryTarget represents a target available for discovery.
type DiscoveryTarget struct {
Name string // IQN, e.g., "iqn.2024.com.seaweedfs:vol1"
Address string // IP:port,portal-group, e.g., "10.0.0.1:3260,1"
}
// EncodeDiscoveryTargets encodes multiple targets into text parameter format.
// Each target produces TargetName=<iqn>\0TargetAddress=<addr>\0
// This handles the special multi-value encoding where the same key can appear
// multiple times (unlike normal negotiation params).
func EncodeDiscoveryTargets(targets []DiscoveryTarget) []byte {
if len(targets) == 0 {
return nil
}
var buf []byte
for _, tgt := range targets {
buf = append(buf, "TargetName="+tgt.Name+"\x00"...)
if tgt.Address != "" {
buf = append(buf, "TargetAddress="+tgt.Address+"\x00"...)
}
}
return buf
}