#include "include/rbd_types.h"
#include "include/rbd/librbd.h"
#include "include/rbd/librbd.hpp"
+#include "include/event_type.h"
#include "common/Thread.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
+#include <poll.h>
#include <time.h>
#include <unistd.h>
#include <iostream>
#include <boost/assign/list_of.hpp>
#include <boost/scope_exit.hpp>
+#ifdef HAVE_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
using namespace std;
#define ASSERT_PASSED(x, args...) \
printf("read completion cb called!\n");
}
+void aio_write_test_data_and_poll(rbd_image_t image, int fd, const char *test_data,
+ uint64_t off, size_t len, uint32_t iohint, bool *passed)
+{
+ rbd_completion_t comp;
+ rbd_aio_create_completion(NULL, (rbd_callback_t) simple_write_cb, &comp);
+ printf("created completion\n");
+ printf("started write\n");
+ if (iohint)
+ rbd_aio_write2(image, off, len, test_data, comp, iohint);
+ else
+ rbd_aio_write(image, off, len, test_data, comp);
+
+ struct pollfd pfd;
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ ASSERT_EQ(1, poll(&pfd, 1, -1));
+ ASSERT_TRUE(pfd.revents & POLLIN);
+
+ rbd_completion_t comps[1];
+ ASSERT_EQ(1, rbd_poll_io_events(image, comps, 1));
+ uint64_t count;
+ ASSERT_EQ(sizeof(count), read(fd, &count, sizeof(count)));
+ int r = rbd_aio_get_return_value(comps[0]);
+ ASSERT_TRUE(rbd_aio_is_complete(comps[0]));
+ printf("return value is: %d\n", r);
+ ASSERT_EQ(0, r);
+ printf("finished write\n");
+ rbd_aio_release(comps[0]);
+ *passed = true;
+}
+
void aio_write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len, uint32_t iohint, bool *passed)
{
rbd_completion_t comp;
*passed = true;
}
+void aio_read_test_data_and_poll(rbd_image_t image, int fd, const char *expected,
+ uint64_t off, size_t len, uint32_t iohint, bool *passed)
+{
+ rbd_completion_t comp;
+ char *result = (char *)malloc(len + 1);
+
+ ASSERT_NE(static_cast<char *>(NULL), result);
+ rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp);
+ printf("created completion\n");
+ printf("started read\n");
+ if (iohint)
+ rbd_aio_read2(image, off, len, result, comp, iohint);
+ else
+ rbd_aio_read(image, off, len, result, comp);
+
+ struct pollfd pfd;
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ ASSERT_EQ(1, poll(&pfd, 1, -1));
+ ASSERT_TRUE(pfd.revents & POLLIN);
+
+ rbd_completion_t comps[1];
+ ASSERT_EQ(1, rbd_poll_io_events(image, comps, 1));
+ uint64_t count;
+ ASSERT_EQ(sizeof(count), read(fd, &count, sizeof(count)));
+
+ int r = rbd_aio_get_return_value(comps[0]);
+ ASSERT_TRUE(rbd_aio_is_complete(comps[0]));
+ printf("return value is: %d\n", r);
+ ASSERT_EQ(len, static_cast<size_t>(r));
+ rbd_aio_release(comps[0]);
+ if (memcmp(result, expected, len)) {
+ printf("read: %s\nexpected: %s\n", result, expected);
+ ASSERT_EQ(0, memcmp(result, expected, len));
+ }
+ free(result);
+ *passed = true;
+}
+
void aio_read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len, uint32_t iohint, bool *passed)
{
rbd_completion_t comp;
ASSERT_EQ(0, parent.close());
}
+
+TEST_F(TestLibRBD, ImagePollIO)
+{
+#ifdef HAVE_EVENTFD
+ rados_ioctx_t ioctx;
+ rados_ioctx_create(_cluster, m_pool_name.c_str(), &ioctx);
+
+ rbd_image_t image;
+ int order = 0;
+ std::string name = get_temp_image_name();
+ uint64_t size = 2 << 20;
+ int fd = eventfd(0, EFD_NONBLOCK);
+
+ ASSERT_EQ(0, create_image(ioctx, name.c_str(), size, &order));
+ ASSERT_EQ(0, rbd_open(ioctx, name.c_str(), &image, NULL));
+
+ ASSERT_EQ(0, rbd_set_image_notification(image, fd, EVENT_SOCKET_TYPE_EVENTFD));
+
+ char test_data[TEST_IO_SIZE + 1];
+ char zero_data[TEST_IO_SIZE + 1];
+ int i;
+
+ for (i = 0; i < TEST_IO_SIZE; ++i)
+ test_data[i] = (char) (rand() % (126 - 33) + 33);
+ test_data[TEST_IO_SIZE] = '\0';
+ memset(zero_data, 0, sizeof(zero_data));
+
+ for (i = 0; i < 5; ++i)
+ ASSERT_PASSED(write_test_data, image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE, 0);
+
+ for (i = 5; i < 10; ++i)
+ ASSERT_PASSED(aio_write_test_data_and_poll, image, fd, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE, 0);
+
+ for (i = 5; i < 10; ++i)
+ ASSERT_PASSED(aio_read_test_data_and_poll, image, fd, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE, 0);
+
+ ASSERT_EQ(0, rbd_close(image));
+ rados_ioctx_destroy(ioctx);
+#endif
+}