blob: b233b207eb49dec4e5477b16d83de48d1a7f31b0 [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;
80cleanup:
Jens Axboe3b665462014-05-19 10:12:56 -060081 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 }
chenh0e55d6b2014-03-27 15:19:43 -040089 }
90 return r;
91}
92
chenhcb92c7f2014-04-02 13:01:01 -040093void fio_gf_cleanup(struct thread_data *td)
chenh0e55d6b2014-03-27 15:19:43 -040094{
chenhcb92c7f2014-04-02 13:01:01 -040095 struct gf_data *g = td->io_ops->data;
96
97 if (g) {
Jens Axboe3b665462014-05-19 10:12:56 -060098 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;
chenhcb92c7f2014-04-02 13:01:01 -0400106 }
chenh0e55d6b2014-03-27 15:19:43 -0400107}
108
chenhcb92c7f2014-04-02 13:01:01 -0400109int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400110{
Jens Axboe3b665462014-05-19 10:12:56 -0600111 struct stat buf;
112 int ret;
113 struct gf_data *g = td->io_ops->data;
chenh0e55d6b2014-03-27 15:19:43 -0400114
Jens Axboe3b665462014-05-19 10:12:56 -0600115 dprint(FD_FILE, "get file size %s\n", f->file_name);
chenh1368c1c2014-03-28 15:01:42 -0400116
Jens Axboe3b665462014-05-19 10:12:56 -0600117 if (!g || !g->fs) {
118 return 0;
119 }
120 if (fio_file_size_known(f))
121 return 0;
chenh0e55d6b2014-03-27 15:19:43 -0400122
Jens Axboe3b665462014-05-19 10:12:56 -0600123 ret = glfs_lstat(g->fs, f->file_name, &buf);
124 if (ret < 0) {
125 log_err("glfs_lstat failed.\n");
126 return ret;
127 }
chenh0e55d6b2014-03-27 15:19:43 -0400128
Jens Axboe3b665462014-05-19 10:12:56 -0600129 f->real_file_size = buf.st_size;
130 fio_file_set_size_known(f);
chenh0e55d6b2014-03-27 15:19:43 -0400131
Jens Axboe3b665462014-05-19 10:12:56 -0600132 return 0;
chenh0e55d6b2014-03-27 15:19:43 -0400133
134}
135
chenhcb92c7f2014-04-02 13:01:01 -0400136int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400137{
chenh0ac466f2014-03-28 15:30:54 -0400138
Jens Axboe3b665462014-05-19 10:12:56 -0600139 int flags = 0;
140 int ret = 0;
141 struct gf_data *g = td->io_ops->data;
142 struct stat sb = { 0, };
chenh0e55d6b2014-03-27 15:19:43 -0400143
Jens Axboe3b665462014-05-19 10:12:56 -0600144 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;
chenh533362e2014-04-01 15:45:57 -0400175
Jens Axboe3b665462014-05-19 10:12:56 -0600176 /* fill the file, copied from extend_file */
177 b = malloc(td->o.max_bs[DDIR_WRITE]);
chenh533362e2014-04-01 15:45:57 -0400178
Jens Axboe3b665462014-05-19 10:12:56 -0600179 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;
chenh533362e2014-04-01 15:45:57 -0400184
Jens Axboe3b665462014-05-19 10:12:56 -0600185 fill_io_buffer(td, b, bs, bs);
chenh533362e2014-04-01 15:45:57 -0400186
Jens Axboe3b665462014-05-19 10:12:56 -0600187 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);
chenh533362e2014-04-01 15:45:57 -0400192
Jens Axboe3b665462014-05-19 10:12:56 -0600193 if (r > 0) {
194 left -= r;
195 continue;
196 } else {
197 if (r < 0) {
198 int __e = errno;
chenh533362e2014-04-01 15:45:57 -0400199
Jens Axboe3b665462014-05-19 10:12:56 -0600200 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");
chenh533362e2014-04-01 15:45:57 -0400214
Jens Axboe3b665462014-05-19 10:12:56 -0600215 break;
216 }
217 }
chenh533362e2014-04-01 15:45:57 -0400218
Jens Axboe3b665462014-05-19 10:12:56 -0600219 if (b)
220 free(b);
221 glfs_lseek(g->fd, 0, SEEK_SET);
chenh533362e2014-04-01 15:45:57 -0400222
Jens Axboe3b665462014-05-19 10:12:56 -0600223 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 }
chenh54fe20f2014-04-08 13:02:26 -0400241#if defined(GFAPI_USE_FADVISE)
Jens Axboe3b665462014-05-19 10:12:56 -0600242 {
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 }
chenh54fe20f2014-04-08 13:02:26 -0400256#endif
Jens Axboe3b665462014-05-19 10:12:56 -0600257 dprint(FD_FILE, "fio %p created %s\n", g->fs, f->file_name);
258 f->fd = -1;
259 f->shadow_fd = -1;
chenh0ac466f2014-03-28 15:30:54 -0400260
Jens Axboe3b665462014-05-19 10:12:56 -0600261 return ret;
chenh0e55d6b2014-03-27 15:19:43 -0400262}
263
chenhcb92c7f2014-04-02 13:01:01 -0400264int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
chenh0e55d6b2014-03-27 15:19:43 -0400265{
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
Jens Axboe3b665462014-05-19 10:12:56 -0600271 if (g) {
272 if (g->fd && glfs_close(g->fd) < 0)
273 ret = errno;
chenh0ac466f2014-03-28 15:30:54 -0400274
Jens Axboe3b665462014-05-19 10:12:56 -0600275 if (g->fs)
276 glfs_fini(g->fs);
chenh0e55d6b2014-03-27 15:19:43 -0400277
Jens Axboe3b665462014-05-19 10:12:56 -0600278 g->fd = NULL;
279 free(g);
280 }
chenh0ac466f2014-03-28 15:30:54 -0400281 td->io_ops->data = NULL;
chenh0e55d6b2014-03-27 15:19:43 -0400282 f->engine_data = 0;
283
284 return ret;
285}