[PATCH] Fix a bunch of bugs
authorJens Axboe <jens.axboe@oracle.com>
Thu, 19 Oct 2006 18:26:22 +0000 (20:26 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 19 Oct 2006 18:26:22 +0000 (20:26 +0200)
- 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 <jens.axboe@oracle.com>
Makefile
engines/Makefile
engines/fio-engine-libaio.c
fio.c
ioengines.c
stat.c

index 9dc4729f75e6626b5b0361a988ba4ef25cf78011..cf587ed3704f7660b41b001b31c3c19f00f6a86e 100644 (file)
--- 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
index ce55894d171980f6ae62fde98e90cf8d391b1b72..9fbc21456194362326b870b57dd6032465e01fec 100644 (file)
@@ -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
index c3fefdaccda7ea97cf660c0db4007b158807310e..57daf1b6b49a5c8b2933eac060b025318594803e 100644 (file)
@@ -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 28be099ab71d432174e1fd1560afd1bf4e596c00..9a1da292f9d5b5ab580948955f36794f921ecd7a 100644 (file)
--- 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)
index 82b7ec3f6f25957832e2f56fc2de83829a519aeb..abc385303d86c466ba34ed261a5624e2546e03de 100644 (file)
@@ -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 e43a336108f0f78c18dcc28d5baf6cd1859b576c..4ba8f193967e8ce51d8134ba7e5b42bc908de1a9 100644 (file)
--- 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);