mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 23:14:21 +00:00
V2 runtime packages: - sw-block/runtime/masterv2: identity authority (desired state, heartbeat handling, promotion arbitration via SelectPromotionCandidate) - sw-block/runtime/volumev2: per-volume micro-cluster shell (node, orchestrator, control session, iSCSI frontend, takeover gate, failover session + driver, replica summary reconstruction) - sw-block/runtime/purev2: RF1 execution shell (engine + store + dispatcher + local boundary observations) - sw-block/runtime/protocolv2: three-channel separation (heartbeat/assignment/query + replica summary) V2 binaries: - sw-block/cmd/v2singleblock: single-node RF1 block server - sw-block/cmd/purev2rf1: minimal RF1 runtime binary Milestone capabilities: - RF1 write/read/sync with engine-driven mode projection - masterv2 ↔ volumev2 heartbeat convergence + assignment reissue - Promotion query with fresh CommittedLSN/WALHeadLSN evidence - Replica summary for bounded takeover reconstruction - Primary-loss reconstruction from peer summaries (fail-closed gate) - In-process failover driver with session observability - Local boundary observations feed engine (Committed/Durable/Checkpoint) Design docs: - v2-two-loop-protocol.md: identity vs data-control separation - v2-automata-ownership-map.md: event/command ownership split - v2-loop1-surface-draft.md: heartbeat/query/assignment field spec - v2-volumev2-single-node-mvp.md: target layering - v2-kernel-closure-review.md: per-volume micro-cluster principle - v2-pure-runtime-rf1-bootstrap.md, v2-capability-map.md, v2-proof-and-retest-pyramid.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
93 lines
2.0 KiB
Go
93 lines
2.0 KiB
Go
package volumev2
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/blockvol"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/blockvol/iscsi"
|
|
)
|
|
|
|
// ISCSITargetExport is a small handle for one running iSCSI frontend export.
|
|
type ISCSITargetExport struct {
|
|
iqn string
|
|
addr string
|
|
server *iscsi.TargetServer
|
|
}
|
|
|
|
// IQN returns the exported target name.
|
|
func (e *ISCSITargetExport) IQN() string {
|
|
if e == nil {
|
|
return ""
|
|
}
|
|
return e.iqn
|
|
}
|
|
|
|
// Address returns the current listen address.
|
|
func (e *ISCSITargetExport) Address() string {
|
|
if e == nil {
|
|
return ""
|
|
}
|
|
return e.addr
|
|
}
|
|
|
|
// Close stops the iSCSI target server.
|
|
func (e *ISCSITargetExport) Close() error {
|
|
if e == nil || e.server == nil {
|
|
return nil
|
|
}
|
|
return e.server.Close()
|
|
}
|
|
|
|
// ExportISCSI starts a small iSCSI target server for one named volume.
|
|
// This gives the single-node MVP a real block frontend without depending on weed/server.
|
|
func (n *Node) ExportISCSI(name, listenAddr, iqn string) (*ISCSITargetExport, error) {
|
|
if n == nil {
|
|
return nil, fmt.Errorf("volumev2: node is nil")
|
|
}
|
|
if listenAddr == "" {
|
|
listenAddr = "127.0.0.1:0"
|
|
}
|
|
if iqn == "" {
|
|
iqn = "iqn.2026-04.com.seaweedfs:v2." + name
|
|
}
|
|
path, err := n.pathFor(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var dev iscsi.BlockDevice
|
|
if err := n.dataPlane.WithVolume(path, func(vol *blockvol.BlockVol) error {
|
|
dev = blockvol.NewBlockVolAdapter(vol)
|
|
return nil
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
if dev == nil {
|
|
return nil, fmt.Errorf("volumev2: no block device for %q", name)
|
|
}
|
|
|
|
cfg := iscsi.DefaultTargetConfig()
|
|
cfg.TargetName = iqn
|
|
logger := log.New(io.Discard, "", 0)
|
|
server := iscsi.NewTargetServer(listenAddr, cfg, logger)
|
|
server.AddVolume(iqn, dev)
|
|
|
|
ln, err := net.Listen("tcp", listenAddr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("volumev2: iscsi listen %s: %w", listenAddr, err)
|
|
}
|
|
server.SetPortalAddr(ln.Addr().String() + ",1")
|
|
go func() {
|
|
_ = server.Serve(ln)
|
|
}()
|
|
|
|
return &ISCSITargetExport{
|
|
iqn: iqn,
|
|
addr: ln.Addr().String(),
|
|
server: server,
|
|
}, nil
|
|
}
|