From c43274f2bb0d5c250e8c6668fc58a50aeb7919c1 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Tue, 3 Jan 2017 14:20:05 +0800 Subject: [PATCH] ceph_test_rados_api_watch_notify: move global variables into test class so the class instances using mempool are destructed before the mempools are destroyed. this avoids the "invalid read" issue reported by valgrind. Fixes: http://tracker.ceph.com/issues/18395 Signed-off-by: Kefu Chai --- src/test/librados/watch_notify.cc | 108 ++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 35 deletions(-) diff --git a/src/test/librados/watch_notify.cc b/src/test/librados/watch_notify.cc index 07370c974106d..5fe63c05e42d2 100644 --- a/src/test/librados/watch_notify.cc +++ b/src/test/librados/watch_notify.cc @@ -14,8 +14,6 @@ using namespace librados; -typedef RadosTest LibRadosWatchNotify; -typedef RadosTestParamPP LibRadosWatchNotifyPP; typedef RadosTestEC LibRadosWatchNotifyEC; typedef RadosTestECPP LibRadosWatchNotifyECPP; @@ -40,14 +38,27 @@ public: } }; -// notify 2 -bufferlist notify_bl; -std::set notify_cookies; -rados_ioctx_t notify_io; -const char *notify_oid = 0; -int notify_err = 0; +class LibRadosWatchNotify : public RadosTest +{ +protected: + // notify 2 + bufferlist notify_bl; + std::set notify_cookies; + rados_ioctx_t notify_io; + const char *notify_oid = nullptr; + int notify_err = 0; + + static void watch_notify2_test_cb(void *arg, + uint64_t notify_id, + uint64_t cookie, + uint64_t notifier_gid, + void *data, + size_t data_len); + static void watch_notify2_test_errcb(void *arg, uint64_t cookie, int err); +}; + -static void watch_notify2_test_cb(void *arg, +void LibRadosWatchNotify::watch_notify2_test_cb(void *arg, uint64_t notify_id, uint64_t cookie, uint64_t notifier_gid, @@ -57,43 +68,70 @@ static void watch_notify2_test_cb(void *arg, std::cout << __func__ << " from " << notifier_gid << " notify_id " << notify_id << " cookie " << cookie << std::endl; assert(notifier_gid > 0); - notify_cookies.insert(cookie); - notify_bl.clear(); - notify_bl.append((char*)data, data_len); + auto thiz = reinterpret_cast(arg); + assert(thiz); + thiz->notify_cookies.insert(cookie); + thiz->notify_bl.clear(); + thiz->notify_bl.append((char*)data, data_len); if (notify_sleep) sleep(notify_sleep); - rados_notify_ack(notify_io, notify_oid, notify_id, cookie, "reply", 5); + rados_notify_ack(thiz->notify_io, thiz->notify_oid, notify_id, cookie, + "reply", 5); } -static void watch_notify2_test_errcb(void *arg, uint64_t cookie, int err) +void LibRadosWatchNotify::watch_notify2_test_errcb(void *arg, + uint64_t cookie, + int err) { std::cout << __func__ << " cookie " << cookie << " err " << err << std::endl; assert(cookie > 1000); - notify_err = err; + auto thiz = reinterpret_cast(arg); + assert(thiz); + thiz->notify_err = err; } +class WatchNotifyTestCtx2; +class LibRadosWatchNotifyPP : public RadosTestParamPP +{ +protected: + bufferlist notify_bl; + std::set notify_cookies; + rados_ioctx_t notify_io; + const char *notify_oid = nullptr; + int notify_err = 0; + + friend class WatchNotifyTestCtx2; +}; + IoCtx *notify_ioctx; + class WatchNotifyTestCtx2 : public WatchCtx2 { + LibRadosWatchNotifyPP *notify; + public: + WatchNotifyTestCtx2(LibRadosWatchNotifyPP *notify) + : notify(notify) + {} + void handle_notify(uint64_t notify_id, uint64_t cookie, uint64_t notifier_gid, bufferlist& bl) { std::cout << __func__ << " cookie " << cookie << " notify_id " << notify_id << " notifier_gid " << notifier_gid << std::endl; - notify_bl = bl; - notify_cookies.insert(cookie); + notify->notify_bl = bl; + notify->notify_cookies.insert(cookie); bufferlist reply; reply.append("reply", 5); if (notify_sleep) sleep(notify_sleep); - notify_ioctx->notify_ack(notify_oid, notify_id, cookie, reply); + notify_ioctx->notify_ack(notify->notify_oid, notify_id, cookie, reply); } void handle_error(uint64_t cookie, int err) { std::cout << __func__ << " cookie " << cookie << " err " << err << std::endl; assert(cookie > 1000); - notify_err = err; + notify->notify_err = err; } }; @@ -233,7 +271,7 @@ TEST_F(LibRadosWatchNotify, Watch2Delete) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_EQ(0, rados_remove(ioctx, notify_oid)); int left = 300; std::cout << "waiting up to " << left << " for disconnect notification ..." @@ -260,7 +298,7 @@ TEST_F(LibRadosWatchNotify, AioWatchDelete) { uint64_t handle; ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp)); rados_aio_watch(ioctx, notify_oid, comp, &handle, - watch_notify2_test_cb, watch_notify2_test_errcb, NULL); + watch_notify2_test_cb, watch_notify2_test_errcb, this); ASSERT_EQ(0, rados_aio_wait_for_complete(comp)); ASSERT_EQ(0, rados_aio_get_return_value(comp)); rados_aio_release(comp); @@ -294,7 +332,7 @@ TEST_F(LibRadosWatchNotify, Watch2Timeout) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); int age = rados_watch_check(ioctx, handle); time_t age_bound = time(0) + 1 - start; ASSERT_LT(age, age_bound * 1000); @@ -338,7 +376,7 @@ TEST_F(LibRadosWatchNotify, Watch2Timeout) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_GT(rados_watch_check(ioctx, handle), 0); // and now a notify will work. @@ -378,7 +416,7 @@ TEST_F(LibRadosWatchNotify, WatchNotify2) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_GT(rados_watch_check(ioctx, handle), 0); char *reply_buf = 0; size_t reply_buf_len; @@ -424,7 +462,7 @@ TEST_F(LibRadosWatchNotify, AioWatchNotify2) { uint64_t handle; ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp)); rados_aio_watch(ioctx, notify_oid, comp, &handle, - watch_notify2_test_cb, watch_notify2_test_errcb, NULL); + watch_notify2_test_cb, watch_notify2_test_errcb, this); ASSERT_EQ(0, rados_aio_wait_for_complete(comp)); ASSERT_EQ(0, rados_aio_get_return_value(comp)); rados_aio_release(comp); @@ -477,7 +515,7 @@ TEST_F(LibRadosWatchNotify, AioNotify) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_GT(rados_watch_check(ioctx, handle), 0); char *reply_buf = 0; size_t reply_buf_len; @@ -529,7 +567,7 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify2) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0)); uint64_t handle; - WatchNotifyTestCtx2 ctx; + WatchNotifyTestCtx2 ctx(this); ASSERT_EQ(0, ioctx.watch2(notify_oid, &handle, &ctx)); ASSERT_GT(ioctx.watch_check(handle), 0); std::list watches; @@ -563,7 +601,7 @@ TEST_P(LibRadosWatchNotifyPP, AioWatchNotify2) { ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0)); uint64_t handle; - WatchNotifyTestCtx2 ctx; + WatchNotifyTestCtx2 ctx(this); librados::AioCompletion *comp = cluster.aio_create_completion(); ASSERT_EQ(0, ioctx.aio_watch(notify_oid, comp, &handle, &ctx)); ASSERT_EQ(0, comp->wait_for_complete()); @@ -606,7 +644,7 @@ TEST_P(LibRadosWatchNotifyPP, AioNotify) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0)); uint64_t handle; - WatchNotifyTestCtx2 ctx; + WatchNotifyTestCtx2 ctx(this); ASSERT_EQ(0, ioctx.watch2(notify_oid, &handle, &ctx)); ASSERT_GT(ioctx.watch_check(handle), 0); std::list watches; @@ -646,11 +684,11 @@ TEST_F(LibRadosWatchNotify, WatchNotify2Multi) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle1, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle2, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_GT(rados_watch_check(ioctx, handle1), 0); ASSERT_GT(rados_watch_check(ioctx, handle2), 0); ASSERT_NE(handle1, handle2); @@ -694,7 +732,7 @@ TEST_F(LibRadosWatchNotify, WatchNotify2Timeout) { ASSERT_EQ(0, rados_watch2(ioctx, notify_oid, &handle, watch_notify2_test_cb, - watch_notify2_test_errcb, NULL)); + watch_notify2_test_errcb, this)); ASSERT_GT(rados_watch_check(ioctx, handle), 0); char *reply_buf = 0; size_t reply_buf_len; @@ -746,7 +784,7 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify2Timeout) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0)); uint64_t handle; - WatchNotifyTestCtx2 ctx; + WatchNotifyTestCtx2 ctx(this); ASSERT_EQ(0, ioctx.watch2(notify_oid, &handle, &ctx)); ASSERT_GT(ioctx.watch_check(handle), 0); std::list watches; @@ -781,7 +819,7 @@ TEST_P(LibRadosWatchNotifyPP, WatchNotify3) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write(notify_oid, bl1, sizeof(buf), 0)); uint64_t handle; - WatchNotifyTestCtx2 ctx; + WatchNotifyTestCtx2 ctx(this); ASSERT_EQ(0, ioctx.watch3(notify_oid, &handle, &ctx, timeout)); ASSERT_GT(ioctx.watch_check(handle), 0); std::list watches; @@ -823,7 +861,7 @@ TEST_F(LibRadosWatchNotify, AioWatchDelete2) { uint64_t handle; ASSERT_EQ(0, rados_aio_create_completion(NULL, NULL, NULL, &comp)); rados_aio_watch2(ioctx, notify_oid, comp, &handle, - watch_notify2_test_cb, watch_notify2_test_errcb, timeout, NULL); + watch_notify2_test_cb, watch_notify2_test_errcb, timeout, this); ASSERT_EQ(0, rados_aio_wait_for_complete(comp)); ASSERT_EQ(0, rados_aio_get_return_value(comp)); rados_aio_release(comp); -- 2.39.5