4 * common Glusterfs's gfapi interface
9 #include "../optgroup.h"
11 struct fio_option gfapi_options[] = {
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,
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,
31 .name = "single-instance",
32 .lname = "Single glusterfs instance",
34 .help = "Only one glusterfs instance",
35 .off1 = offsetof(struct gf_options, gf_single_instance),
36 .category = FIO_OPT_C_ENGINE,
37 .group = FIO_OPT_G_GFAPI,
45 struct flist_head list;
52 static pthread_mutex_t glfs_lock = PTHREAD_MUTEX_INITIALIZER;
53 static FLIST_HEAD(glfs_list_head);
55 static glfs_t *fio_gf_new_fs(char *volume, char *brick)
59 struct stat sb = { 0, };
61 fs = glfs_new(volume);
63 log_err("glfs_new failed.\n");
66 glfs_set_logging(fs, "/tmp/fio_gfapi.log", 7);
68 r = glfs_set_volfile_server(fs, "tcp", brick, 0);
70 log_err("glfs_set_volfile_server failed.\n");
75 log_err("glfs_init failed. Is glusterd running on brick?\n");
79 r = glfs_lstat(fs, ".", &sb);
81 log_err("glfs_lstat failed.\n");
93 static glfs_t *fio_gf_get_glfs(struct gf_options *opt,
94 char *volume, char *brick)
96 struct glfs_info *glfs = NULL;
97 struct glfs_info *tmp;
98 struct flist_head *entry;
100 if (!opt->gf_single_instance)
101 return fio_gf_new_fs(volume, brick);
103 pthread_mutex_lock (&glfs_lock);
105 flist_for_each(entry, &glfs_list_head) {
106 tmp = flist_entry(entry, struct glfs_info, list);
107 if (!strcmp(volume, tmp->volume) &&
108 !strcmp(brick, tmp->brick)) {
117 glfs = malloc(sizeof(*glfs));
120 INIT_FLIST_HEAD(&glfs->list);
122 glfs->volume = strdup(volume);
123 glfs->brick = strdup(brick);
124 glfs->fs = fio_gf_new_fs(volume, brick);
131 flist_add_tail(&glfs->list, &glfs_list_head);
136 pthread_mutex_unlock (&glfs_lock);
143 static void fio_gf_put_glfs(struct gf_options *opt, glfs_t *fs)
145 struct glfs_info *glfs = NULL;
146 struct glfs_info *tmp;
147 struct flist_head *entry;
149 if (!opt->gf_single_instance) {
154 pthread_mutex_lock (&glfs_lock);
156 flist_for_each(entry, &glfs_list_head) {
157 tmp = flist_entry(entry, struct glfs_info, list);
165 log_err("glfs not found to fini.\n");
169 if (glfs->refcount == 0) {
173 flist_del(&glfs->list);
177 pthread_mutex_unlock (&glfs_lock);
180 int fio_gf_setup(struct thread_data *td)
182 struct gf_data *g = NULL;
183 struct gf_options *opt = td->eo;
185 dprint(FD_IO, "fio setup\n");
190 g = malloc(sizeof(struct gf_data));
192 log_err("malloc failed.\n");
196 g->aio_events = NULL;
198 g->fs = fio_gf_get_glfs(opt, opt->gf_vol, opt->gf_brick);
202 dprint(FD_FILE, "fio setup %p\n", g->fs);
207 td->io_ops_data = NULL;
211 void fio_gf_cleanup(struct thread_data *td)
213 struct gf_data *g = td->io_ops_data;
221 fio_gf_put_glfs(td->eo, g->fs);
223 td->io_ops_data = NULL;
227 int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f)
231 struct gf_data *g = td->io_ops_data;
233 dprint(FD_FILE, "get file size %s\n", f->file_name);
238 if (fio_file_size_known(f))
241 ret = glfs_lstat(g->fs, f->file_name, &buf);
243 log_err("glfs_lstat failed.\n");
247 f->real_file_size = buf.st_size;
248 fio_file_set_size_known(f);
254 int fio_gf_open_file(struct thread_data *td, struct fio_file *f)
259 struct gf_data *g = td->io_ops_data;
260 struct stat sb = { 0, };
265 } else if (td_read(td)) {
273 flags |= OS_O_DIRECT;
277 dprint(FD_FILE, "fio file %s open mode %s td rw %s\n", f->file_name,
278 flags & O_RDONLY ? "ro" : "rw", td_read(td) ? "read" : "write");
279 g->fd = glfs_creat(g->fs, f->file_name, flags, 0644);
282 log_err("glfs_creat failed.\n");
285 /* file for read doesn't exist or shorter than required, create/extend it */
287 if (glfs_lstat(g->fs, f->file_name, &sb)
288 || sb.st_size < f->real_file_size) {
289 dprint(FD_FILE, "fio extend file %s from %jd to %" PRIu64 "\n",
290 f->file_name, (intmax_t) sb.st_size, f->real_file_size);
291 #if defined(CONFIG_GF_NEW_API)
292 ret = glfs_ftruncate(g->fd, f->real_file_size, NULL, NULL);
294 ret = glfs_ftruncate(g->fd, f->real_file_size);
297 log_err("failed fio extend file %s to %" PRIu64 "\n",
298 f->file_name, f->real_file_size);
300 unsigned long long left;
305 /* fill the file, copied from extend_file */
306 b = malloc(td->o.max_bs[DDIR_WRITE]);
308 left = f->real_file_size;
309 while (left && !td->terminate) {
310 bs = td->o.max_bs[DDIR_WRITE];
314 fill_io_buffer(td, b, bs, bs);
316 r = glfs_write(g->fd, b, bs, 0);
318 "fio write %d of %" PRIu64 " file %s\n",
319 r, f->real_file_size,
334 ("fio: ENOSPC on laying out "
350 glfs_lseek(g->fd, 0, SEEK_SET);
352 if (td->terminate && td->o.unlink) {
353 dprint(FD_FILE, "terminate unlink %s\n",
355 glfs_unlink(g->fs, f->file_name);
356 } else if (td->o.create_fsync) {
357 #if defined(CONFIG_GF_NEW_API)
358 if (glfs_fsync(g->fd, NULL, NULL) < 0) {
360 if (glfs_fsync(g->fd) < 0) {
363 "failed to sync, close %s\n",
365 td_verror(td, errno, "fsync");
374 #if defined(GFAPI_USE_FADVISE)
378 r = glfs_fadvise(g->fd, 0, f->real_file_size,
381 r = glfs_fadvise(g->fd, 0, f->real_file_size,
382 POSIX_FADV_SEQUENTIAL);
385 dprint(FD_FILE, "fio %p fadvise %s status %d\n", g->fs,
390 dprint(FD_FILE, "fio %p created %s\n", g->fs, f->file_name);
397 int fio_gf_close_file(struct thread_data *td, struct fio_file *f)
400 struct gf_data *g = td->io_ops_data;
402 dprint(FD_FILE, "fd close %s\n", f->file_name);
405 if (g->fd && glfs_close(g->fd) < 0)
413 int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f)
416 struct gf_data *g = td->io_ops_data;
418 dprint(FD_FILE, "fd unlink %s\n", f->file_name);
421 if (g->fd && glfs_close(g->fd) < 0)
424 glfs_unlink(g->fs, f->file_name);
432 td->io_ops_data = NULL;