]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
qa: test sending a dummy op to check if mds crashes 48253/head
authordparmar18 <dparmar@redhat.com>
Tue, 26 Jul 2022 11:33:47 +0000 (17:03 +0530)
committerdparmar18 <dparmar@redhat.com>
Mon, 26 Sep 2022 12:03:34 +0000 (17:33 +0530)
Signed-off-by: Dhairya Parmar <dparmar@redhat.com>
(cherry picked from commit 62756e961f63b7478cc0981936914008ec5af65e)

src/client/Client.h
src/common/ceph_strings.cc
src/include/ceph_fs.h
src/test/client/CMakeLists.txt
src/test/client/TestClient.h
src/test/client/ops.cc [new file with mode: 0644]

index cda4abaf289eed0fa45cfd8dbc23054cc5431cb3..269cb13fae768ff71991457ad7cf46d459094f54 100644 (file)
@@ -901,6 +901,7 @@ public:
   bool _collect_and_send_global_metrics;
 
 protected:
+  std::list<ceph::condition_variable*> 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<ceph::condition_variable*> waiting_for_reclaim;
   int reclaim_errno = 0;
   epoch_t reclaim_osd_epoch = 0;
   entity_addrvec_t reclaim_target_addrs;
index 48148a5b78f44e56329d494b739102402fbe4ea8..da88426321d54d88e6c92e7ca22d01a9e5d530bf 100644 (file)
@@ -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";
index aed669a7f4506bb51ebe22c541fac20efc22aa3e..491931a8b2784da09ffac50955f1a79603e1c87a 100644 (file)
@@ -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,
index 66d403c7e9e5361bd18485cf20d004ec011a533f..1937bdd0b55423d63adcaa39dfeea3f6e39fedbb 100644 (file)
@@ -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
index e1c0199b3105b70603eb502285e000db60ece143..bf3b274af603ebdfdd4d666f0fb7bcef155a4571 100644 (file)
 #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<MClientSession>(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<MClientReclaim>(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 (file)
index 0000000..1cb7862
--- /dev/null
@@ -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 <iostream>
+#include <errno.h>
+#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);
+}