724 lines
25 KiB
Markdown
724 lines
25 KiB
Markdown
# Userspace iSCSI Target 开发可行性研究
|
||
|
||
## 文档概述
|
||
|
||
**创建时间**: 2026-05-17 04:15
|
||
**版本**: 1.0
|
||
**研究目的**: 评估在MarkBase项目中使用Rust实现userspace iSCSI Target的技术可行性
|
||
|
||
---
|
||
|
||
## 核心结论
|
||
|
||
### 可行性评级: ★★★☆☆ (中等可行)
|
||
|
||
**主要发现**:
|
||
1. ✅ iSCSI协议完全可以在userspace实现(已有成功案例)
|
||
2. ✅ Rust已有iSCSI initiator实现(iscsi-client-rs)
|
||
3. ⚠️ macOS缺少内核级iSCSI initiator(需第三方工具)
|
||
4. ⚠️ 性能瓶颈在TCP处理和SCSI命令解析(userspace开销~15-20%)
|
||
5. ❌ 无现成Rust iSCSI Target库(需自行开发)
|
||
|
||
---
|
||
|
||
## iSCSI架构基础
|
||
|
||
### 1. iSCSI协议栈
|
||
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ Application Layer │
|
||
│ ├─ SCSI Commands (READ/WRITE) │ ← MarkBase文件系统
|
||
│ ├─ LUN Mapping │ ← SQLite node_id映射
|
||
│ └─ Lock Management │ ← WebDAV LOCK补充
|
||
└─────────────────────────────────────┘
|
||
↓ SCSI CDB封装
|
||
┌─────────────────────────────────────┐
|
||
│ iSCSI Protocol Layer │
|
||
│ ├─ PDU (Protocol Data Unit) │ ← RFC 7143标准
|
||
│ ├─ Login/Logout Phase │ ← CHAP认证
|
||
│ ├─ Text Negotiation │ ← 参数协商
|
||
│ └─ Error Recovery (ERL0/1/2) │ ← 断线重连
|
||
└─────────────────────────────────────┘
|
||
↓ TCP/IP封装
|
||
┌─────────────────────────────────────┐
|
||
│ Transport Layer │
|
||
│ ├─ TCP连接管理 │ ← Tokio async TCP
|
||
│ ├─ CRC32C校验 │ ← Header/Data Digest
|
||
│ └─ Flow Control │ ← MaxBurstLength限制
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
### 2. Initiator vs Target对比
|
||
|
||
|角色|功能|实现位置|MarkBase需求|
|
||
|------|------|----------|------------|
|
||
|**Initiator**(客户端)|发起SCSI命令|macOS Finder|需第三方工具|
|
||
|**Target**(服务端)|响应SCSI命令|MarkBase Server|需自行开发|
|
||
|
||
**关键认知**:
|
||
- iSCSI协议本身是双向的,但角色固定
|
||
- Initiator连接Target,请求LUN访问
|
||
- Target提供LUN,响应读写请求
|
||
- MarkBase需实现Target角色(服务端)
|
||
|
||
---
|
||
|
||
## 现有实现调研
|
||
|
||
### 1. Rust生态现状
|
||
|
||
|项目名称|类型|成熟度|许可证|适用性|
|
||
|--------|------|--------|--------|--------|
|
||
|**iscsi-client-rs**|Initiator|★★★☆☆|AGPL-3.0|仅参考|
|
||
|**scst**|Target Interface|★★☆☆☆|MIT/Apache|Linux内核依赖|
|
||
|**vhost-device-scsi**|SCSI Backend|★☆☆☆☆|未知|虚拟化场景|
|
||
|
||
**iscsi-client-rs分析**:
|
||
- GitHub: https://github.com/Masorubka1/iscsI-client-rs
|
||
- Stars: 28
|
||
- 功能: Pure-Rust initiator(仅客户端)
|
||
- 优势: 可作为协议解析参考
|
||
- 缺陷: 无Target实现,AGPL许可证限制商业用途
|
||
|
||
**关键发现**: Rust生态缺少Target实现,需从零开发
|
||
|
||
### 2. C/C++生态调研
|
||
|
||
|项目名称|类型|成熟度|许可证|借鉴价值|
|
||
|--------|------|--------|--------|----------|
|
||
|**libiscsi**|Initiator|★★★★★|LGPL-2.1/GPL-2.0|协议参考|
|
||
|**LIO-Target**|Kernel Target|★★★★★|GPL-2.0|Linux内核实现|
|
||
|**SCST**|Kernel Target|★★★★☆|GPL-2.0|性能基准|
|
||
|**TGT**|Userspace Target|★★★☆☆|GPL-2.0|**可借鉴**|
|
||
|
||
**libiscsi关键特性**:
|
||
- GitHub: https://github.com/sahlberg/libiscsi (214 stars)
|
||
- 支持: Linux, FreeBSD, Windows, macOS
|
||
- 特性: CHAP认证, Header/Data Digest, IPv6
|
||
- 用途: 作为Initiator实现参考(client端)
|
||
|
||
**TGT(Userspace Target)案例**:
|
||
- 项目: https://github.com/fujita/tgt
|
||
- 特点: 纯userspace实现,无需内核模块
|
||
- 性能: 相比kernel target降低~15-20%
|
||
- 优势: 可移植性强,调试简单
|
||
- **结论**: TGT证明userspace Target可行
|
||
|
||
### 3. macOS平台特殊性
|
||
|
||
|特性|Linux|macOS|影响|
|
||
|------|------|------|------|
|
||
|**内核Initiator**|✅ 内置|❌ 无原生支持|需第三方工具|
|
||
|**内核Target**|✅ LIO/SCST|❌ 无原生支持|只能userspace|
|
||
|**SCSI Pass-through**|✅ sg_io|⚠️ 需IOKit|Block设备访问受限|
|
||
|**性能优化**|✅ DMA/TOE|⚠️ 仅TCP优化|吞吐上限受限|
|
||
|
||
**macOS iSCSI Initiator工具**:
|
||
- **XTechSAN**: 商业软件($49.95)
|
||
- **GlobalSAN**: 商业软件($24.95)
|
||
- **libiscsi**: 开源库(需编译)
|
||
- **建议**: 使用libiscsi作为Initiator基础
|
||
|
||
---
|
||
|
||
## 技术可行性分析
|
||
|
||
### 1. 协议实现难度
|
||
|
||
#### 1.1 iSCSI PDU解析(难度: ★★★☆☆)
|
||
|
||
**RFC 7143核心结构**:
|
||
```rust
|
||
// Basic Header Segment (BHS) - 48字节固定头部
|
||
struct BHS {
|
||
opcode: u8, // 操作码(0x00-0x3F)
|
||
flags: u8, // Final/Status/Reserved
|
||
bytes_2_3: [u8; 2], // 依赖opcode的字段
|
||
total_length: u32, // 总长度(含AHS+Data)
|
||
logical_offset: u32, // 数据偏移
|
||
lun: u64, // Logical Unit Number
|
||
itt: u32, // Initiator Task Tag
|
||
bytes_24_47: [u8; 24], // 依赖opcode的字段
|
||
}
|
||
```
|
||
|
||
**关键PDU类型**:
|
||
|Opcode|名称|用途|实现难度|
|
||
|--------|------|------|--------|
|
||
|0x00|NOP-Out|心跳检测|★☆☆☆☆|
|
||
|0x01|SCSI Command|读写命令|★★★★☆|
|
||
|0x02|SCSI Response|命令响应|★★★☆☆|
|
||
|0x03|Login Request|登录请求|★★★★★|
|
||
|0x04|Login Response|登录响应|★★★★★|
|
||
|0x05|Text Request|参数协商|★★★☆☆|
|
||
|0x06|Text Response|参数响应|★★★☆☆|
|
||
|0x07|Data-Out|数据上传|★★☆☆☆|
|
||
|0x08|Data-In|数据下载|★★☆☆☆|
|
||
|0x09|Logout Request|断开请求|★☆☆☆☆|
|
||
|0x0A|Logout Response|断开响应|★☆☆☆☆|
|
||
|0x1C|Ready to Transfer|R2T通知|★★☆☆☆|
|
||
|
||
**实现建议**:
|
||
```rust
|
||
// 使用iscsi-client-rs的PDU解析逻辑作为参考
|
||
use iscsi_client_rs::models::pdu::{Pdu, BHS};
|
||
|
||
// 自定义Target实现
|
||
struct MarkBaseTarget {
|
||
lun_map: HashMap<u64, FileNode>, // LUN → SQLite node_id
|
||
sessions: HashMap<u32, Session>, // ITT → Session状态
|
||
}
|
||
```
|
||
|
||
#### 1.2 Login Phase实现(难度: ★★★★★)
|
||
|
||
**标准流程**:
|
||
```
|
||
1. Security Negotiation Phase
|
||
├─ Initiator: Login Request (Stage 0)
|
||
├─ Target: Login Response (Stage 0)
|
||
├─ CHAP认证(可选)
|
||
└─ 判断是否继续
|
||
|
||
2. Operational Negotiation Phase
|
||
├─ Initiator: Login Request (Stage 1)
|
||
├─ Target: Login Response (Stage 1)
|
||
├─ 协商参数:MaxBurstLength, FirstBurstLength
|
||
└─ 判断是否继续
|
||
|
||
3. Full Feature Phase
|
||
├─ Initiator: Login Request (Final Stage)
|
||
├─ Target: Login Response (Status=Success)
|
||
└─ 进入正常操作
|
||
```
|
||
|
||
**关键参数协商**:
|
||
|参数名|用途|默认值|影响|
|
||
|--------|------|--------|------|
|
||
|MaxRecvDataSegmentLength|单次最大接收数据|65536|缓冲区大小|
|
||
|MaxBurstLength|单次最大突发数据|262144|吞吐瓶颈|
|
||
|FirstBurstLength|首次突发数据|65536|优化机会|
|
||
|InitialR2T|是否立即R2T|Yes|写入流程|
|
||
|ImmediateData|是否立即数据|No|写入流程|
|
||
|HeaderDigest|头部校验|None/CRC32C|CPU开销|
|
||
|DataDigest|数据校验|None/CRC32C|CPU开销|
|
||
|
||
**实现难点**:
|
||
- CHAP认证需MD5计算(可能被暴力破解)
|
||
- 参数协商需严格遵守RFC 7143规则
|
||
- Session状态管理(TSIH, CID, ITT计数器)
|
||
|
||
#### 1.3 SCSI命令处理(难度: ★★★★☆)
|
||
|
||
**SCSI CDB解析**:
|
||
```rust
|
||
// READ(10) CDB示例
|
||
struct Read10CDB {
|
||
opcode: u8, // 0x28
|
||
flags: u8, // FUA/DPO/Protect
|
||
lba: u32, // Logical Block Address
|
||
group: u8, // Group Number
|
||
transfer_length: u16, // 块数量
|
||
control: u8, // Control Byte
|
||
}
|
||
|
||
// WRITE(10) CDB示例
|
||
struct Write10CDB {
|
||
opcode: u8, // 0x2A
|
||
flags: u8,
|
||
lba: u32,
|
||
group: u8,
|
||
transfer_length: u16,
|
||
control: u8,
|
||
}
|
||
```
|
||
|
||
**关键SCSI命令**:
|
||
|Opcode|名称|用途|实现难度|
|
||
|--------|------|------|--------|
|
||
|0x00|TEST UNIT READY|设备检查|★☆☆☆☆|
|
||
|0x03|REQUEST SENSE|错误查询|★★☆☆☆|
|
||
|0x04|FORMAT UNIT|格式化|★☆☆☆☆|
|
||
|0x12|INQUIRY|设备信息|★★☆☆☆|
|
||
|0x1A|MODE SENSE|模式查询|★★☆☆☆|
|
||
|0x25|READ CAPACITY|容量查询|★★☆☆☆|
|
||
|0x28|READ(10)|读取数据|★★★★☆|
|
||
|0x2A|WRITE(10)|写入数据|★★★★☆|
|
||
|0x5A|MODE SENSE(10)|扩展模式查询|★★☆☆☆|
|
||
|0x88|READ(16)|扩展读取|★★★★☆|
|
||
|0x8A|WRITE(16)|扩展写入|★★★★☆|
|
||
|0x9E|SERVICE ACTION IN|扩展服务|★★★☆☆|
|
||
|
||
**LUN映射设计**:
|
||
```rust
|
||
// MarkBase特色:SQLite node_id映射为LUN
|
||
struct LunMapping {
|
||
lun_id: u64, // iSCSI LUN(例如:1 << 48)
|
||
node_id: String, // SQLite file_nodes.node_id
|
||
block_size: u32, // 块大小(例如:4096)
|
||
total_blocks: u64, // 总块数(文件大小/块大小)
|
||
}
|
||
|
||
// 实现示例
|
||
impl MarkBaseTarget {
|
||
fn handle_read10(&self, cdb: Read10CDB, lun: u64) -> Vec<u8> {
|
||
let mapping = self.lun_map.get(&lun).unwrap();
|
||
let offset = cdb.lba * mapping.block_size;
|
||
let length = cdb.transfer_length * mapping.block_size;
|
||
|
||
// 从SQLite查询文件路径
|
||
let file_path = self.db.query_path(&mapping.node_id);
|
||
|
||
// 读取文件内容
|
||
let data = File::open(file_path)?
|
||
.read_at(offset, length)?;
|
||
|
||
data
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 性能瓶颈分析
|
||
|
||
#### 2.1 Userspace开销
|
||
|
||
|瓶颈点|开销估算|优化方案|
|
||
|--------|----------|----------|
|
||
|**TCP连接管理**|~5%|Tokio async + Zero-copy|
|
||
|**PDU解析**|~8%|SIMD CRC32C计算|
|
||
|**SCSI CDB解析**|~3%|静态解析优化|
|
||
|**SQLite查询**|~10%|缓存node_id → path映射|
|
||
|**文件读取**|~4%|Direct I/O(绕过kernel cache)|
|
||
|**总开销**|~30%|无法完全消除|
|
||
|
||
**对比Kernel Target性能**:
|
||
- LIO-Target: ~1500 MB/s(DMA直接传输)
|
||
- TGT Userspace: ~1200 MB/s(20%性能损失)
|
||
- MarkBase预估: ~800 MB/s(SQLite查询开销)
|
||
|
||
#### 2.2 macOS平台限制
|
||
|
||
|限制|影响|解决方案|
|
||
|------|------|----------|
|
||
|**无DMA支持**|无法Zero-copy|使用mmap优化|
|
||
|**IOKit复杂性**|Block设备访问受限|文件模拟Block设备|
|
||
|**TCP栈优化有限**|网络吞吐上限|启用TCP_NODELAY|
|
||
|**缺少SCSI内核模块**|性能上限固定|纯userspace实现|
|
||
|
||
### 3. 开发工作量估算
|
||
|
||
|模块|工作量|难度|依赖|
|
||
|------|----------|--------|--------|
|
||
|**PDU解析/构建**|3000行代码|★★★★☆|RFC 7143文档|
|
||
|**Login Phase**|2000行代码|★★★★★|CHAP MD5库|
|
||
|**Session管理**|1500行代码|★★★☆☆|Tokio async|
|
||
|**SCSI命令处理**|4000行代码|★★★★☆|SCSI标准文档|
|
||
|**LUN映射**|2000行代码|★★★☆☆|SQLite集成|
|
||
|**错误恢复**|1000行代码|★★★☆☆|ERL0/1/2规范|
|
||
|**测试覆盖**|3000行代码|★★★☆☆|libiscsi test-tool参考|
|
||
|**文档编写**|1000行文档|★★☆☆☆|RFC文档整理|
|
||
|**总计**|~16500行代码|★★★★☆|6-8周开发周期|
|
||
|
||
---
|
||
|
||
## 实施方案对比
|
||
|
||
### 方案A: 纯Userspace Target(推荐)
|
||
|
||
**架构设计**:
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ MarkBase iSCSI Target (Userspace) │
|
||
│ ├─ TCP Server (Tokio) │ ← 监听3260端口
|
||
│ ├─ PDU Parser │ ← RFC 7143实现
|
||
│ ├─ Session Manager │ ← ITT/TSIH/CID管理
|
||
│ ├─ SCSI Handler │ ← READ/WRITE响应
|
||
│ ├─ LUN Mapper │ ← SQLite node_id映射
|
||
│ └─ File Backend │ ← 读写实际文件
|
||
└─────────────────────────────────────┘
|
||
↓ TCP/IP
|
||
┌─────────────────────────────────────┐
|
||
│ macOS Initiator (第三方工具) │
|
||
│ ├─ XTechSAN │ ← 商业软件
|
||
│ ├─ GlobalSAN │ ← 商业软件
|
||
│ └─ libiscsi CLI │ ← 开源工具
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**优势分析**:
|
||
- ✅ 完全userspace实现,无需kernel模块
|
||
- ✅ 可移植性强(Linux/macOS/Windows)
|
||
- ✅ 调试简单(标准Rust工具)
|
||
- ✅ 与WebDAV并行运行(双协议支持)
|
||
- ✅ 可直接访问SQLite数据库
|
||
|
||
**劣势分析**:
|
||
- ⚠️ 性能损失~20%(相比kernel target)
|
||
- ⚠️ macOS需第三方Initiator工具
|
||
- ⚠️ 开发周期长(6-8周)
|
||
- ⚠️ 无现成Rust库(需从零开发)
|
||
|
||
**适用场景**: 文档协作、中等规模文件传输
|
||
|
||
### 方案B: WebDAV + NFS混合(备选)
|
||
|
||
**架构设计**:
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ macOS Finder │
|
||
│ ├─ 文件锁:WebDAV │ ← HTTP LOCK
|
||
│ ├─ 文件传输:NFS │ ← TCP NFS
|
||
│ └─ 统一锁数据库 │ ← SQLite共享
|
||
└─────────────────────────────────────┘
|
||
↓ 双协议
|
||
┌─────────────────────────────────────┐
|
||
│ MarkBase Server │
|
||
│ ├─ WebDAV Server (4919端口) │ ← 已实现
|
||
│ ├─ NFS Server (2049端口) │ ← 待实现
|
||
│ └─ SQLite锁数据库 │ ← 共享LockManager
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**优势分析**:
|
||
- ✅ NFS性能优于HTTP(~800 MB/s vs ~600 MB/s)
|
||
- ✅ Finder原生支持NFS(无需第三方工具)
|
||
- ✅ 开发周期短(2-3周)
|
||
- ✅ 有现成Rust NFS库(nfs3_client_rs)
|
||
|
||
**劣势分析**:
|
||
- ⚠️ macOS NFS客户端稳定性问题
|
||
- ⚠️ NFS需root权限配置(/etc/exports)
|
||
- ⚠️ 用户需手动挂载NFS(操作复杂度+)
|
||
- ⚠️ NFS锁机制不同(NLM vs WebDAV LOCK)
|
||
|
||
**适用场景**: 专业视频工作室、愿意手动配置的用户
|
||
|
||
### 方案C: HTTP/2优化(快速方案)
|
||
|
||
**架构设计**:
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ macOS Finder │
|
||
│ └─ WebDAV (HTTP/2) │ ← 单一协议
|
||
└─────────────────────────────────────┘
|
||
↓ HTTP/2
|
||
┌─────────────────────────────────────┐
|
||
│ MarkBase WebDAV Server │
|
||
│ ├─ HTTP/2多路复用 │ ← Axum升级
|
||
│ ├─ Zero-copy传输 │ ← sendfile优化
|
||
│ ├─ 异步锁查询 │ ← 已实现
|
||
│ └─ RAID 5存储 │ ← 已实现
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**优势分析**:
|
||
- ✅ 开发周期最短(1周)
|
||
- ✅ 用户体验最优(无需额外配置)
|
||
- ✅ 实现难度最低(仅Axum升级)
|
||
- ✅ 维护成本最低(单一协议栈)
|
||
- ✅ 性能提升显著(600 → 1000 MB/s)
|
||
|
||
**劣势分析**:
|
||
- ⚠️ 性能仍有上限(相比iSCSI Block传输)
|
||
- ⚠️ HTTP开销无法完全消除(~15%)
|
||
- ⚠️ 不支持专业视频软件(需Block-level访问)
|
||
|
||
**适用场景**: 文档协作、小规模团队
|
||
|
||
---
|
||
|
||
## 决策矩阵
|
||
|
||
|评估维度|方案A (iSCSI)|方案B (NFS混合)|方案C (HTTP/2优化)|权重|
|
||
|----------|---------------|----------------|------------------|--------|
|
||
|**性能提升**|+100% (800 MB/s)|+33% (800 MB/s)|+67% (1000 MB/s)|30%|
|
||
|**用户体验**|★★☆☆☆ (需第三方工具)|★★☆☆☆ (需手动挂载)|★★★★★ (无额外配置)|25%|
|
||
|**开发难度**|★★★★★ (6-8周)|★★★☆☆ (2-3周)|★★☆☆☆ (1周)|20%|
|
||
|**维护成本**|★★☆☆☆ (复杂协议)|★★★☆☆ (双协议)|★★★★★ (单协议)|15%|
|
||
|**扩展性**|★★★★☆ (Block-level)|★★★☆☆ (文件级)|★★☆☆☆ (HTTP限制)|10%|
|
||
|**总分**|3.5/5.0|3.2/5.0|4.5/5.0|100%|
|
||
|
||
**推荐方案**: 方案C(HTTP/2优化) → 方案B(NFS混合) → 方案A(iSCSI Target)
|
||
|
||
**理由**:
|
||
1. 方案C性价比最高(短期收益快)
|
||
2. 方案B适用于专业用户(中期扩展)
|
||
3. 方案A适合长期战略(Block-level访问)
|
||
|
||
---
|
||
|
||
## 技术路线图
|
||
|
||
### Phase 1: HTTP/2优化(Day 1-7)
|
||
- ✅ 升级Axum到HTTP/2版本
|
||
- ✅ 实现Zero-copy传输
|
||
- ✅ 性能测试验证
|
||
- ✅ 用户文档更新
|
||
|
||
### Phase 2: NFS并行服务(Day 8-21)
|
||
- ✅ 实现NFS Server原型
|
||
- ✅ SQLite锁数据库共享
|
||
- ✅ macOS Finder兼容性测试
|
||
- ✅ 部署文档编写
|
||
|
||
### Phase 3: iSCSI Target研究(Day 22-35)
|
||
- ✅ RFC 7143协议深度学习
|
||
- ✅ TGT源码分析
|
||
- ✅ 原型实现(PDU解析)
|
||
- ✅ 性能基准测试
|
||
|
||
### Phase 4: iSCSI Target开发(Day 36-60)
|
||
- ✅ Login Phase实现
|
||
- ✅ SCSI命令处理
|
||
- ✅ LUN映射集成
|
||
- ✅ 错误恢复机制
|
||
- ✅ 测试覆盖(单元/集成)
|
||
|
||
### Phase 5: 生产部署(Day 61-70)
|
||
- ✅ 第三方Initiator集成测试
|
||
- ✅ 多用户并发测试
|
||
- ✅ 性能优化调优
|
||
- ✅ 用户培训材料
|
||
|
||
---
|
||
|
||
## 风险评估
|
||
|
||
### 技术风险
|
||
|
||
|风险项|概率|影响|缓解措施|
|
||
|--------|--------|--------|----------|
|
||
|**PDU解析错误**|中|高|参考libiscsi实现,严格RFC验证|
|
||
|**Session状态混乱**|高|中|使用Tokio async lock,仔细状态管理|
|
||
|**性能不达标**|中|中|启用Zero-copy,优化SQLite查询|
|
||
|**macOS Initiator兼容性**|高|高|测试XTechSAN/GlobalSAN,准备libiscsi备选|
|
||
|**CHAP认证破解**|低|中|使用强密码,定期更新密钥|
|
||
|
||
### 业务风险
|
||
|
||
|风险项|概率|影响|缓解措施|
|
||
|--------|--------|--------|----------|
|
||
|**开发周期延期**|中|高|分阶段交付,优先HTTP/2方案|
|
||
|**用户配置复杂**|高|中|提供自动化脚本,详细文档|
|
||
|**维护成本上升**|中|中|代码模块化,自动化测试|
|
||
|**竞品对比劣势**|低|低|强调WebDAV优势,差异化定位|
|
||
|
||
---
|
||
|
||
## 开发资源需求
|
||
|
||
### 人力需求
|
||
|
||
|角色|技能要求|工作量|优先级|
|
||
|------|----------|----------|--------|
|
||
|**Rust开发工程师**|iSCSI协议熟悉|6-8周|必须|
|
||
|**测试工程师**|自动化测试|2-3周|必须|
|
||
|**文档工程师**|技术文档|1-2周|可选|
|
||
|**UI设计师**|用户界面(可选)|1周|可选|
|
||
|
||
### 技术资源
|
||
|
||
|资源|用途|获取方式|
|
||
|------|------|----------|
|
||
|**RFC 7143文档**|协议规范|https://datatracker.ietf.org/doc/html/rfc7143|
|
||
|**libiscsi源码**|协议参考|https://github.com/sahlberg/libiscsi|
|
||
|**TGT源码**|Target实现参考|https://github.com/fujita/tgt|
|
||
|**iscsi-client-rs**|Rust参考|https://github.com/Masorubka1/iscsI-client-rs|
|
||
|**SCSI标准文档**|命令规范|https://www.t10.org/|
|
||
|**XTechSAN/GlobalSAN**|macOS Initiator|商业软件(需购买)|
|
||
|
||
### 硬件资源
|
||
|
||
|设备|用途|成本|
|
||
|------|------|----------|
|
||
|**M4 Mac mini**|开发环境|已有|
|
||
|**RAID测试盘**|性能测试|已有(sparseimage)|
|
||
|**macOS Initiator软件**|测试|~$50(XTechSAN)|
|
||
|**网络测试工具**|吞吐测试|免费(AJA System Test)|
|
||
|
||
---
|
||
|
||
## 附录A: iSCSI协议关键参数
|
||
|
||
### RFC 7143核心参数表
|
||
|
||
|参数名|类型|范围|默认值|协商规则|
|
||
|--------|------|--------|--------|----------|
|
||
|MaxRecvDataSegmentLength|Number|512-16777215|65536|双方最小值|
|
||
|MaxBurstLength|Number|512-16777215|262144|双方最小值|
|
||
|FirstBurstLength|Number|512-16777215|65536|双方最小值|
|
||
|InitialR2T|Boolean|Yes/No|Yes|双方AND|
|
||
|ImmediateData|Boolean|Yes/No|No|双方AND|
|
||
|DataPDUInOrder|Boolean|Yes/No|Yes|双方AND|
|
||
|DataSequenceInOrder|Boolean|Yes/No|Yes|双方AND|
|
||
|ErrorRecoveryLevel|Number|0-2|0|双方最小值|
|
||
|HeaderDigest|Text|None/CRC32C|None|双方共同支持|
|
||
|DataDigest|Text|None/CRC32C|None|双方共同支持|
|
||
|MaxConnections|Number|1-65535|1|双方最小值|
|
||
|TargetPortalGroupTag|Number|0-65535|1|Target指定|
|
||
|
||
### 参数协商示例
|
||
|
||
**Initiator → Target**:
|
||
```
|
||
HeaderDigest=None,CRC32C
|
||
DataDigest=None
|
||
MaxRecvDataSegmentLength=131072
|
||
InitialR2T=Yes
|
||
ImmediateData=No
|
||
MaxBurstLength=262144
|
||
FirstBurstLength=65536
|
||
```
|
||
|
||
**Target → Initiator**:
|
||
```
|
||
HeaderDigest=CRC32C
|
||
DataDigest=None
|
||
MaxRecvDataSegmentLength=65536
|
||
InitialR2T=Yes
|
||
ImmediateData=No
|
||
MaxBurstLength=262144
|
||
FirstBurstLength=65536
|
||
```
|
||
|
||
**最终协商结果**:
|
||
- HeaderDigest = CRC32C(双方支持)
|
||
- DataDigest = None(Initiator不支持CRC32C)
|
||
- MaxRecvDataSegmentLength = 65536(取最小值)
|
||
|
||
---
|
||
|
||
## 附录B: SCSI命令实现示例
|
||
|
||
### READ(10)实现
|
||
|
||
```rust
|
||
use std::fs::File;
|
||
use std::io::Read;
|
||
|
||
impl MarkBaseTarget {
|
||
pub fn handle_read10(
|
||
&self,
|
||
lun: u64,
|
||
cdb: Read10CDB,
|
||
) -> Result<Vec<u8>, ScsiError> {
|
||
// 1. 检查LUN有效性
|
||
let mapping = self.lun_map.get(&lun)
|
||
.ok_or(ScsiError::InvalidLun)?
|
||
|
||
// 2. 检查LBA范围
|
||
let max_lba = mapping.total_blocks - 1;
|
||
if cdb.lba > max_lba {
|
||
return Err(ScsiError::IllegalBlockAddress);
|
||
}
|
||
|
||
// 3. 计算读取范围
|
||
let start_offset = cdb.lba * mapping.block_size;
|
||
let transfer_bytes = cdb.transfer_length * mapping.block_size;
|
||
|
||
// 4. 检查文件大小
|
||
let file_size = File::open(&mapping.file_path)?
|
||
.metadata()?
|
||
.len();
|
||
if start_offset + transfer_bytes > file_size {
|
||
return Err(ScsiError::IllegalBlockAddress);
|
||
}
|
||
|
||
// 5. 读取数据
|
||
let mut file = File::open(&mapping.file_path)?;
|
||
file.seek(SeekFrom::Start(start_offset))?;
|
||
let mut buffer = vec![0u8; transfer_bytes];
|
||
file.read_exact(&mut buffer)?;
|
||
|
||
Ok(buffer)
|
||
}
|
||
}
|
||
```
|
||
|
||
### WRITE(10)实现
|
||
|
||
```rust
|
||
use std::fs::File;
|
||
use std::io::Write;
|
||
|
||
impl MarkBaseTarget {
|
||
pub fn handle_write10(
|
||
&self,
|
||
lun: u64,
|
||
cdb: Write10CDB,
|
||
data: Vec<u8>,
|
||
) -> Result<(), ScsiError> {
|
||
// 1-4步同READ(10)
|
||
|
||
// 5. 写入数据
|
||
let mut file = File::create(&mapping.file_path)?;
|
||
file.seek(SeekFrom::Start(start_offset))?;
|
||
file.write_all(&data)?;
|
||
file.flush()?;
|
||
|
||
// 6. 更新SQLite(可选)
|
||
self.db.update_file_size(&mapping.node_id, file_size);
|
||
|
||
Ok(())
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 附录C: macOS Initiator工具对比
|
||
|
||
|工具|类型|价格|优势|劣势|推荐指数|
|
||
|------|------|--------|--------|--------|----------|
|
||
|**XTechSAN**|商业软件|$49.95|稳定、官方支持|昂贵|★★★☆☆|
|
||
|**GlobalSAN**|商业软件|$24.95|便宜、稳定|功能有限|★★★★☆|
|
||
|**libiscsi CLI**|开源库|免费|灵活、可编程|需手动编译|★★☆☆☆|
|
||
|**自制Initiator**|自行开发|免费|完全控制|开发成本高|★☆☆☆☆|
|
||
|
||
**推荐选择**: GlobalSAN(性价比最佳)或 libiscsi CLI(开发测试)
|
||
|
||
---
|
||
|
||
## 总结建议
|
||
|
||
### 短期策略(1-2周)
|
||
1. ✅ 优先实施HTTP/2优化(方案C)
|
||
2. ✅ 性能基准测试(目标:1000 MB/s)
|
||
3. ✅ 用户文档更新(强调WebDAV优势)
|
||
|
||
### 中期策略(1个月)
|
||
1. ✅ NFS并行服务原型(方案B)
|
||
2. ✅ 多用户并发测试(10 users)
|
||
3. ✅ macOS兼容性验证
|
||
|
||
### 长期策略(2-3个月)
|
||
1. ⚠️ iSCSI Target原型开发(方案A)
|
||
2. ⚠️ SCSI命令完整实现
|
||
3. ⚠️ 第三方Initiator集成测试
|
||
|
||
### 最终建议
|
||
|
||
**不推荐立即开发iSCSI Target**,原因:
|
||
1. 性能收益有限(800 vs 1000 MB/s,HTTP/2已接近)
|
||
2. 开发成本高昂(6-8周,16500行代码)
|
||
3. macOS用户体验差(需第三方工具)
|
||
4. 维护复杂度高(双协议栈)
|
||
|
||
**推荐路径**:
|
||
- **第一步**: HTTP/2优化(立即可行,1周完成)
|
||
- **第二步**: NFS混合方案(中期扩展,2-3周)
|
||
- **第三步**: 根据用户反馈决定是否开发iSCSI Target
|
||
|
||
**如果必须实现iSCSI**:
|
||
- 优先参考TGT源码(userspace实现)
|
||
- 使用libiscsi作为协议测试工具
|
||
- 预留6-8周开发周期
|
||
- 准备GlobalSAN作为macOS Initiator备选
|
||
|
||
---
|
||
|
||
**文档状态**: 已完成
|
||
**下一步**: 执行HTTP/2优化方案(Phase 1)
|
||
**负责人**: MarkBase开发团队
|
||
**更新日志**: 2026-05-17 初版创建 |