# Go ROFS Error Watcher

A Go client for monitoring EROFS (Read Only Filesystem Error) notifications via netlink.

## 项目结构

```
go-rofs-err-watcher/
├── cmd/go-rofs-err-watcher/          # 主应用程序
│   └── main.go               # 命令行入口
├── pkg/client/               # 客户端库
│   ├── client.go            # 核心客户端实现
│   └── client_test.go       # 客户端测试
├── go.mod                   # Go 模块定义
├── go.sum                   # 依赖校验和
├── Makefile                 # 构建脚本
└── README.md               # 项目说明
```

## 功能特性

- **模块化设计**: 将 netlink 连接、消息解析等功能分离到独立模块
- **异步消息处理**: 使用 Go channels 进行异步消息接收和处理
- **完整的系统调用测试**: 支持测试多种系统调用触发的 netlink 消息
- **错误处理**: 完善的错误处理和日志记录

## 支持的系统调用

测试覆盖以下系统调用：
- `open` - 打开文件
- `unlink` - 删除文件
- `rmdir` - 删除目录
- `mkdir` - 创建目录
- `mknod` - 创建特殊文件节点
- `link` - 创建硬链接
- `symlink` - 创建符号链接
- `rename` - 重命名文件
- `truncate` - 截断文件
- `chmod` - 修改文件权限
- `chown` - 修改文件所有者
- `utime` - 修改文件时间
- `setxattr` - 设置扩展属性
- `removexattr` - 删除扩展属性
- `ioctl` - 设备控制操作

## 构建和安装

### 依赖要求

- Go 1.22.3 或更高版本
- Linux 系统（需要 netlink 支持）
- Root 权限（用于修改 /usr 目录下文件）

### 构建

```bash
# 下载依赖
make deps

# 构建应用程序
make build

# 安装到系统
make install
```

### 使用方法

```bash
# 启动监听
sudo ./erofs-client monitor

# 或者使用 make 命令
make monitor
```

## 测试

### 运行测试

```bash
# 运行所有测试（需要 root 权限）
make test-root

# 或者分别运行
sudo go test -v ./pkg/client
```

### 构建测试程序再运行

```bash
make build-test
```

运行测试程序
```bash
sudo ./test-client -test.v
```

### 测试说明

测试分为两个部分：

1. **客户端测试** (`pkg/client/client_test.go`):
   - 测试客户端创建和连接
   - 测试基本的消息接收功能
   - 测试基础系统调用（open, chmod, truncate 等）

### 测试流程

每个测试遵循以下流程：
1. 启动 netlink 监听
2. 执行目标系统调用
3. 接收并解析 netlink 消息
4. 验证消息字段匹配
5. 超时时间为 3 秒

## API 文档

### Client 结构体

```go
type Client struct {
    // 内部字段...
}

// 创建新的客户端
func NewClient() (*Client, error)

// 关闭客户端连接
func (c *Client) Close() error

// 接收消息（异步）
func (c *Client) ReceiveMessages(ctx context.Context) (<-chan NotificationMessage, <-chan error)

// 获取连接信息
func (c *Client) GetFamilyInfo() (string, uint16, uint32)
```

### NotificationMessage 结构体

```go
type NotificationMessage struct {
    Timestamp time.Time // 消息时间戳
    Command   uint8     // 命令类型
    Filename  string    // 文件名
    PID       uint32    // 进程 ID
    Comm      string    // 进程命令名
    FuncName  string    // 函数名
}
```

## 开发说明

### 添加新的系统调用测试

1. 在 `pkg/client/client_test.go` 中的 `testCases` 数组添加新的测试用例
2. 实现相应的系统调用函数
3. 运行测试验证功能

### 扩展客户端功能

1. 在 `pkg/client/client.go` 中添加新的方法
2. 在 `pkg/client/client_test.go` 中添加相应的测试
3. 更新文档

## 注意事项

- 需要 root 权限才能进行 netlink 监听
- 某些系统调用可能不会触发 netlink 消息，这取决于内核配置和文件系统类型
- 测试使用的目标文件路径为 `/usr/share/man/man1/dash.1.gz`
- 超时时间设置为 3 秒，可以根据需要调整

## 许可证

本项目采用开源许可证，具体许可证信息请查看 LICENSE 文件。
