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