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