b233b207eb49dec4e5477b16d83de48d1a7f31b0
[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         dprint(FD_FILE, "fio file %s open mode %s td rw %s\n", f->file_name,
154                flags == O_RDONLY ? "ro" : "rw", td_read(td) ? "read" : "write");
155         g->fd = glfs_creat(g->fs, f->file_name, flags, 0644);
156         if (!g->fd) {
157                 log_err("glfs_creat failed.\n");
158                 ret = errno;
159         }
160         /* file for read doesn't exist or shorter than required, create/extend it */
161         if (td_read(td)) {
162                 if (glfs_lstat(g->fs, f->file_name, &sb)
163                     || sb.st_size < f->real_file_size) {
164                         dprint(FD_FILE, "fio extend file %s from %ld to %ld\n",
165                                f->file_name, sb.st_size, f->real_file_size);
166                         ret = glfs_ftruncate(g->fd, f->real_file_size);
167                         if (ret) {
168                                 log_err("failed fio extend file %s to %ld\n",
169                                         f->file_name, f->real_file_size);
170                         } else {
171                                 unsigned long long left;
172                                 unsigned int bs;
173                                 char *b;
174                                 int r;
175
176                                 /* fill the file, copied from extend_file */
177                                 b = malloc(td->o.max_bs[DDIR_WRITE]);
178
179                                 left = f->real_file_size;
180                                 while (left && !td->terminate) {
181                                         bs = td->o.max_bs[DDIR_WRITE];
182                                         if (bs > left)
183                                                 bs = left;
184
185                                         fill_io_buffer(td, b, bs, bs);
186
187                                         r = glfs_write(g->fd, b, bs, 0);
188                                         dprint(FD_IO,
189                                                "fio write %d of %ld file %s\n",
190                                                r, f->real_file_size,
191                                                f->file_name);
192
193                                         if (r > 0) {
194                                                 left -= r;
195                                                 continue;
196                                         } else {
197                                                 if (r < 0) {
198                                                         int __e = errno;
199
200                                                         if (__e == ENOSPC) {
201                                                                 if (td->o.
202                                                                     fill_device)
203                                                                         break;
204                                                                 log_info
205                                                                     ("fio: ENOSPC on laying out "
206                                                                      "file, stopping\n");
207                                                                 break;
208                                                         }
209                                                         td_verror(td, errno,
210                                                                   "write");
211                                                 } else
212                                                         td_verror(td, EIO,
213                                                                   "write");
214
215                                                 break;
216                                         }
217                                 }
218
219                                 if (b)
220                                         free(b);
221                                 glfs_lseek(g->fd, 0, SEEK_SET);
222
223                                 if (td->terminate) {
224                                         dprint(FD_FILE, "terminate unlink %s\n",
225                                                f->file_name);
226                                         unlink(f->file_name);
227                                 } else if (td->o.create_fsync) {
228                                         if (glfs_fsync(g->fd) < 0) {
229                                                 dprint(FD_FILE,
230                                                        "failed to sync, close %s\n",
231                                                        f->file_name);
232                                                 td_verror(td, errno, "fsync");
233                                                 glfs_close(g->fd);
234                                                 g->fd = NULL;
235                                                 return 1;
236                                         }
237                                 }
238                         }
239                 }
240         }
241 #if defined(GFAPI_USE_FADVISE)
242         {
243                 int r = 0;
244                 if (td_random(td)) {
245                         r = glfs_fadvise(g->fd, 0, f->real_file_size,
246                                          POSIX_FADV_RANDOM);
247                 } else {
248                         r = glfs_fadvise(g->fd, 0, f->real_file_size,
249                                          POSIX_FADV_SEQUENTIAL);
250                 }
251                 if (r) {
252                         dprint(FD_FILE, "fio %p fadvise %s status %d\n", g->fs,
253                                f->file_name, r);
254                 }
255         }
256 #endif
257         dprint(FD_FILE, "fio %p created %s\n", g->fs, f->file_name);
258         f->fd = -1;
259         f->shadow_fd = -1;
260
261         return ret;
262 }
263
264 int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
265 {
266         int ret = 0;
267         struct gf_data *g = td->io_ops->data;
268
269         dprint(FD_FILE, "fd close %s\n", f->file_name);
270
271         if (g) {
272                 if (g->fd && glfs_close(g->fd) < 0)
273                         ret = errno;
274
275                 if (g->fs)
276                         glfs_fini(g->fs);
277
278                 g->fd = NULL;
279                 free(g);
280         }
281         td->io_ops->data = NULL;
282         f->engine_data = 0;
283
284         return ret;
285 }