如何实现一个FIO插件
FIO是一个开源的压力测试工具,主要用来测试磁盘的io性能。它支持13种不同类型的io引擎(libaio sync mmap libiscsi nbd nfs等等),它支持用户自定义各种不同的io pattern。
当我们测试自己开发的IO路径时,也可以添加一个自定义的ioengine。
ioengine接口
fio ioengine的接口在ioengines.h,要实现一个自定义的async engine,就需要实现这一套接口,然后fio的框架会调用engine的queue接口把io放进来,ioengine负责执行IO,然后ioengine会通过getevents接口来获取events,得到io执行结果。
struct ioengine_ops {
struct flist_head list;
const char *name;
int version;
int flags;
void *dlhandle;
int (*setup)(struct thread_data *);
int (*init)(struct thread_data *);
int (*post_init)(struct thread_data *);
int (*prep)(struct thread_data *, struct io_u *);
enum fio_q_status (*queue)(struct thread_data *, struct io_u *);
int (*commit)(struct thread_data *);
int (*getevents)(struct thread_data *, unsigned int, unsigned int, const struct timespec *);
struct io_u *(*event)(struct thread_data *, int);
char *(*errdetails)(struct io_u *);
int (*cancel)(struct thread_data *, struct io_u *);
void (*cleanup)(struct thread_data *);
int (*open_file)(struct thread_data *, struct fio_file *);
int (*close_file)(struct thread_data *, struct fio_file *);
int (*invalidate)(struct thread_data *, struct fio_file *);
int (*unlink_file)(struct thread_data *, struct fio_file *);
int (*get_file_size)(struct thread_data *, struct fio_file *);
int (*prepopulate_file)(struct thread_data *, struct fio_file *);
void (*terminate)(struct thread_data *);
int (*iomem_alloc)(struct thread_data *, size_t);
void (*iomem_free)(struct thread_data *);
int (*io_u_init)(struct thread_data *, struct io_u *);
void (*io_u_free)(struct thread_data *, struct io_u *);
int (*get_zoned_model)(struct thread_data *td,
struct fio_file *f, enum zbd_zoned_model *);
int (*report_zones)(struct thread_data *, struct fio_file *,
uint64_t, struct zbd_zone *, unsigned int);
int (*reset_wp)(struct thread_data *, struct fio_file *,
uint64_t, uint64_t);
int (*get_max_open_zones)(struct thread_data *, struct fio_file *,
unsigned int *);
int (*get_max_active_zones)(struct thread_data *, struct fio_file *,
unsigned int *);
int (*finish_zone)(struct thread_data *, struct fio_file *,
uint64_t, uint64_t);
int (*fdp_fetch_ruhs)(struct thread_data *, struct fio_file *,
struct fio_ruhs_info *);
int option_struct_size;
struct fio_option *options;
};实现ioengine接口
1 每个线程都有一个thread data
2 定义一组ioengine_ops
3 IO入队列函数
4 提交队列中的请求
5 POLL获取事件
6 解析每一个事件,释放IO_U
7 最后修改Makefile,把自定义engine添加进去
最后更新于