X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Fglusterfs.c;h=d0250b70eab0713941a0567c4b23da58ddd82c36;hp=507cd25dc89d0c638193134d0543b0670da0ed50;hb=4806b82473fea74c517e5e0c7665b0ca0542b3ec;hpb=38ef9c90fbe4fddc209f94b277b49e78f7f6a424 diff --git a/engines/glusterfs.c b/engines/glusterfs.c index 507cd25d..d0250b70 100644 --- a/engines/glusterfs.c +++ b/engines/glusterfs.c @@ -6,6 +6,7 @@ */ #include "gfapi.h" +#include "../optgroup.h" struct fio_option gfapi_options[] = { { @@ -26,21 +27,164 @@ 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"); - if (td->io_ops->data) + if (td->io_ops_data) return 0; g = malloc(sizeof(struct gf_data)); @@ -48,47 +192,25 @@ 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"); - 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"); + g->fs = fio_gf_get_glfs(opt, opt->gf_vol, opt->gf_brick); + if (!g->fs) 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; + td->io_ops_data = g; return 0; cleanup: - if (g->fs) - glfs_fini(g->fs); free(g); - td->io_ops->data = NULL; - return r; + td->io_ops_data = NULL; + return -EIO; } void fio_gf_cleanup(struct thread_data *td) { - struct gf_data *g = td->io_ops->data; + struct gf_data *g = td->io_ops_data; if (g) { if (g->aio_events) @@ -96,9 +218,9 @@ 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; + td->io_ops_data = NULL; } } @@ -106,7 +228,7 @@ int fio_gf_get_file_size(struct thread_data *td, struct fio_file *f) { struct stat buf; int ret; - struct gf_data *g = td->io_ops->data; + struct gf_data *g = td->io_ops_data; dprint(FD_FILE, "get file size %s\n", f->file_name); @@ -134,7 +256,7 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f) int flags = 0; int ret = 0; - struct gf_data *g = td->io_ops->data; + struct gf_data *g = td->io_ops_data; struct stat sb = { 0, }; if (td_write(td)) { @@ -164,11 +286,11 @@ 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); ret = glfs_ftruncate(g->fd, f->real_file_size); 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; @@ -189,7 +311,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); @@ -267,7 +389,7 @@ int fio_gf_open_file(struct thread_data *td, struct fio_file *f) int fio_gf_close_file(struct thread_data *td, struct fio_file *f) { int ret = 0; - struct gf_data *g = td->io_ops->data; + struct gf_data *g = td->io_ops_data; dprint(FD_FILE, "fd close %s\n", f->file_name); @@ -283,7 +405,7 @@ int fio_gf_close_file(struct thread_data *td, struct fio_file *f) int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f) { int ret = 0; - struct gf_data *g = td->io_ops->data; + struct gf_data *g = td->io_ops_data; dprint(FD_FILE, "fd unlink %s\n", f->file_name); @@ -299,7 +421,7 @@ int fio_gf_unlink_file(struct thread_data *td, struct fio_file *f) g->fd = NULL; free(g); } - td->io_ops->data = NULL; + td->io_ops_data = NULL; return ret; }