From: dparmar18 Date: Tue, 26 Jul 2022 11:33:47 +0000 (+0530) Subject: qa: test sending a dummy op to check if mds crashes X-Git-Tag: v16.2.11~81^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=498ea2ec15e0fb622521e9e583cbaa2208e3cb51;p=ceph.git qa: test sending a dummy op to check if mds crashes Signed-off-by: Dhairya Parmar (cherry picked from commit 62756e961f63b7478cc0981936914008ec5af65e) --- diff --git a/src/client/Client.h b/src/client/Client.h index cda4abaf289e..269cb13fae76 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -901,6 +901,7 @@ public: bool _collect_and_send_global_metrics; protected: + std::list waiting_for_reclaim; /* Flags for check_caps() */ static const unsigned CHECK_CAPS_NODELAY = 0x1; static const unsigned CHECK_CAPS_SYNCHRONOUS = 0x2; @@ -1562,7 +1563,6 @@ private: uint64_t retries_on_invalidate = 0; // state reclaim - std::list waiting_for_reclaim; int reclaim_errno = 0; epoch_t reclaim_osd_epoch = 0; entity_addrvec_t reclaim_target_addrs; diff --git a/src/common/ceph_strings.cc b/src/common/ceph_strings.cc index 48148a5b78f4..da88426321d5 100644 --- a/src/common/ceph_strings.cc +++ b/src/common/ceph_strings.cc @@ -275,6 +275,7 @@ const char *ceph_mds_op_name(int op) case CEPH_MDS_OP_LOOKUPINO: return "lookupino"; case CEPH_MDS_OP_LOOKUPNAME: return "lookupname"; case CEPH_MDS_OP_GETATTR: return "getattr"; + case CEPH_MDS_OP_DUMMY: return "dummy"; case CEPH_MDS_OP_SETXATTR: return "setxattr"; case CEPH_MDS_OP_SETATTR: return "setattr"; case CEPH_MDS_OP_RMXATTR: return "rmxattr"; diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index aed669a7f450..491931a8b278 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -388,6 +388,7 @@ enum { CEPH_MDS_OP_LOOKUPINO = 0x00104, CEPH_MDS_OP_LOOKUPNAME = 0x00105, CEPH_MDS_OP_GETVXATTR = 0x00106, + CEPH_MDS_OP_DUMMY = 0x00107, CEPH_MDS_OP_SETXATTR = 0x01105, CEPH_MDS_OP_RMXATTR = 0x01106, diff --git a/src/test/client/CMakeLists.txt b/src/test/client/CMakeLists.txt index 66d403c7e9e5..1937bdd0b554 100644 --- a/src/test/client/CMakeLists.txt +++ b/src/test/client/CMakeLists.txt @@ -2,6 +2,7 @@ if(${WITH_CEPHFS}) add_executable(ceph_test_client main.cc alternate_name.cc + ops.cc ) target_link_libraries(ceph_test_client client diff --git a/src/test/client/TestClient.h b/src/test/client/TestClient.h index e1c0199b3105..bf3b274af603 100644 --- a/src/test/client/TestClient.h +++ b/src/test/client/TestClient.h @@ -20,8 +20,73 @@ #include "msg/Messenger.h" #include "mon/MonClient.h" #include "osdc/ObjectCacher.h" - +#include "client/MetaRequest.h" #include "client/Client.h" +#include "messages/MClientReclaim.h" +#include "messages/MClientSession.h" +#include "common/async/blocked_completion.h" + +#define dout_subsys ceph_subsys_client + +namespace bs = boost::system; +namespace ca = ceph::async; + +class ClientScaffold : public Client { +public: + ClientScaffold(Messenger *m, MonClient *mc, Objecter *objecter_) : Client(m, mc, objecter_) {} + virtual ~ClientScaffold() + { } + int check_dummy_op(const UserPerm& perms){ + RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); + if (!mref_reader.is_state_satisfied()) { + return -CEPHFS_ENOTCONN; + } + std::scoped_lock l(client_lock); + MetaRequest *req = new MetaRequest(CEPH_MDS_OP_DUMMY); + int res = make_request(req, perms); + ldout(cct, 10) << __func__ << " result=" << res << dendl; + return res; + } + int send_unknown_session_op(int op) { + RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); + if (!mref_reader.is_state_satisfied()) { + return -CEPHFS_ENOTCONN; + } + std::scoped_lock l(client_lock); + auto session = _get_or_open_mds_session(0); + auto msg = make_message(op, session->seq); + int res = session->con->send_message2(std::move(msg)); + ldout(cct, 10) << __func__ << " result=" << res << dendl; + return res; + } + bool check_client_blocklisted() { + RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); + if (!mref_reader.is_state_satisfied()) { + return -CEPHFS_ENOTCONN; + } + std::scoped_lock l(client_lock); + bs::error_code ec; + ldout(cct, 20) << __func__ << ": waiting for latest osdmap" << dendl; + objecter->wait_for_latest_osdmap(ca::use_blocked[ec]); + ldout(cct, 20) << __func__ << ": got latest osdmap: " << ec << dendl; + const auto myaddrs = messenger->get_myaddrs(); + return objecter->with_osdmap([&](const OSDMap& o) {return o.is_blocklisted(myaddrs);}); + } + bool check_unknown_reclaim_flag(uint32_t flag) { + RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); + if (!mref_reader.is_state_satisfied()) { + return -CEPHFS_ENOTCONN; + } + std::scoped_lock l(client_lock); + char uuid[256]; + sprintf(uuid, "unknownreclaimflag:%x", getpid()); + auto session = _get_or_open_mds_session(0); + auto m = make_message(uuid, flag); + ceph_assert(session->con->send_message2(std::move(m)) == 0); + wait_on_list(waiting_for_reclaim); + return session->reclaim_state == MetaSession::RECLAIM_FAIL ? true : false; + } +}; class TestClient : public ::testing::Test { public: @@ -53,7 +118,7 @@ public: messenger->add_dispatcher_tail(objecter); objecter->start(); - client = new Client(messenger, mc, objecter); + client = new ClientScaffold(messenger, mc, objecter); client->init(); client->mount("/", myperm, true); } @@ -81,5 +146,5 @@ protected: MonClient* mc = nullptr; Messenger* messenger = nullptr; Objecter* objecter = nullptr; - Client* client = nullptr; + ClientScaffold* client = nullptr; }; diff --git a/src/test/client/ops.cc b/src/test/client/ops.cc new file mode 100644 index 000000000000..1cb78625e438 --- /dev/null +++ b/src/test/client/ops.cc @@ -0,0 +1,39 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2022 Red Hat + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include +#include +#include "TestClient.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" +#include "gmock/gmock-matchers.h" +#include "gmock/gmock-more-matchers.h" + +TEST_F(TestClient, CheckDummyOP) { + ASSERT_EQ(client->check_dummy_op(myperm), -EOPNOTSUPP); +} + +TEST_F(TestClient, CheckUnknownSessionOp) { + ASSERT_EQ(client->send_unknown_session_op(-1), 0); + sleep(5); + ASSERT_EQ(client->check_client_blocklisted(), true); +} + +TEST_F(TestClient, CheckZeroReclaimFlag) { + ASSERT_EQ(client->check_unknown_reclaim_flag(0), true); +} +TEST_F(TestClient, CheckUnknownReclaimFlag) { + ASSERT_EQ(client->check_unknown_reclaim_flag(-1 & ~MClientReclaim::FLAG_FINISH), true); +}