- 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>
$(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
$(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
clean:
-rm -f *.o .depend cscope.out $(PROGS) engines/*.o
%.o: %.c
$(CC) $(ALL_CFLAGS) -o $*.o $<
%.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
ifneq ($(wildcard .depend),)
include .depend
endif
continue;
} else if (r == -EINTR)
continue;
continue;
} else if (r == -EINTR)
continue;
ret = io_submit(ld->aio_ctx, 1, &iocb);
if (ret == 1)
return 0;
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;
usleep(100);
else if (ret == -EINTR)
continue;
}
static int fio_libaio_cancel(struct thread_data *td, struct io_u *io_u)
}
static int fio_libaio_cancel(struct thread_data *td, struct io_u *io_u)
}
ld->aio_events = malloc(td->iodepth * sizeof(struct io_event));
}
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;
}
td->io_ops->data = ld;
return 0;
}
struct timeval s, e;
unsigned long usec;
struct fio_file *f;
struct timeval s, e;
unsigned long usec;
struct fio_file *f;
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;
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;
struct io_u *io_u;
if (td->terminate)
struct io_u *io_u;
if (td->terminate)
ret = td_io_getevents(td, min_evts, td->cur_depth, timeout);
if (ret < 0) {
ret = td_io_getevents(td, min_evts, td->cur_depth, timeout);
if (ret < 0) {
break;
} else if (!ret)
continue;
break;
} else if (!ret)
continue;
- 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);
+ }
for (i = 0, cputhreads = 0; i < thread_number; i++) {
struct thread_data *td = &threads[i];
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)
cputhreads++;
if (td->runstate != TD_EXITED)
struct ioengine_ops *load_ioengine(struct thread_data *td, char *name)
{
char engine[16], engine_lib[256];
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);
void *dlhandle;
strcpy(engine, name);
- 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)
}
void close_ioengine(struct thread_data *td)
td->io_ops->cleanup(td);
dlclose(td->io_ops->dlhandle);
td->io_ops->cleanup(td);
dlclose(td->io_ops->dlhandle);
+ free(td->io_ops);
+ td->io_ops = NULL;
log_err("unknown sysfs layout\n");
return;
}
log_err("unknown sysfs layout\n");
return;
}
+ strcpy(tmp, p);
+ sprintf(foo, "%s", tmp);
}
td->sysfs_root = strdup(foo);
}
td->sysfs_root = strdup(foo);