github编辑

如何实现一个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添加进去

最后更新于