X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Fglusterfs.c;h=f2b84a2ab70b00013d13aafdbbaa73fc385071bc;hp=2abc283fc048f1580271cb257e1831454e5a3f18;hb=ce4d13ca162df4127ec3b5911553802c53396705;hpb=c1f9846dca7df2bfd37f0279092a5887913bf342 diff --git a/engines/glusterfs.c b/engines/glusterfs.c index 2abc283f..f2b84a2a 100644 --- a/engines/glusterfs.c +++ b/engines/glusterfs.c @@ -27,17 +27,160 @@ struct fio_option gfapi_options[] = { .category = FIO_OPT_C_ENGINE, .group = FIO_OPT_G_GFAPI, }, + { + .name = "single-instance", + .lname = "Single glusterfs instance", + .type = FIO_OPT_BOOL, + .help = "Only one glusterfs instance", + .off1 = offsetof(struct gf_options, gf_single_instance), + .category = FIO_OPT_C_ENGINE, + .group = FIO_OPT_G_GFAPI, + }, { .name = NULL, }, }; -int fio_gf_setup(struct thread_data *td) +struct glfs_info { + struct flist_head list; + char *volume; + char *brick; + glfs_t *fs; + int refcount; +}; + +static pthread_mutex_t glfs_lock = PTHREAD_MUTEX_INITIALIZER; +static FLIST_HEAD(glfs_list_head); + +static glfs_t *fio_gf_new_fs(char *volume, char *brick) { int r = 0; + glfs_t *fs; + struct stat sb = { 0, }; + + fs = glfs_new(volume); + if (!fs) { + log_err("glfs_new failed.\n"); + goto out; + } + glfs_set_logging(fs, "/tmp/fio_gfapi.log", 7); + /* default to tcp */ + r = glfs_set_volfile_server(fs, "tcp", brick, 0); + if (r) { + log_err("glfs_set_volfile_server failed.\n"); + goto out; + } + r = glfs_init(fs); + if (r) { + log_err("glfs_init failed. Is glusterd running on brick?\n"); + goto out; + } + sleep(2); + r = glfs_lstat(fs, ".", &sb); + if (r) { + log_err("glfs_lstat failed.\n"); + goto out; + } + +out: + if (r) { + glfs_fini(fs); + fs = NULL; + } + return fs; +} + +static glfs_t *fio_gf_get_glfs(struct gf_options *opt, + char *volume, char *brick) +{ + struct glfs_info *glfs = NULL; + struct glfs_info *tmp; + struct flist_head *entry; + + if (!opt->gf_single_instance) + return fio_gf_new_fs(volume, brick); + + pthread_mutex_lock (&glfs_lock); + + flist_for_each(entry, &glfs_list_head) { + tmp = flist_entry(entry, struct glfs_info, list); + if (!strcmp(volume, tmp->volume) && + !strcmp(brick, tmp->brick)) { + glfs = tmp; + break; + } + } + + if (glfs) { + glfs->refcount++; + } else { + glfs = malloc(sizeof(*glfs)); + if (!glfs) + goto out; + INIT_FLIST_HEAD(&glfs->list); + glfs->refcount = 0; + glfs->volume = strdup(volume); + glfs->brick = strdup(brick); + glfs->fs = fio_gf_new_fs(volume, brick); + if (!glfs->fs) { + free(glfs); + glfs = NULL; + goto out; + } + + flist_add_tail(&glfs->list, &glfs_list_head); + glfs->refcount = 1; + } + +out: + pthread_mutex_unlock (&glfs_lock); + + if (glfs) + return glfs->fs; + return NULL; +} + +static void fio_gf_put_glfs(struct gf_options *opt, glfs_t *fs) +{ + struct glfs_info *glfs = NULL; + struct glfs_info *tmp; + struct flist_head *entry; + + if (!opt->gf_single_instance) { + glfs_fini(fs); + return; + } + + pthread_mutex_lock (&glfs_lock); + + flist_for_each(entry, &glfs_list_head) { + tmp = flist_entry(entry, struct glfs_info, list); + if (tmp->fs == fs) { + glfs = tmp; + break; + } + } + + if (!glfs) { + log_err("glfs not found to fini.\n"); + } else { + glfs->refcount--; + + if (glfs->refcount == 0) { + glfs_fini(glfs->fs); + free(glfs->volume); + free(glfs->brick); + flist_del(&glfs->list); + } + } + + pthread_mutex_unlock (&glfs_lock); +} + +int fio_gf_setup(struct thread_data *td) +{ struct gf_data *g = NULL; struct gf_options *opt = td->eo; - struct stat sb = { 0, }; dprint(FD_IO, "fio setup\n"); @@ -49,42 +192,20 @@ int fio_gf_setup(struct thread_data *td) log_err("malloc failed.\n"); return -ENOMEM; } - g->fs = NULL; g->fd = NULL; g->aio_events = NULL; - g->fs = glfs_new(opt->gf_vol); - if (!g->fs) { - log_err("glfs_new failed.\n"); + g->fs = fio_gf_get_glfs(opt, opt->gf_vol, opt->gf_brick); + if (!g->fs) goto cleanup; - } - glfs_set_logging(g->fs, "/tmp/fio_gfapi.log", 7); - /* default to tcp */ - r = glfs_set_volfile_server(g->fs, "tcp", opt->gf_brick, 0); - if (r) { - log_err("glfs_set_volfile_server failed.\n"); - goto cleanup; - } - r = glfs_init(g->fs); - if (r) { - log_err("glfs_init failed. Is glusterd running on brick?\n"); - goto cleanup; - } - sleep(2); - r = glfs_lstat(g->fs, ".", &sb); - if (r) { - log_err("glfs_lstat failed.\n"); - goto cleanup; - } + dprint(FD_FILE, "fio setup %p\n", g->fs); td->io_ops_data = g; return 0; cleanup: - if (g->fs) - glfs_fini(g->fs); free(g); td->io_ops_data = NULL; - return r; + return -EIO; } void fio_gf_cleanup(struct thread_data *td) @@ -97,7 +218,7 @@ void fio_gf_cleanup(struct thread_data *td) if (g->fd) glfs_close(g->fd); if (g->fs) - glfs_fini(g->fs); + fio_gf_put_glfs(td->eo, g->fs); free(g); td->io_ops_data = NULL; } @@ -165,11 +286,15 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f) if (td_read(td)) { if (glfs_lstat(g->fs, f->file_name, &sb) || sb.st_size < f->real_file_size) { - dprint(FD_FILE, "fio extend file %s from %ld to %ld\n", - f->file_name, sb.st_size, f->real_file_size); + dprint(FD_FILE, "fio extend file %s from %jd to %" PRIu64 "\n", + f->file_name, (intmax_t) sb.st_size, f->real_file_size); +#if defined(CONFIG_GF_NEW_API) + ret = glfs_ftruncate(g->fd, f->real_file_size, NULL, NULL); +#else ret = glfs_ftruncate(g->fd, f->real_file_size); +#endif if (ret) { - log_err("failed fio extend file %s to %ld\n", + log_err("failed fio extend file %s to %" PRIu64 "\n", f->file_name, f->real_file_size); } else { unsigned long long left; @@ -190,7 +315,7 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f) r = glfs_write(g->fd, b, bs, 0); dprint(FD_IO, - "fio write %d of %ld file %s\n", + "fio write %d of %" PRIu64 " file %s\n", r, f->real_file_size, f->file_name); @@ -229,7 +354,11 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f) f->file_name); glfs_unlink(g->fs, f->file_name); } else if (td->o.create_fsync) { +#if defined(CONFIG_GF_NEW_API) + if (glfs_fsync(g->fd, NULL, NULL) < 0) { +#else if (glfs_fsync(g->fd) < 0) { +#endif dprint(FD_FILE, "failed to sync, close %s\n", f->file_name);