X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=engines%2Frbd.c;h=268b6ebdffad2b71e4da565ed90867e76f90947a;hp=5b51a39c9e8f3595d733a88a1d77cc19ce89aa8f;hb=HEAD;hpb=ef2f4a50c25b3315d8825eb5e6fdfd6d57a47b74 diff --git a/engines/rbd.c b/engines/rbd.c index 5b51a39c..2f25889a 100644 --- a/engines/rbd.c +++ b/engines/rbd.c @@ -9,9 +9,6 @@ #include "../fio.h" #include "../optgroup.h" -#ifdef CONFIG_RBD_BLKIN -#include -#endif #ifdef CONFIG_RBD_POLL /* add for poll */ @@ -24,9 +21,6 @@ struct fio_rbd_iou { rbd_completion_t completion; int io_seen; int io_complete; -#ifdef CONFIG_RBD_BLKIN - struct blkin_trace_info info; -#endif }; struct rbd_data { @@ -146,7 +140,7 @@ static bool _fio_rbd_setup_poll(struct rbd_data *rbd) int r; /* add for rbd poll */ - rbd->fd = eventfd(0, EFD_NONBLOCK); + rbd->fd = eventfd(0, EFD_SEMAPHORE); if (rbd->fd < 0) { log_err("eventfd failed.\n"); return false; @@ -179,7 +173,7 @@ static int _fio_rbd_connect(struct thread_data *td) char *client_name = NULL; /* - * If we specify cluser name, the rados_create2 + * If we specify cluster name, the rados_create2 * will not assume 'client.'. name is considered * as a full type.id namestr */ @@ -206,6 +200,14 @@ static int _fio_rbd_connect(struct thread_data *td) log_err("rados_create failed.\n"); goto failed_early; } + if (o->pool_name == NULL) { + log_err("rbd pool name must be provided.\n"); + goto failed_early; + } + if (!o->rbd_name) { + log_err("rbdname must be provided.\n"); + goto failed_early; + } r = rados_conf_read_file(rbd->cluster, NULL); if (r < 0) { @@ -225,12 +227,30 @@ static int _fio_rbd_connect(struct thread_data *td) goto failed_shutdown; } + if (td->o.odirect) { + r = rados_conf_set(rbd->cluster, "rbd_cache", "false"); + if (r < 0) { + log_info("failed to disable RBD in-memory cache\n"); + } + } + r = rbd_open(rbd->io_ctx, o->rbd_name, &rbd->image, NULL /*snap */ ); if (r < 0) { log_err("rbd_open failed.\n"); goto failed_open; } + if (!td->o.odirect) { + /* + * ensure cache enables writeback/around mode unless explicitly + * configured for writethrough mode + */ + r = rbd_flush(rbd->image); + if (r < 0) { + log_info("rbd: failed to issue initial flush\n"); + } + } + if (!_fio_rbd_setup_poll(rbd)) goto failed_poll; @@ -322,12 +342,14 @@ static inline int fri_check_complete(struct rbd_data *rbd, struct io_u *io_u, return 0; } +#ifndef CONFIG_RBD_POLL static inline int rbd_io_u_seen(struct io_u *io_u) { struct fio_rbd_iou *fri = io_u->engine_data; return fri->io_seen; } +#endif static void rbd_io_u_wait_complete(struct io_u *io_u) { @@ -366,25 +388,37 @@ static int rbd_iter_events(struct thread_data *td, unsigned int *events, int event_num = 0; struct fio_rbd_iou *fri = NULL; rbd_completion_t comps[min_evts]; + uint64_t counter; + bool completed; struct pollfd pfd; pfd.fd = rbd->fd; pfd.events = POLLIN; - ret = poll(&pfd, 1, -1); + ret = poll(&pfd, 1, wait ? -1 : 0); if (ret <= 0) return 0; - - assert(pfd.revents & POLLIN); + if (!(pfd.revents & POLLIN)) + return 0; event_num = rbd_poll_io_events(rbd->image, comps, min_evts); for (i = 0; i < event_num; i++) { fri = rbd_aio_get_arg(comps[i]); io_u = fri->io_u; + + /* best effort to decrement the semaphore */ + ret = read(rbd->fd, &counter, sizeof(counter)); + if (ret <= 0) + log_err("rbd_iter_events failed to decrement semaphore.\n"); + + completed = fri_check_complete(rbd, io_u, events); + assert(completed); + + this_events++; + } #else io_u_qiter(&td->io_u_all, io_u, i) { -#endif if (!(io_u->flags & IO_U_F_FLIGHT)) continue; if (rbd_io_u_seen(io_u)) @@ -395,6 +429,7 @@ static int rbd_iter_events(struct thread_data *td, unsigned int *events, else if (wait) rbd->sort_events[sidx++] = io_u; } +#endif if (!wait || !sidx) return this_events; @@ -455,7 +490,8 @@ static int fio_rbd_getevents(struct thread_data *td, unsigned int min, return events; } -static int fio_rbd_queue(struct thread_data *td, struct io_u *io_u) +static enum fio_q_status fio_rbd_queue(struct thread_data *td, + struct io_u *io_u) { struct rbd_data *rbd = td->io_ops_data; struct fio_rbd_iou *fri = io_u->engine_data; @@ -474,28 +510,16 @@ static int fio_rbd_queue(struct thread_data *td, struct io_u *io_u) } if (io_u->ddir == DDIR_WRITE) { -#ifdef CONFIG_RBD_BLKIN - blkin_init_trace_info(&fri->info); - r = rbd_aio_write_traced(rbd->image, io_u->offset, io_u->xfer_buflen, - io_u->xfer_buf, fri->completion, &fri->info); -#else r = rbd_aio_write(rbd->image, io_u->offset, io_u->xfer_buflen, io_u->xfer_buf, fri->completion); -#endif if (r < 0) { log_err("rbd_aio_write failed.\n"); goto failed_comp; } } else if (io_u->ddir == DDIR_READ) { -#ifdef CONFIG_RBD_BLKIN - blkin_init_trace_info(&fri->info); - r = rbd_aio_read_traced(rbd->image, io_u->offset, io_u->xfer_buflen, - io_u->xfer_buf, fri->completion, &fri->info); -#else r = rbd_aio_read(rbd->image, io_u->offset, io_u->xfer_buflen, io_u->xfer_buf, fri->completion); -#endif if (r < 0) { log_err("rbd_aio_read failed.\n"); @@ -605,11 +629,11 @@ static int fio_rbd_setup(struct thread_data *td) goto cleanup; } - dprint(FD_IO, "rbd-engine: image size: %lu\n", info.size); + dprint(FD_IO, "rbd-engine: image size: %" PRIu64 "\n", info.size); /* taken from "net" engine. Pretend we deal with files, * even if we do not have any ideas about files. - * The size of the RBD is set instead of a artificial file. + * The size of the RBD is set instead of an artificial file. */ if (!td->files_index) { add_file(td, td->o.filename ? : "rbd", 0, 0); @@ -662,7 +686,7 @@ static int fio_rbd_io_u_init(struct thread_data *td, struct io_u *io_u) return 0; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name = "rbd", .version = FIO_IOOPS_VERSION, .setup = fio_rbd_setup,