Add GS Rust refactoring feasibility analysis
This commit is contained in:
@@ -0,0 +1,361 @@
|
|||||||
|
# GS (DtrGuiSrv) Rust 重構分析
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
分析是否可將 GS (DtrGuiSrv) C 語言程式完整用 Rust 重構為 `raidguard_x_gui_server`。
|
||||||
|
|
||||||
|
## 現有 GS 元件分析
|
||||||
|
|
||||||
|
### GS (C) 元件清單
|
||||||
|
|
||||||
|
| 檔案 | 功能 | 複雜度 | 依賴 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| cMain.c | 主程式入口、初始化 | 中 | 所有模組 |
|
||||||
|
| cNetWork.c | TCP 網路通訊 (Port 8922) | 高 | socket API |
|
||||||
|
| cInBand.c | In-Band API 處理 | 高 | RAID Driver |
|
||||||
|
| cPollingEvent.c | 事件輪詢執行緒 | 中 | 佇列、檔案 |
|
||||||
|
| cMail.c | Email 發送 (SMTP) | 中 | SMTP library |
|
||||||
|
| cShareMem.c | 共享記憶體 | 中 | POSIX SHM |
|
||||||
|
| cSrvConfig.c | 伺服器設定 | 低 | 檔案 I/O |
|
||||||
|
| cDTRIoCtl.c | RAID I/O Control | 高 | Driver API |
|
||||||
|
|
||||||
|
### 每個元件的關鍵功能
|
||||||
|
|
||||||
|
```
|
||||||
|
cMain.c
|
||||||
|
├── InitGUIServer() - 初始化
|
||||||
|
├── InitSMTP() - SMTP 初始化
|
||||||
|
├── InitRAIDCard() - RAID 卡初始化
|
||||||
|
└── Main Loop - 網路監聽
|
||||||
|
|
||||||
|
cNetWork.c
|
||||||
|
├── InitialSrvSocket() - 建立 TCP Server (Port 8922)
|
||||||
|
├── InitialClientSocket() - accept()
|
||||||
|
├── GUITrans() - TCP 傳輸 (Phase1 + Phase2)
|
||||||
|
└── ServerGUITrans() - 伺服器端傳輸
|
||||||
|
|
||||||
|
cInBand.c
|
||||||
|
├── HandleInBandReq() - 處理 In-Band 請求
|
||||||
|
├── HandleSrvConfigReq() - 處理伺服器設定
|
||||||
|
└── [RAID Driver I/O] - 與硬體通訊
|
||||||
|
|
||||||
|
cPollingEvent.c
|
||||||
|
├── PollingCtlrEvent() - 執行緒:輪詢事件
|
||||||
|
├── SaveInBandEvent() - 儲存到記憶體佇列
|
||||||
|
├── RecEventToFile() - 寫入事件檔案
|
||||||
|
└── HandleInBandEventReq() - 處理 GC 請求
|
||||||
|
|
||||||
|
cMail.c
|
||||||
|
├── InitMailEntryFreeQ() - 初始化郵件佇列
|
||||||
|
├── IssueMailOut() - 發送郵件
|
||||||
|
└── LoadMailAddrFromFile() - 載入郵件地址
|
||||||
|
|
||||||
|
cShareMem.c
|
||||||
|
├── InitialSHMForAllCtlr() - 初始化共享記憶體
|
||||||
|
└── 與 RAID Driver 共享資料
|
||||||
|
|
||||||
|
cDTRIoCtl.c
|
||||||
|
├── QuaryDTR() - 查詢 RAID 資訊
|
||||||
|
├── DevIoControl() - I/O Control
|
||||||
|
└── 硬體驅動程式介面
|
||||||
|
```
|
||||||
|
|
||||||
|
## 重構可行性分析
|
||||||
|
|
||||||
|
### 可以重構的部分 (✅)
|
||||||
|
|
||||||
|
| 元件 | Rust 方案 | 難度 |
|
||||||
|
|------|-----------|------|
|
||||||
|
| TCP 網路 | tokio, async-std | 中 |
|
||||||
|
| 協議解析 | nom, manual parsing | 低 |
|
||||||
|
| 事件輪詢 | tokio::spawn, interval | 低 |
|
||||||
|
| 設定管理 | serde_json, toml | 低 |
|
||||||
|
| 日誌系統 | tracing, log | 低 |
|
||||||
|
| Email 發送 | lettre | 中 |
|
||||||
|
| 錯誤處理 | thiserror, anyhow | 低 |
|
||||||
|
|
||||||
|
### 難以重構的部分 (⚠️)
|
||||||
|
|
||||||
|
| 元件 | 問題 | 建議 |
|
||||||
|
|------|------|------|
|
||||||
|
| cShareMem.c | POSIX 共享記憶體依賴 | 使用 rust-posix-shmem 或 FFI |
|
||||||
|
| cDTRIoCtl.c | RAID Driver I/O | 需要 FFI 綁定或重寫 Driver |
|
||||||
|
| 硬體驅動 | 低層級硬體存取 | 保持 C 或用 FFI |
|
||||||
|
|
||||||
|
### 需要 FFI 的部分
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// 使用 FFI 呼叫現有 C 函數
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct CtlrInfo {
|
||||||
|
pub bStatus: u8,
|
||||||
|
pub bCtlrSN: [c_char; 16],
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
fn QuaryDTR(bDevNo: u8, bPageBuf: *mut u8, pbHeatsink: *mut u8) -> c_short;
|
||||||
|
fn DevIoControl(...) -> c_uchar;
|
||||||
|
fn GetCtlSemP(DeviceNum: c_short) -> c_short;
|
||||||
|
fn GetCtlSemV(DeviceNum: c_short) -> c_short;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 現有 Rust 專案結構
|
||||||
|
|
||||||
|
```
|
||||||
|
raidguard_x_gui_server/
|
||||||
|
├── Cargo.toml # tokio, serde, tracing, lettre
|
||||||
|
├── src/
|
||||||
|
│ ├── main.rs # 入口
|
||||||
|
│ ├── lib.rs # library
|
||||||
|
│ ├── server.rs # TCP Server
|
||||||
|
│ ├── protocol/ # 協議解析
|
||||||
|
│ ├── handlers/ # 請求處理
|
||||||
|
│ ├── mock/ # 模擬數據
|
||||||
|
│ └── backend/ # 後端
|
||||||
|
```
|
||||||
|
|
||||||
|
## 重構架構建議
|
||||||
|
|
||||||
|
### 模組化設計
|
||||||
|
|
||||||
|
```
|
||||||
|
raidguard_x_gui_server/
|
||||||
|
├── src/
|
||||||
|
│ ├── main.rs
|
||||||
|
│ ├── lib.rs
|
||||||
|
│ │
|
||||||
|
│ ├── network/ # 網路通訊
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── server.rs # TCP Server (Port 8922)
|
||||||
|
│ │ ├── transport.rs # Phase1/Phase2 傳輸
|
||||||
|
│ │ └── client.rs # Client 連線管理
|
||||||
|
│ │
|
||||||
|
│ ├── protocol/ # 協議
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── request.rs # 請求解析
|
||||||
|
│ │ ├── response.rs # 回應封裝
|
||||||
|
│ │ └── error.rs # 協議錯誤
|
||||||
|
│ │
|
||||||
|
│ ├── inband/ # In-Band API
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── handler.rs # 請求處理
|
||||||
|
│ │ ├── page.rs # Page 資料
|
||||||
|
│ │ └── password.rs # 密碼處理
|
||||||
|
│ │
|
||||||
|
│ ├── event/ # 事件處理
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── queue.rs # 事件佇列
|
||||||
|
│ │ ├── polling.rs # 輪詢執行緒
|
||||||
|
│ │ └── storage.rs # 事件儲存
|
||||||
|
│ │
|
||||||
|
│ ├── email/ # Email 通知
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── smtp.rs # SMTP 發送
|
||||||
|
│ │ └── template.rs # 郵件範本
|
||||||
|
│ │
|
||||||
|
│ ├── config/ # 設定管理
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── server.rs # 伺服器設定
|
||||||
|
│ │ └── storage.rs # 設定儲存
|
||||||
|
│ │
|
||||||
|
│ ├── driver/ # RAID Driver (FFI)
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ ├── ffi.rs # FFI 綁定
|
||||||
|
│ │ └── types.rs # C 類型包裝
|
||||||
|
│ │
|
||||||
|
│ └── logging/ # 日誌
|
||||||
|
│ └── mod.rs
|
||||||
|
```
|
||||||
|
|
||||||
|
### 技術選型
|
||||||
|
|
||||||
|
| 功能 | Rust 選擇 | 說明 |
|
||||||
|
|------|----------|------|
|
||||||
|
| 非同步 runtime | tokio | 完整 async/await 支援 |
|
||||||
|
| TCP 網路 | tokio::net | 內建 TCP 支援 |
|
||||||
|
| 協議解析 | nom / 手動 | 簡單協議,手動即可 |
|
||||||
|
| 序列化 | serde | JSON 支援 |
|
||||||
|
| Email | lettre | SMTP client |
|
||||||
|
| 日誌 | tracing | 結構化日誌 |
|
||||||
|
| 錯誤處理 | thiserror | 錯誤鏈 |
|
||||||
|
| 共享記憶體 | libc::sys::shm | FFI |
|
||||||
|
| 執行緒安全 | Arc<Mutex<>> | 內建 |
|
||||||
|
|
||||||
|
## 重構階段規劃
|
||||||
|
|
||||||
|
### Phase 1: 基礎設施 (1-2 週)
|
||||||
|
|
||||||
|
- [ ] 專案初始化 (現有)
|
||||||
|
- [ ] TCP Server (Port 8922)
|
||||||
|
- [ ] 協議解析 (Phase1/Phase2)
|
||||||
|
- [ ] 基本請求/回應處理
|
||||||
|
- [ ] 日誌系統
|
||||||
|
|
||||||
|
### Phase 2: In-Band API (2-3 週)
|
||||||
|
|
||||||
|
- [ ] GET_PAGE 處理 (0x01)
|
||||||
|
- [ ] SEND_PASSWORD 處理 (0x1D)
|
||||||
|
- [ ] 其他 OpCode 處理
|
||||||
|
- [ ] 與 RAID Driver FFI
|
||||||
|
|
||||||
|
### Phase 3: 事件系統 (1-2 週)
|
||||||
|
|
||||||
|
- [ ] 事件輪詢執行緒
|
||||||
|
- [ ] 事件佇列
|
||||||
|
- [ ] 事件儲存 (檔案)
|
||||||
|
- [ ] GC 事件查詢
|
||||||
|
|
||||||
|
### Phase 4: 通知系統 (1 週)
|
||||||
|
|
||||||
|
- [ ] Email 發送 (SMTP)
|
||||||
|
- [ ] SNMP Trap (可選)
|
||||||
|
- [ ] 設定管理
|
||||||
|
|
||||||
|
### Phase 5: 整合測試 (1-2 週)
|
||||||
|
|
||||||
|
- [ ] 單元測試
|
||||||
|
- [ ] 整合測試
|
||||||
|
- [ ] 效能優化
|
||||||
|
- [ ] 文檔
|
||||||
|
|
||||||
|
## 挑戰與解決方案
|
||||||
|
|
||||||
|
### 挑戰 1: RAID Driver I/O
|
||||||
|
|
||||||
|
**問題**: cDTRIoctl.c 需要與硬體驅動程式直接通訊
|
||||||
|
|
||||||
|
**解決方案**:
|
||||||
|
```rust
|
||||||
|
// 方案 A: FFI 呼叫現有 C 函數
|
||||||
|
#[link(name = "DtrIoCtl")]
|
||||||
|
extern "C" {
|
||||||
|
fn DevIoControl(...) -> c_uchar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方案 B: 將 Driver 程式碼移植到 Rust
|
||||||
|
// (需要大量時間)
|
||||||
|
|
||||||
|
// 方案 C: 保持 GS 為 C,只重構 GUI 部分
|
||||||
|
// (推薦: 混合架構)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 挑戰 2: 共享記憶體
|
||||||
|
|
||||||
|
**問題**: cShareMem.c 使用 POSIX 共享記憶體
|
||||||
|
|
||||||
|
**解決方案**:
|
||||||
|
```rust
|
||||||
|
// 使用 nix crate
|
||||||
|
use nix::sys::shm::{shmat, shmget, ShmFlags};
|
||||||
|
|
||||||
|
// 或使用 libc
|
||||||
|
use libc::{shmget, shmat, shmctl, IPC_RMID};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 挑戰 3: 執行緒同步
|
||||||
|
|
||||||
|
**問題**: C 的 Semaphore 需要轉換
|
||||||
|
|
||||||
|
**解決方案**:
|
||||||
|
```rust
|
||||||
|
// Rust 建議使用
|
||||||
|
use std::sync::{Mutex, Semaphore, Arc};
|
||||||
|
|
||||||
|
// 或使用 tokio::sync
|
||||||
|
use tokio::sync::{Mutex, Semaphore};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 挑戰 4: 相容性
|
||||||
|
|
||||||
|
**問題**: 需要完全相容現有 GC (Java) 協議
|
||||||
|
|
||||||
|
**解決方案**:
|
||||||
|
```rust
|
||||||
|
// 確保位元組級別完全相同
|
||||||
|
#[repr(C)]
|
||||||
|
struct RequestHeader {
|
||||||
|
pub req_type: u8,
|
||||||
|
pub phase_code: u8,
|
||||||
|
pub length: u16, // Little-endian
|
||||||
|
}
|
||||||
|
|
||||||
|
// 測試覆蓋所有現有功能
|
||||||
|
```
|
||||||
|
|
||||||
|
## 推薦策略
|
||||||
|
|
||||||
|
### 策略 A: 完全重構 (全部 Rust)
|
||||||
|
|
||||||
|
**優點**:
|
||||||
|
- 單一語言,維護簡單
|
||||||
|
- 記憶體安全
|
||||||
|
- 現代化生態
|
||||||
|
|
||||||
|
**缺點**:
|
||||||
|
- 需要 FFI 或重寫 Driver
|
||||||
|
- 開發時間長
|
||||||
|
|
||||||
|
**時間預估**: 3-4 個月
|
||||||
|
|
||||||
|
### 策略 B: 混合架構 (推薦)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────┐
|
||||||
|
│ 混合架構 │
|
||||||
|
├─────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||||
|
│ │ GC (Java) │ │ Rust Server │ │ C Driver │ │
|
||||||
|
│ │ Port 8922 │◄──►│ │◄──►│ (現有) │ │
|
||||||
|
│ │ │ │ │ │ │ │
|
||||||
|
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ 共享記憶體/FDI │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**優點**:
|
||||||
|
- 保留穩定的 C Driver
|
||||||
|
- Rust 處理網路/業務邏輯
|
||||||
|
- 逐步遷移
|
||||||
|
|
||||||
|
**缺點**:
|
||||||
|
- FFI 複雜度
|
||||||
|
|
||||||
|
**時間預估**: 2-3 個月
|
||||||
|
|
||||||
|
### 策略 C: 只重構 GUI Client
|
||||||
|
|
||||||
|
維持 GS 為 C 程式,只重構 GC (Java) 為 Rust GUI Client。
|
||||||
|
|
||||||
|
## 結論
|
||||||
|
|
||||||
|
**可以完整重構,但建議採用混合策略:**
|
||||||
|
|
||||||
|
1. **網路/協議/事件/Email** → Rust (可完全重構)
|
||||||
|
2. **RAID Driver/共享記憶體** → 保持 C 或 FFI
|
||||||
|
3. **優先順序**: 先重構 GC (Java→Rust) → 再考慮 GS
|
||||||
|
|
||||||
|
**主要原因**:
|
||||||
|
- Driver 層變動風險高
|
||||||
|
- GS 相對穩定,需求變化少
|
||||||
|
- GC (GUI) 更有現代化價值
|
||||||
|
|
||||||
|
## 現有程式碼利用率
|
||||||
|
|
||||||
|
```
|
||||||
|
raidguard_x_gui_server (現有)
|
||||||
|
├── ✅ network/server.rs → 可基於 cNetWork.c
|
||||||
|
├── ✅ protocol/ → 可基於 GS 協議
|
||||||
|
├── ⚠️ handlers/ → 需要實作 In-Band API
|
||||||
|
└── ❌ backend/ → 需要連接 RAID Driver
|
||||||
|
```
|
||||||
|
|
||||||
|
## 下一步建議
|
||||||
|
|
||||||
|
1. **短期**: 完成現有 Rust Server 與 GS 的替換
|
||||||
|
2. **中期**: FFI 整合現有 C Driver
|
||||||
|
3. **長期**: 逐步將 Driver 移植到 Rust (如有需要)
|
||||||
Reference in New Issue
Block a user