1+ #include <stddef.h>
2+ #include <math.h>
3+
4+ #include "../fio.h"
5+ #include "../optgroup.h"
6+
7+ /* zonda_fs client headers */
8+ #include "zonda_fs_c.h"
9+
10+ struct zondafsio_data {
11+ zonda_fs_client_t * client ;
12+ zonda_fs_file_t * file ;
13+ };
14+
15+ struct zondafsio_options {
16+ char * master ;
17+ char * cluster ;
18+ char * client ;
19+ char * fence_dir ;
20+ char * log_path ;
21+ char * role ;
22+ char * ip ;
23+ };
24+
25+ static struct fio_option options [] = {
26+ {
27+ .name = "master" ,
28+ .lname = "zonda2 fs master addr" ,
29+ .type = FIO_OPT_STR_STORE ,
30+ .off1 = offsetof(struct zondafsio_options , master ),
31+ .def = "" ,
32+ .help = "Master addr of the zonda2 fs" ,
33+ .category = FIO_OPT_C_ENGINE ,
34+ .group = FIO_OPT_G_ZONDAFS ,
35+ },
36+ {
37+ .name = "cluster" ,
38+ .lname = "zonda2 cluster id" ,
39+ .type = FIO_OPT_STR_STORE ,
40+ .off1 = offsetof(struct zondafsio_options , cluster ),
41+ .def = "" ,
42+ .help = "Cluster id of the zonda2 fs" ,
43+ .category = FIO_OPT_C_ENGINE ,
44+ .group = FIO_OPT_G_ZONDAFS ,
45+ },
46+ {
47+ .name = "client" ,
48+ .lname = "zonda2 client id" ,
49+ .type = FIO_OPT_STR_STORE ,
50+ .off1 = offsetof(struct zondafsio_options , client ),
51+ .def = "fio_client" ,
52+ .help = "Client id of the zonda2 fs" ,
53+ .category = FIO_OPT_C_ENGINE ,
54+ .group = FIO_OPT_G_ZONDAFS ,
55+ },
56+ {
57+ .name = "fence_dir" ,
58+ .lname = "zonda2 read/write fence_dir" ,
59+ .type = FIO_OPT_STR_STORE ,
60+ .off1 = offsetof(struct zondafsio_options , fence_dir ),
61+ .def = "" ,
62+ .help = "Fence dir id of the zonda2 fs" ,
63+ .category = FIO_OPT_C_ENGINE ,
64+ .group = FIO_OPT_G_ZONDAFS ,
65+ },
66+ {
67+ .name = "log_path" ,
68+ .lname = "zonda2 cpp client log path" ,
69+ .type = FIO_OPT_STR_STORE ,
70+ .off1 = offsetof(struct zondafsio_options , log_path ),
71+ .def = "./logs" ,
72+ .help = "Log path of the zonda2 fs" ,
73+ .category = FIO_OPT_C_ENGINE ,
74+ .group = FIO_OPT_G_ZONDAFS ,
75+ },
76+ {
77+ .name = "role" ,
78+ .lname = "zonda2 cpp client role" ,
79+ .type = FIO_OPT_STR_STORE ,
80+ .off1 = offsetof(struct zondafsio_options , role ),
81+ .def = "fio_role" ,
82+ .help = "Role of the zonda2 fs" ,
83+ .category = FIO_OPT_C_ENGINE ,
84+ .group = FIO_OPT_G_ZONDAFS ,
85+ },
86+ {
87+ .name = "ip" ,
88+ .lname = "zonda2 ip used by io fence" ,
89+ .type = FIO_OPT_STR_STORE ,
90+ .off1 = offsetof(struct zondafsio_options , ip ),
91+ .def = "127.0.0.1" ,
92+ .help = "The host ip of the zonda2 fence" ,
93+ .category = FIO_OPT_C_ENGINE ,
94+ .group = FIO_OPT_G_ZONDAFS ,
95+ },
96+ {
97+ .name = NULL ,
98+ },
99+ };
100+
101+ static enum fio_q_status fio_zondafs_queue (struct thread_data * td ,
102+ struct io_u * io_u )
103+ {
104+ struct zondafsio_data * zd = td -> io_ops_data ;
105+ zonda_fs_file_t * file = NULL ;
106+ zonda_error_code_t code ;
107+ int ret ;
108+ unsigned long offset ;
109+ unsigned long bytes_written = 0 , bytes_read = 0 ;
110+ file = zd -> file ;
111+
112+ if (io_u -> ddir == DDIR_READ ) {
113+ code = zonda_fs_file_read_at (file , io_u -> xfer_buflen , io_u -> offset , io_u -> xfer_buflen , & bytes_read );
114+ if (code != 0 && code != 23014 ) {
115+ io_u -> error = EIO ;
116+ return FIO_Q_COMPLETED ;
117+ }
118+ if (bytes_read != io_u -> xfer_buflen ) {
119+ if (code != 23014 ) {
120+ io_u -> error = EIO ;
121+ }
122+ }
123+ } else if (io_u -> ddir == DDIR_WRITE ) {
124+ code = zonda_fs_file_append (file , io_u -> xfer_buflen , io_u -> xfer_buf , & bytes_written );
125+ if (code != 0 || bytes_written != io_u -> xfer_buflen ) {
126+ io_u -> error = EIO ;
127+ }
128+ } else {
129+ log_err ("zondafs: Invalid I/O Operation: %d\n" , io_u -> ddir );
130+ io_u -> error = EINVAL ;
131+ }
132+ if (io_u -> error )
133+ td_verror (td , io_u -> error , "xfer" );
134+
135+ return FIO_Q_COMPLETED ;
136+ }
137+
138+ int fio_zondafs_open_file (struct thread_data * td , struct fio_file * f )
139+ {
140+ struct zondafsio_data * zd = td -> io_ops_data ;
141+
142+ zonda_fs_file_t * file = NULL ;
143+ zonda_error_code_t code ;
144+
145+ uint32_t flags = ZONDA_FS_OPEN_FLAGS_RDWR | ZONDA_FS_OPEN_FLAGS_CREAT ;
146+ code = zonda_fs_client_open (zd -> client , f -> file_name , flags , & file );
147+ if (code != 0 ) {
148+ log_err ("zondafs: unable to open" );
149+ return code ;
150+ }
151+ zd -> file = file ;
152+ return 0 ;
153+ }
154+
155+ int fio_zondafs_close_file (struct thread_data * td , struct fio_file * f )
156+ {
157+ struct zondafsio_data * zd = td -> io_ops_data ;
158+
159+ zonda_fs_file_close (zd -> file );
160+ zonda_fs_file_destroy (zd -> file );
161+ zonda_fs_client_destroy (zd -> client );
162+ return 0 ;
163+ }
164+
165+ static int fio_zondafs_setup (struct thread_data * td )
166+ {
167+ struct zondafsio_data * zd ;
168+ struct fio_file * f ;
169+ int i ;
170+ uint64_t file_size , total_file_size ;
171+
172+ if (!td -> io_ops_data ) {
173+ zd = calloc (1 , sizeof (* zd ));
174+ td -> io_ops_data = zd ;
175+ }
176+
177+ total_file_size = 0 ;
178+ file_size = 0 ;
179+
180+ for_each_file (td , f , i ) {
181+ if (!td -> o .file_size_low ) {
182+ file_size = floor (td -> o .size / td -> o .nr_files );
183+ total_file_size += file_size ;
184+ }
185+ else if (td -> o .file_size_low == td -> o .file_size_high )
186+ file_size = td -> o .file_size_low ;
187+ else {
188+ file_size = get_rand_file_size (td );
189+ }
190+ f -> real_file_size = file_size ;
191+ }
192+ return 0 ;
193+ }
194+
195+ static int fio_zondafs_init (struct thread_data * td )
196+ {
197+ struct zondafsio_data * zd = td -> io_ops_data ;
198+ struct zondafsio_options * option = td -> eo ;
199+
200+ zonda_fs_client_t * client = NULL ;
201+ zonda_error_code_t code ;
202+
203+ zonda_fs_conn_config_t config = {
204+ .master_addr = option -> master ,
205+ .cluster_id = option -> cluster ,
206+ .client_id = option -> client ,
207+ .fence_dir = option -> fence_dir ,
208+ .log_path = option -> log_path ,
209+ .role = option -> role ,
210+ .ip = option -> ip ,
211+ };
212+
213+ code = zonda_fs_client_new (& config , & client );
214+ if (code != 0 ) {
215+ log_err ("zondafs: unable to new client\n" );
216+ return EINVAL ;
217+ }
218+ zd -> client = client ;
219+
220+ code = zonda_fs_client_fence_directory (client , option -> fence_dir );
221+ if (code != 0 ) {
222+ log_err ("zondafs: unable to fence dir\n" );
223+ return EINVAL ;
224+ }
225+ return 0 ;
226+ }
227+
228+ FIO_STATIC struct ioengine_ops ioengine = {
229+ .name = "zondafs" ,
230+ .version = FIO_IOOPS_VERSION ,
231+ .flags = FIO_SYNCIO | FIO_DISKLESSIO | FIO_NODISKUTIL ,
232+ .setup = fio_zondafs_setup ,
233+ .init = fio_zondafs_init ,
234+ .queue = fio_zondafs_queue ,
235+ .open_file = fio_zondafs_open_file ,
236+ .close_file = fio_zondafs_close_file ,
237+ .option_struct_size = sizeof (struct zondafsio_options ),
238+ .options = options ,
239+ };
240+
241+ static void fio_init fio_zondafs_register (void )
242+ {
243+ register_ioengine (& ioengine );
244+ }
245+
246+ static void fio_exit fio_zondafs_unregister (void )
247+ {
248+ unregister_ioengine (& ioengine );
249+ }
0 commit comments