blob: 507cd25dc89d0c638193134d0543b0670da0ed50 [file] [log] [blame]
chenh0e55d6b2014-03-27 15:19:43 -04001/*
2 * glusterfs engine
3 *
chenhcb92c7f2014-04-02 13:01:01 -04004 * common Glusterfs's gfapi interface
chenh0e55d6b2014-03-27 15:19:43 -04005 *
6 */
7
chenhcb92c7f2014-04-02 13:01:01 -04008#include "gfapi.h"
chenh0e55d6b2014-03-27 15:19:43 -04009
chenhcb92c7f2014-04-02 13:01:01 -040010struct fio_option gfapi_options[] = {
Jens Axboe3b665462014-05-19 10:12:56 -060011 {
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 },
chenh0e55d6b2014-03-27 15:19:43 -040032};
33
chenhcb92c7f2014-04-02 13:01:01 -040034int fio_gf_setup(struct thread_data *td)
chenh0e55d6b2014-03-27 15:19:43 -040035{
36 int r = 0;
37 struct gf_data *g = NULL;
38 struct gf_options *opt = td->eo;
Jens Axboe3b665462014-05-19 10:12:56 -060039 struct stat sb = { 0, };
chenh0ac466f2014-03-28 15:30:54 -040040
41 dprint(FD_IO, "fio setup\n");
chenh0e55d6b2014-03-27 15:19:43 -040042
43 if (td->io_ops->data)
Jens Axboe3b665462014-05-19 10:12:56 -060044 return 0;
chenh0e55d6b2014-03-27 15:19:43 -040045
46 g = malloc(sizeof(struct gf_data));
Jens Axboe3b665462014-05-19 10:12:56 -060047 if (!g) {
48 log_err("malloc failed.\n");
49 return -ENOMEM;
chenh0e55d6b2014-03-27 15:19:43 -040050 }
Jens Axboe3b665462014-05-19 10:12:56 -060051 g->fs = NULL;
52 g->fd = NULL;
53 g->aio_events = NULL;
chenh0e55d6b2014-03-27 15:19:43 -040054
Jens Axboe3b665462014-05-19 10:12:56 -060055 g->fs = glfs_new(opt->gf_vol);
56 if (!g->fs) {
57 log_err("glfs_new failed.\n");
58 goto cleanup;
chenh0e55d6b2014-03-27 15:19:43 -040059 }
Jens Axboe3b665462014-05-19 10:12:56 -060060 glfs_set_logging(g->fs, "/tmp/fio_gfapi.log", 7);
chenh0e55d6b2014-03-27 15:19:43 -040061 /* default to tcp */
chenh0ac466f2014-03-28 15:30:54 -040062 r = glfs_set_volfile_server(g->fs, "tcp", opt->gf_brick, 0);
Jens Axboe3b665462014-05-19 10:12:56 -060063 if (r) {
64 log_err("glfs_set_volfile_server failed.\n");
65 goto cleanup;
chenh0e55d6b2014-03-27 15:19:43 -040066 }
67 r = glfs_init(g->fs);
Jens Axboe3b665462014-05-19 10:12:56 -060068 if (r) {
69 log_err("glfs_init failed. Is glusterd running on brick?\n");
70 goto cleanup;
chenh0e55d6b2014-03-27 15:19:43 -040071 }
chenh0ac466f2014-03-28 15:30:54 -040072 sleep(2);
Jens Axboe3b665462014-05-19 10:12:56 -060073 r = glfs_lstat(g->fs, ".", &sb);
74 if (r) {
75 log_err("glfs_lstat failed.\n");
76 goto cleanup;
chenh0ac466f2014-03-28 15:30:54 -040077 }
78 dprint(FD_FILE, "fio setup %p\n", g->fs);
chenh0e55d6b2014-03-27 15:19:43 -040079 td->io_ops->data = g;
Jens Axboe7cb786f2014-07-03 15:30:37 -060080 return 0;
chenh0e55d6b2014-03-27 15:19:43 -040081cleanup:
Jens Axboe7cb786f2014-07-03 15:30:37 -060082 if (g->fs)
83 glfs_fini(g->fs);
84 free(g);
85 td->io_ops->data = NULL;
chenh0e55d6b2014-03-27 15:19:43 -040086 return r;
87}
88
chenhcb92c7f2014-04-02 13:01:01 -040089void fio_gf_cleanup(struct thread_data *td)
chenh0e55d6b2014-03-27 15:19:43 -040090{
chenhcb92c7f2014-04-02 13:01:01 -040091 struct gf_data *g = td->io_ops->data;
92
93 if (g) {
Jens Axboe3b665462014-05-19 10:12:56 -060094 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;
chenhcb92c7f2014-04-02 13:01:01 -0400102 }
chenh0e55d6b2014-03-27 15:19:43 -0400103}
104
chenhcb92c7f2014-04-02 13:01:01 -0400105int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400106{
Jens Axboe3b665462014-05-19 10:12:56 -0600107 struct stat buf;
108 int ret;
109 struct gf_data *g = td->io_ops->data;
chenh0e55d6b2014-03-27 15:19:43 -0400110
Jens Axboe3b665462014-05-19 10:12:56 -0600111 dprint(FD_FILE, "get file size %s\n", f->file_name);
chenh1368c1c2014-03-28 15:01:42 -0400112
Jens Axboe3b665462014-05-19 10:12:56 -0600113 if (!g || !g->fs) {
114 return 0;
115 }
116 if (fio_file_size_known(f))
117 return 0;
chenh0e55d6b2014-03-27 15:19:43 -0400118
Jens Axboe3b665462014-05-19 10:12:56 -0600119 ret = glfs_lstat(g->fs, f->file_name, &buf);
120 if (ret < 0) {
121 log_err("glfs_lstat failed.\n");
122 return ret;
123 }
chenh0e55d6b2014-03-27 15:19:43 -0400124
Jens Axboe3b665462014-05-19 10:12:56 -0600125 f->real_file_size = buf.st_size;
126 fio_file_set_size_known(f);
chenh0e55d6b2014-03-27 15:19:43 -0400127
Jens Axboe3b665462014-05-19 10:12:56 -0600128 return 0;
chenh0e55d6b2014-03-27 15:19:43 -0400129
130}
131
chenhcb92c7f2014-04-02 13:01:01 -0400132int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400133{
chenh0ac466f2014-03-28 15:30:54 -0400134
Jens Axboe3b665462014-05-19 10:12:56 -0600135 int flags = 0;
136 int ret = 0;
137 struct gf_data *g = td->io_ops->data;
138 struct stat sb = { 0, };
chenh0e55d6b2014-03-27 15:19:43 -0400139
Jens Axboe3b665462014-05-19 10:12:56 -0600140 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 }
Tiziano Müller05986502014-07-03 16:48:39 +0200149
150 if (td->o.odirect)
151 flags |= OS_O_DIRECT;
152 if (td->o.sync_io)
153 flags |= O_SYNC;
154
Jens Axboe3b665462014-05-19 10:12:56 -0600155 dprint(FD_FILE, "fio file %s open mode %s td rw %s\n", f->file_name,
Tiziano Müller05986502014-07-03 16:48:39 +0200156 flags & O_RDONLY ? "ro" : "rw", td_read(td) ? "read" : "write");
Jens Axboe3b665462014-05-19 10:12:56 -0600157 g->fd = glfs_creat(g->fs, f->file_name, flags, 0644);
158 if (!g->fd) {
Jens Axboe3b665462014-05-19 10:12:56 -0600159 ret = errno;
Tiziano Müllerc5b35fb2014-07-03 18:22:29 +0200160 log_err("glfs_creat failed.\n");
161 return ret;
Jens Axboe3b665462014-05-19 10:12:56 -0600162 }
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;
chenh533362e2014-04-01 15:45:57 -0400178
Jens Axboe3b665462014-05-19 10:12:56 -0600179 /* fill the file, copied from extend_file */
180 b = malloc(td->o.max_bs[DDIR_WRITE]);
chenh533362e2014-04-01 15:45:57 -0400181
Jens Axboe3b665462014-05-19 10:12:56 -0600182 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;
chenh533362e2014-04-01 15:45:57 -0400187
Jens Axboe3b665462014-05-19 10:12:56 -0600188 fill_io_buffer(td, b, bs, bs);
chenh533362e2014-04-01 15:45:57 -0400189
Jens Axboe3b665462014-05-19 10:12:56 -0600190 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);
chenh533362e2014-04-01 15:45:57 -0400195
Jens Axboe3b665462014-05-19 10:12:56 -0600196 if (r > 0) {
197 left -= r;
198 continue;
199 } else {
200 if (r < 0) {
201 int __e = errno;
chenh533362e2014-04-01 15:45:57 -0400202
Jens Axboe3b665462014-05-19 10:12:56 -0600203 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");
chenh533362e2014-04-01 15:45:57 -0400217
Jens Axboe3b665462014-05-19 10:12:56 -0600218 break;
219 }
220 }
chenh533362e2014-04-01 15:45:57 -0400221
Jens Axboe3b665462014-05-19 10:12:56 -0600222 if (b)
223 free(b);
224 glfs_lseek(g->fd, 0, SEEK_SET);
chenh533362e2014-04-01 15:45:57 -0400225
Castor Fu9187a262014-08-19 09:28:53 -0700226 if (td->terminate && td->o.unlink) {
Jens Axboe3b665462014-05-19 10:12:56 -0600227 dprint(FD_FILE, "terminate unlink %s\n",
228 f->file_name);
Castor Fu9187a262014-08-19 09:28:53 -0700229 glfs_unlink(g->fs, f->file_name);
Jens Axboe3b665462014-05-19 10:12:56 -0600230 } 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 }
chenh54fe20f2014-04-08 13:02:26 -0400244#if defined(GFAPI_USE_FADVISE)
Jens Axboe3b665462014-05-19 10:12:56 -0600245 {
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 }
chenh54fe20f2014-04-08 13:02:26 -0400259#endif
Jens Axboe3b665462014-05-19 10:12:56 -0600260 dprint(FD_FILE, "fio %p created %s\n", g->fs, f->file_name);
261 f->fd = -1;
262 f->shadow_fd = -1;
rootfsb42fab12014-08-19 14:42:45 -0400263 td->o.open_files ++;
Jens Axboe3b665462014-05-19 10:12:56 -0600264 return ret;
chenh0e55d6b2014-03-27 15:19:43 -0400265}
266
chenhcb92c7f2014-04-02 13:01:01 -0400267int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400268{
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
Jens Axboe3b665462014-05-19 10:12:56 -0600274 if (g) {
275 if (g->fd && glfs_close(g->fd) < 0)
276 ret = errno;
Castor Fu9187a262014-08-19 09:28:53 -0700277 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);
chenh0ac466f2014-03-28 15:30:54 -0400295
Jens Axboe3b665462014-05-19 10:12:56 -0600296 if (g->fs)
297 glfs_fini(g->fs);
chenh0e55d6b2014-03-27 15:19:43 -0400298
Jens Axboe3b665462014-05-19 10:12:56 -0600299 g->fd = NULL;
300 free(g);
301 }
chenh0ac466f2014-03-28 15:30:54 -0400302 td->io_ops->data = NULL;
chenh0e55d6b2014-03-27 15:19:43 -0400303
304 return ret;
305}