Open utterances-bot opened 1 year ago
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:1234")?;
// Wait for a connection
let (mut socket, _) = listener.accept()?;
loop {
// Read the NVMe-oF command header
let mut buf = [0u8; 128];
let len = socket.read(&mut buf)?;
// If we've reached the end of the stream, break out of the loop
if len == 0 {
break;
}
// Pattern match on the command code in the NVMe-oF header
match buf[0] {
// NVMe-oF Connect command
0x00 => {
// Send a simple response
let response = b"Hello from the NVMe-oF target!";
socket.write_all(response)?;
},
// NVMe-oF Command Capsule command
0x01 => {
// TODO: Implement command capsule handling
},
// NVMe-oF Fabrics Discovery command
0x02 => {
// TODO: Implement fabrics discovery handling
},
// NVMe-oF Fabrics Get Log Page command
0x03 => {
// TODO: Implement fabrics get log page handling
},
// NVMe-oF Fabrics Set Features command
0x04 => {
// TODO: Implement fabrics set features handling
},
// NVMe-oF Fabrics Get Features command
0x05 => {
// TODO: Implement fabrics get features handling
},
// NVMe-oF Fabrics Asynchronous Event Request command
0x06 => {
// TODO: Implement fabrics asynchronous event request handling
},
// NVMe-oF Fabrics Asynchronous Event Completion command
0x07 => {
// TODO: Implement fabrics asynchronous event completion handling
},
// NVMe-oF Fabrics Firmware Activate command
0x08 => {
// TODO: Implement fabrics firmware activate handling
},
// NVMe-oF Fabrics Firmware Image Download command
0x09 => {
// TODO: Implement fabrics firmware image download handling
},
// Other NVMe-oF commands...
_ => {
// TODO: Handle unknown commands
}
}
}
Ok(())
}
이런식으로 스펙을 줄줄 외워서 skeleton 을 만들어 주기도 함
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
fn main() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:1234")?;
// Wait for a connection
let (mut socket, _) = listener.accept()?;
loop {
// Read the NVMe-oF command header
let mut buf = [0u8; 128];
let len = socket.read(&mut buf)?;
// If we've reached the end of the stream, break out of the loop
if len == 0 {
break;
}
// Pattern match on the command code in the NVMe-oF header
match buf[0] {
// NVMe-oF Connect command
0x00 => {
// Send a simple response
let response = b"Hello from the NVMe-oF target!";
socket.write_all(response)?;
},
// NVMe-oF Command Capsule command
0x01 => {
// Get the buffer offset and length from the NVMe-oF header
let data_offset = ((buf[16] as u32) << 24) | ((buf[17] as u32) << 16) | ((buf[18] as u32) << 8) | buf[19] as u32;
let data_len = ((buf[20] as u32) << 24) | ((buf[21] as u32) << 16) | ((buf[22] as u32) << 8) | buf[23] as u32;
// Read the command capsule from the stream
let mut cmd_buf = vec![0u8; data_len as usize];
socket.read_exact(&mut cmd_buf)?;
// Parse the command capsule
let opcode = ((cmd_buf[0] as u32) << 24) | ((cmd_buf[1] as u32) << 16) | ((cmd_buf[2] as u32) << 8) | cmd_buf[3] as u32;
let nsid = ((cmd_buf[4] as u32) << 24) | ((cmd_buf[5] as u32) << 16) | ((cmd_buf[6] as u32) << 8) | cmd_buf[7] as u32;
let data = &cmd_buf[8..];
// Parse the opcode into a string term
let opcode_str = match opcode {
0x00 => "Delete I/O Submission Queue",
0x01 => "Create I/O Submission Queue",
0x02 => "Get Log Page",
0x04 => "Delete I/O Completion Queue",
0x05 => "Create I/O Completion Queue",
0x06 => "Identify Controller",
0x07 => "Abort Command",
0x09 => "Get Features",
0x0a => "Set Features",
0x0b => "Asynchronous Event Request",
0x0c => "Namespace Management",
0x0d => "Firmware Commit",
0x0e => "Firmware Image Download",
_ => "Unknown Opcode"
};
println!("Received command capsule with opcode '{}'", opcode_str);
// TODO: Implement command handling based on the opcode and data
},
이런식으로 opcode 별 주석이나 human readable string map을 주기도 함.
nvmf <1> - introduction (feat. ChatGPT) | Production-ready Rust Libraries (PRL)
ChatGPT를 사용하면 블로그를 편하게 찍어낼 수 있다는 이야기를 들어, 아침에 일어나 “폰”으로 ChatGPT 에게 물어보았다, 아니 여쭤보았다:
https://yyu-nim.github.io/rust/nvmf/chatgpt/2023/03/18/nvmf-1-intro.html