Skip to content

Commit bd4f1aa

Browse files
Add CLAUDE.md and README.md updates
1 parent 7d71916 commit bd4f1aa

File tree

3 files changed

+420
-35
lines changed

3 files changed

+420
-35
lines changed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CLAUDE.md

CLAUDE.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
**dperf** is a MinIO drive performance measurement tool that identifies slow drives by performing parallel I/O operations on multiple file paths. It measures read/write throughput and displays results sorted by performance (fastest drives first).
8+
9+
## Build & Test Commands
10+
11+
### Build
12+
```bash
13+
make build # Builds dperf binary with CGO_ENABLED=0
14+
```
15+
16+
### Install
17+
```bash
18+
make install # Builds and installs to $GOPATH/bin/dperf
19+
go install github.com/minio/dperf@latest # Install from source
20+
```
21+
22+
### Run
23+
```bash
24+
./dperf /mnt/drive1 # Single drive
25+
./dperf /mnt/drive{1..6} # Multiple drives (parallel)
26+
./dperf --serial /mnt/drive{1..6} # Multiple drives (sequential)
27+
./dperf --write-only /mnt/drive1 # Write-only benchmark
28+
./dperf -v /mnt/drive{1..6} # Verbose output (per-drive stats)
29+
```
30+
31+
### Key Flags
32+
- `-b, --blocksize`: Read/write block size (default: "4MiB")
33+
- `-f, --filesize`: Amount of data per drive (default: "1GiB")
34+
- `-i, --ioperdrive`: Concurrent I/O per drive (default: 4)
35+
- `--serial`: Run tests sequentially instead of parallel
36+
- `--write-only`: Run write-only tests
37+
- `-v, --verbose`: Show individual path stats (default shows only aggregate)
38+
39+
### Profiling (Hidden Flags)
40+
```bash
41+
./dperf --prof.cpu --prof.dir=./profiles /mnt/drive1 # CPU profiling
42+
./dperf --prof.mem --prof.dir=./profiles /mnt/drive1 # Memory profiling
43+
./dperf --prof.cpuio --prof.dir=./profiles /mnt/drive1 # CPU/IO profiling
44+
```
45+
46+
Other profile types: `--prof.block`, `--prof.mutex`, `--prof.trace`, `--prof.thread`
47+
48+
### Clean
49+
```bash
50+
make clean # Remove *.test and temporary files
51+
```
52+
53+
## Architecture
54+
55+
### Package Structure
56+
57+
#### `main.go`
58+
Entry point that sets up signal handling (SIGINT, SIGTERM, SIGSEGV) and calls into the `cmd` package.
59+
60+
#### `cmd/cmd.go`
61+
- Defines the Cobra command structure and all CLI flags
62+
- Validates input parameters (blocksize/filesize must be ≥4K and multiples of 4K)
63+
- Validates paths (must be directories, not root, must exist)
64+
- Orchestrates profiling setup via `startTraces()`
65+
- Creates `DrivePerf` struct and calls `RunAndRender()`
66+
67+
#### `pkg/dperf/perf.go`
68+
Core performance testing logic:
69+
- `DrivePerf`: Main configuration struct with Serial, BlockSize, FileSize, IOPerDrive, WriteOnly, Verbose options
70+
- `Run()`: Executes tests either serially or in parallel (goroutines per path)
71+
- `runTests()`: Per-path orchestration - launches IOPerDrive goroutines for write, then read
72+
- `RunAndRender()`: Runs tests and displays sorted results
73+
74+
#### `pkg/dperf/run_linux.go` (Linux only)
75+
Platform-specific I/O implementation using direct I/O (O_DIRECT):
76+
- `runWriteTest()`: Opens file with O_DIRECT|O_RDWR|O_CREATE, writes FileSize bytes using random data, measures throughput
77+
- `runReadTest()`: Opens file with O_DIRECT|O_RDONLY, reads FileSize bytes, measures throughput
78+
- `copyAligned()`: Core I/O function handling aligned/unaligned buffers for direct I/O
79+
- Uses `syscall.Fdatasync()` for write durability
80+
- Uses `unix.Fadvise(FADV_SEQUENTIAL)` for read optimization
81+
- Random data generation via `github.com/minio/pkg/v3/rng`
82+
83+
#### `pkg/dperf/run_other.go` (Non-Linux)
84+
Stub implementation returning `ErrNotImplemented` - dperf only works on Linux.
85+
86+
#### `pkg/dperf/result.go`
87+
Output formatting:
88+
- `DrivePerfResult`: Contains Path, WriteThroughput, ReadThroughput, Error
89+
- `render()`: Displays results in colored tables using `github.com/minio/pkg/v3/console`
90+
- Shows per-drive stats in verbose mode, always shows aggregate TotalWRITE/TotalREAD
91+
92+
### Key Technical Details
93+
94+
**Direct I/O Requirements:**
95+
- Block size must be ≥4096 bytes and a multiple of 4096 (O_DIRECT alignment requirement)
96+
- File size must be ≥4096 bytes and a multiple of 4096
97+
- Buffers allocated via `directio.AlignedBlock()` for page alignment
98+
- When unaligned writes occur, O_DIRECT is disabled and fdatasync is used
99+
100+
**Concurrency Model:**
101+
- By default, runs all paths in parallel (goroutine per path)
102+
- Each path spawns IOPerDrive goroutines (default: 4) for concurrent I/O
103+
- `--serial` flag forces sequential path execution
104+
- Write tests complete before read tests begin (per path)
105+
106+
**Test Files:**
107+
- Created at `{path}/{uuid}/.writable-check.tmp-{0..IOPerDrive-1}`
108+
- Automatically cleaned up after test via `defer os.RemoveAll()`
109+
110+
**Result Sorting:**
111+
- Results sorted by ReadThroughput descending (fastest first)
112+
- Helps identify slowest drives quickly
113+
114+
## Kubernetes Deployment
115+
116+
See `dperf.yaml` for example Job that benchmarks PersistentVolumeClaims (useful for DirectPV testing).
117+
118+
## Requirements
119+
120+
- Linux OS (uses O_DIRECT, unix.Fadvise, syscall.Fdatasync)
121+
- Go 1.17+ for building
122+
- Write permissions on target paths
123+
- Block devices supporting direct I/O

0 commit comments

Comments
 (0)