From 84585003d025a38b91749cb0d68f6b5653d1f1a3 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 19 Oct 2006 20:26:22 +0200 Subject: [PATCH] [PATCH] Fix a bunch of bugs - engines/fio-engine-libaio.o needs to link against -laio and fio need not anymore. This caused funky crashes with libaio io engine. - Fix a few bugs in the libaio engine. - Only do sync/cleanup in do_io() if we exit without error. - ->io_ops may be NULL in reap_threads(), if the job exited. - Allocate io engine, don't reuse the dlopen() object. - Overlapping sprintf() in init_disk_util(). Signed-off-by: Jens Axboe --- Makefile | 2 +- engines/Makefile | 3 +++ engines/fio-engine-libaio.c | 8 +++++--- fio.c | 27 +++++++++++++++++---------- ioengines.c | 12 +++++++++--- stat.c | 3 ++- 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 9dc4729f..cf587ed3 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ all: depend $(PROGS) $(SCRIPTS) $(MAKE) -C engines fio: fio.o ioengines.o init.o stat.o log.o time.o md5.o crc32.o filesetup.o eta.o verify.o - $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -lpthread -laio -lm -lrt -ldl + $(CC) $(CFLAGS) -o $@ $(filter %.o,$^) -lpthread -lm -lrt -ldl clean: -rm -f *.o .depend cscope.out $(PROGS) engines/*.o diff --git a/engines/Makefile b/engines/Makefile index ce55894d..9fbc2145 100644 --- a/engines/Makefile +++ b/engines/Makefile @@ -14,6 +14,9 @@ clean: %.o: %.c $(CC) $(ALL_CFLAGS) -o $*.o $< +fio-engine-libaio.o: fio-engine-libaio.c + $(CC) $(ALL_CFLAGS) -laio -o $*.o $< + ifneq ($(wildcard .depend),) include .depend endif diff --git a/engines/fio-engine-libaio.c b/engines/fio-engine-libaio.c index c3fefdac..57daf1b6 100644 --- a/engines/fio-engine-libaio.c +++ b/engines/fio-engine-libaio.c @@ -55,7 +55,7 @@ static int fio_libaio_getevents(struct thread_data *td, int min, int max, continue; } else if (r == -EINTR) continue; - else + else if (r != 0) break; } while (1); @@ -72,7 +72,7 @@ static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u) ret = io_submit(ld->aio_ctx, 1, &iocb); if (ret == 1) return 0; - else if (ret == -EAGAIN) + else if (ret == -EAGAIN || !ret) usleep(100); else if (ret == -EINTR) continue; @@ -80,8 +80,9 @@ static int fio_libaio_queue(struct thread_data *td, struct io_u *io_u) break; } while (1); - return (int) ret; + assert(ret); + return (int) ret; } static int fio_libaio_cancel(struct thread_data *td, struct io_u *io_u) @@ -116,6 +117,7 @@ static int fio_libaio_init(struct thread_data *td) } ld->aio_events = malloc(td->iodepth * sizeof(struct io_event)); + memset(ld->aio_events, 0, td->iodepth * sizeof(struct io_event)); td->io_ops->data = ld; return 0; } diff --git a/fio.c b/fio.c index 28be099a..9a1da292 100644 --- a/fio.c +++ b/fio.c @@ -688,14 +688,14 @@ static void do_io(struct thread_data *td) struct timeval s, e; unsigned long usec; struct fio_file *f; - int i; + int i, ret = 0; td_set_runstate(td, TD_RUNNING); while (td->this_io_bytes[td->ddir] < td->io_size) { struct timespec ts = { .tv_sec = 0, .tv_nsec = 0}; struct timespec *timeout; - int ret, min_evts = 0; + int min_evts = 0; struct io_u *io_u; if (td->terminate) @@ -728,9 +728,10 @@ static void do_io(struct thread_data *td) min_evts = 1; } + ret = td_io_getevents(td, min_evts, td->cur_depth, timeout); if (ret < 0) { - td_verror(td, ret); + td_verror(td, -ret); break; } else if (!ret) continue; @@ -768,13 +769,15 @@ static void do_io(struct thread_data *td) td_io_sync(td, f); } - if (td->cur_depth) - cleanup_pending_aio(td); + if (!ret) { + if (td->cur_depth) + cleanup_pending_aio(td); - if (should_fsync(td) && td->end_fsync) { - td_set_runstate(td, TD_FSYNCING); - for_each_file(td, f, i) - td_io_sync(td, f); + if (should_fsync(td) && td->end_fsync) { + td_set_runstate(td, TD_FSYNCING); + for_each_file(td, f, i) + td_io_sync(td, f); + } } } @@ -1095,7 +1098,11 @@ static void reap_threads(int *nr_running, int *t_rate, int *m_rate) for (i = 0, cputhreads = 0; i < thread_number; i++) { struct thread_data *td = &threads[i]; - if (td->io_ops->flags & FIO_CPUIO) + /* + * ->io_ops is NULL for a thread that has closed its + * io engine + */ + if (td->io_ops && td->io_ops->flags & FIO_CPUIO) cputhreads++; if (td->runstate != TD_EXITED) diff --git a/ioengines.c b/ioengines.c index 82b7ec3f..abc38530 100644 --- a/ioengines.c +++ b/ioengines.c @@ -20,7 +20,7 @@ struct ioengine_ops *load_ioengine(struct thread_data *td, char *name) { char engine[16], engine_lib[256]; - struct ioengine_ops *ops; + struct ioengine_ops *ops, *ret; void *dlhandle; strcpy(engine, name); @@ -52,8 +52,12 @@ struct ioengine_ops *load_ioengine(struct thread_data *td, char *name) return NULL; } - ops->dlhandle = dlhandle; - return ops; + ret = malloc(sizeof(*ret)); + memcpy(ret, ops, sizeof(*ret)); + ret->data = NULL; + ret->dlhandle = dlhandle; + + return ret; } void close_ioengine(struct thread_data *td) @@ -62,4 +66,6 @@ void close_ioengine(struct thread_data *td) td->io_ops->cleanup(td); dlclose(td->io_ops->dlhandle); + free(td->io_ops); + td->io_ops = NULL; } diff --git a/stat.c b/stat.c index e43a3361..4ba8f193 100644 --- a/stat.c +++ b/stat.c @@ -239,7 +239,8 @@ void init_disk_util(struct thread_data *td) log_err("unknown sysfs layout\n"); return; } - sprintf(foo, "%s", p); + strcpy(tmp, p); + sprintf(foo, "%s", tmp); } td->sysfs_root = strdup(foo); -- 2.25.1