engines/libaio: fix submit loop to use 'ld->queued' for exit
[fio.git] / engines / glusterfs.c
CommitLineData
6e7d7dfb 1/*
2 * glusterfs engine
3 *
cc47f094 4 * common Glusterfs's gfapi interface
6e7d7dfb 5 *
6 */
7
cc47f094 8#include "gfapi.h"
6e7d7dfb 9
cc47f094 10struct fio_option gfapi_options[] = {
b29c813f
JA
11 {
12 .name = "volume",
13 .lname = "Glusterfs volume",
14 .type = FIO_OPT_STR_STORE,
15 .help = "Name of the Glusterfs volume",
16 .off1 = offsetof(struct gf_options, gf_vol),
17 .category = FIO_OPT_C_ENGINE,
18 .group = FIO_OPT_G_GFAPI,
19 },
20 {
21 .name = "brick",
22 .lname = "Glusterfs brick name",
23 .type = FIO_OPT_STR_STORE,
24 .help = "Name of the Glusterfs brick to connect",
25 .off1 = offsetof(struct gf_options, gf_brick),
26 .category = FIO_OPT_C_ENGINE,
27 .group = FIO_OPT_G_GFAPI,
28 },
29 {
30 .name = NULL,
31 },
6e7d7dfb 32};
33
cc47f094 34int fio_gf_setup(struct thread_data *td)
6e7d7dfb 35{
36 int r = 0;
37 struct gf_data *g = NULL;
38 struct gf_options *opt = td->eo;
b29c813f 39 struct stat sb = { 0, };
7cb57176 40
41 dprint(FD_IO, "fio setup\n");
6e7d7dfb 42
43 if (td->io_ops->data)
b29c813f 44 return 0;
6e7d7dfb 45
46 g = malloc(sizeof(struct gf_data));
b29c813f
JA
47 if (!g) {
48 log_err("malloc failed.\n");
49 return -ENOMEM;
6e7d7dfb 50 }
b29c813f
JA
51 g->fs = NULL;
52 g->fd = NULL;
53 g->aio_events = NULL;
54
55 g->fs = glfs_new(opt->gf_vol);
56 if (!g->fs) {
57 log_err("glfs_new failed.\n");
58 goto cleanup;
6e7d7dfb 59 }
b29c813f 60 glfs_set_logging(g->fs, "/tmp/fio_gfapi.log", 7);
6e7d7dfb 61 /* default to tcp */
7cb57176 62 r = glfs_set_volfile_server(g->fs, "tcp", opt->gf_brick, 0);
b29c813f
JA
63 if (r) {
64 log_err("glfs_set_volfile_server failed.\n");
65 goto cleanup;
6e7d7dfb 66 }
67 r = glfs_init(g->fs);
b29c813f
JA
68 if (r) {
69 log_err("glfs_init failed. Is glusterd running on brick?\n");
70 goto cleanup;
7cb57176 71 }
72 sleep(2);
b29c813f
JA
73 r = glfs_lstat(g->fs, ".", &sb);
74 if (r) {
75 log_err("glfs_lstat failed.\n");
76 goto cleanup;
6e7d7dfb 77 }
7cb57176 78 dprint(FD_FILE, "fio setup %p\n", g->fs);
6e7d7dfb 79 td->io_ops->data = g;
93782cbb 80 return 0;
6e7d7dfb 81cleanup:
93782cbb
JA
82 if (g->fs)
83 glfs_fini(g->fs);
84 free(g);
85 td->io_ops->data = NULL;
6e7d7dfb 86 return r;
87}
88
cc47f094 89void fio_gf_cleanup(struct thread_data *td)
6e7d7dfb 90{
cc47f094 91 struct gf_data *g = td->io_ops->data;
92
93 if (g) {
b29c813f
JA
94 if (g->aio_events)
95 free(g->aio_events);
96 if (g->fd)
97 glfs_close(g->fd);
98 if (g->fs)
99 glfs_fini(g->fs);
100 free(g);
101 td->io_ops->data = NULL;
cc47f094 102 }
6e7d7dfb 103}
104
cc47f094 105int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
6e7d7dfb 106{
b29c813f
JA
107 struct stat buf;
108 int ret;
109 struct gf_data *g = td->io_ops->data;
6e7d7dfb 110
b29c813f 111 dprint(FD_FILE, "get file size %s\n", f->file_name);
6aa56500 112
b29c813f
JA
113 if (!g || !g->fs) {
114 return 0;
115 }
116 if (fio_file_size_known(f))
117 return 0;
6e7d7dfb 118
b29c813f
JA
119 ret = glfs_lstat(g->fs, f->file_name, &buf);
120 if (ret < 0) {
121 log_err("glfs_lstat failed.\n");
122 return ret;
123 }
6e7d7dfb 124
b29c813f
JA
125 f->real_file_size = buf.st_size;
126 fio_file_set_size_known(f);
6e7d7dfb 127
b29c813f 128 return 0;
6e7d7dfb 129
130}
131
cc47f094 132int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
6e7d7dfb 133{
a8a93dee 134
b29c813f
JA
135 int flags = 0;
136 int ret = 0;
137 struct gf_data *g = td->io_ops->data;
138 struct stat sb = { 0, };
139
140 if (td_write(td)) {
141 if (!read_only)
142 flags = O_RDWR;
143 } else if (td_read(td)) {
144 if (!read_only)
145 flags = O_RDWR;
146 else
147 flags = O_RDONLY;
148 }
65bea10f
TM
149
150 if (td->o.odirect)
151 flags |= OS_O_DIRECT;
152 if (td->o.sync_io)
153 flags |= O_SYNC;
154
b29c813f 155 dprint(FD_FILE, "fio file %s open mode %s td rw %s\n", f->file_name,
65bea10f 156 flags & O_RDONLY ? "ro" : "rw", td_read(td) ? "read" : "write");
b29c813f
JA
157 g->fd = glfs_creat(g->fs, f->file_name, flags, 0644);
158 if (!g->fd) {
b29c813f 159 ret = errno;
1a889967
TM
160 log_err("glfs_creat failed.\n");
161 return ret;
b29c813f
JA
162 }
163 /* file for read doesn't exist or shorter than required, create/extend it */
164 if (td_read(td)) {
165 if (glfs_lstat(g->fs, f->file_name, &sb)
166 || sb.st_size < f->real_file_size) {
167 dprint(FD_FILE, "fio extend file %s from %ld to %ld\n",
168 f->file_name, sb.st_size, f->real_file_size);
169 ret = glfs_ftruncate(g->fd, f->real_file_size);
170 if (ret) {
171 log_err("failed fio extend file %s to %ld\n",
172 f->file_name, f->real_file_size);
173 } else {
174 unsigned long long left;
175 unsigned int bs;
176 char *b;
177 int r;
178
179 /* fill the file, copied from extend_file */
180 b = malloc(td->o.max_bs[DDIR_WRITE]);
181
182 left = f->real_file_size;
183 while (left && !td->terminate) {
184 bs = td->o.max_bs[DDIR_WRITE];
185 if (bs > left)
186 bs = left;
187
188 fill_io_buffer(td, b, bs, bs);
189
190 r = glfs_write(g->fd, b, bs, 0);
191 dprint(FD_IO,
192 "fio write %d of %ld file %s\n",
193 r, f->real_file_size,
194 f->file_name);
195
196 if (r > 0) {
197 left -= r;
198 continue;
199 } else {
200 if (r < 0) {
201 int __e = errno;
202
203 if (__e == ENOSPC) {
204 if (td->o.
205 fill_device)
206 break;
207 log_info
208 ("fio: ENOSPC on laying out "
209 "file, stopping\n");
210 break;
211 }
212 td_verror(td, errno,
213 "write");
214 } else
215 td_verror(td, EIO,
216 "write");
217
218 break;
219 }
220 }
221
222 if (b)
223 free(b);
224 glfs_lseek(g->fd, 0, SEEK_SET);
225
38ef9c90 226 if (td->terminate && td->o.unlink) {
b29c813f
JA
227 dprint(FD_FILE, "terminate unlink %s\n",
228 f->file_name);
38ef9c90 229 glfs_unlink(g->fs, f->file_name);
b29c813f
JA
230 } else if (td->o.create_fsync) {
231 if (glfs_fsync(g->fd) < 0) {
232 dprint(FD_FILE,
233 "failed to sync, close %s\n",
234 f->file_name);
235 td_verror(td, errno, "fsync");
236 glfs_close(g->fd);
237 g->fd = NULL;
238 return 1;
239 }
240 }
241 }
242 }
243 }
6fa14b99 244#if defined(GFAPI_USE_FADVISE)
b29c813f
JA
245 {
246 int r = 0;
247 if (td_random(td)) {
248 r = glfs_fadvise(g->fd, 0, f->real_file_size,
249 POSIX_FADV_RANDOM);
250 } else {
251 r = glfs_fadvise(g->fd, 0, f->real_file_size,
252 POSIX_FADV_SEQUENTIAL);
253 }
254 if (r) {
255 dprint(FD_FILE, "fio %p fadvise %s status %d\n", g->fs,
256 f->file_name, r);
257 }
258 }
6fa14b99 259#endif
b29c813f
JA
260 dprint(FD_FILE, "fio %p created %s\n", g->fs, f->file_name);
261 f->fd = -1;
262 f->shadow_fd = -1;
e6590c12 263 td->o.open_files ++;
b29c813f 264 return ret;
6e7d7dfb 265}
266
cc47f094 267int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
6e7d7dfb 268{
269 int ret = 0;
270 struct gf_data *g = td->io_ops->data;
271
272 dprint(FD_FILE, "fd close %s\n", f->file_name);
273
b29c813f
JA
274 if (g) {
275 if (g->fd && glfs_close(g->fd) < 0)
276 ret = errno;
38ef9c90
CF
277 g->fd = NULL;
278 }
279
280 return ret;
281}
282
283int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f)
284{
285 int ret = 0;
286 struct gf_data *g = td->io_ops->data;
287
288 dprint(FD_FILE, "fd unlink %s\n", f->file_name);
289
290 if (g) {
291 if (g->fd && glfs_close(g->fd) < 0)
292 ret = errno;
293
294 glfs_unlink(g->fs, f->file_name);
7cb57176 295
b29c813f
JA
296 if (g->fs)
297 glfs_fini(g->fs);
6e7d7dfb 298
b29c813f
JA
299 g->fd = NULL;
300 free(g);
301 }
7cb57176 302 td->io_ops->data = NULL;
6e7d7dfb 303
304 return ret;
305}