]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: flush and invalidate cache via admin socket
authorMykola Golub <mgolub@mirantis.com>
Tue, 3 Nov 2015 06:55:23 +0000 (08:55 +0200)
committerMykola Golub <mgolub@mirantis.com>
Mon, 9 Nov 2015 14:14:11 +0000 (16:14 +0200)
Fixes: #2468
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/LibrbdAdminSocketHook.cc [new file with mode: 0644]
src/librbd/LibrbdAdminSocketHook.h [new file with mode: 0644]
src/librbd/Makefile.am

index ecb246ca39ada0d4412e84ec40de0aa8e26147ca..50c0b0295edd86a55f03a4366bc82da48eee0d2a 100644 (file)
@@ -15,6 +15,7 @@
 #include "librbd/internal.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/ImageWatcher.h"
+#include "librbd/LibrbdAdminSocketHook.h"
 #include "librbd/ObjectMap.h"
 
 #include <boost/bind.hpp>
@@ -84,7 +85,8 @@ public:
       object_cacher(NULL), writeback_handler(NULL), object_set(NULL),
       readahead(),
       total_bytes_read(0), copyup_finisher(NULL),
-      object_map(*this), aio_work_queue(NULL), op_work_queue(NULL)
+      object_map(*this), aio_work_queue(NULL), op_work_queue(NULL),
+      asok_hook(new LibrbdAdminSocketHook(this))
   {
     md_ctx.dup(p);
     data_ctx.dup(p);
@@ -127,6 +129,8 @@ public:
 
     delete op_work_queue;
     delete aio_work_queue;
+
+    delete asok_hook;
   }
 
   int ImageCtx::init() {
@@ -688,6 +692,7 @@ public:
     C_SaferCond ctx;
     invalidate_cache(&ctx);
     result = ctx.wait();
+    ldout(cct, 20) << "finished invalidating cache" << dendl;
 
     if (result && purge_on_error) {
       cache_lock.Lock();
index 3c7f170b5843943c81b5e6e2e9d276871fb4eb64..bfddf80169736873576d0020a7e98c364e815738 100644 (file)
@@ -41,6 +41,7 @@ namespace librbd {
   template <typename ImageCtxT> class AsyncRequest;
   class AsyncResizeRequest;
   class CopyupRequest;
+  class LibrbdAdminSocketHook;
   class ImageWatcher;
 
   struct ImageCtx {
@@ -158,6 +159,9 @@ namespace librbd {
     uint32_t blacklist_expire_seconds;
     uint32_t request_timed_out_seconds;
     bool enable_alloc_hint;
+
+    LibrbdAdminSocketHook *asok_hook;
+
     static bool _filter_metadata_confs(const string &prefix, std::map<string, bool> &configs,
                                        map<string, bufferlist> &pairs, map<string, bufferlist> *res);
 
diff --git a/src/librbd/LibrbdAdminSocketHook.cc b/src/librbd/LibrbdAdminSocketHook.cc
new file mode 100644 (file)
index 0000000..ca7d64a
--- /dev/null
@@ -0,0 +1,97 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/errno.h"
+
+#include "librbd/ImageCtx.h"
+#include "librbd/LibrbdAdminSocketHook.h"
+#include "librbd/internal.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbdadminsocket: "
+
+namespace librbd {
+
+class LibrbdAdminSocketCommand {
+public:
+  virtual ~LibrbdAdminSocketCommand() {}
+  virtual bool call(stringstream *ss) = 0;
+};
+
+class FlushCacheCommand : public LibrbdAdminSocketCommand {
+public:
+  FlushCacheCommand(ImageCtx *ictx) : ictx(ictx) {}
+
+  bool call(stringstream *ss) {
+    int r = flush(ictx);
+    if (r < 0) {
+      *ss << "flush: " << cpp_strerror(r);
+      return false;
+    }
+    return true;
+  }
+
+private:
+  ImageCtx *ictx;
+};
+
+struct InvalidateCacheCommand : public LibrbdAdminSocketCommand {
+public:
+  InvalidateCacheCommand(ImageCtx *ictx) : ictx(ictx) {}
+
+  bool call(stringstream *ss) {
+    int r = invalidate_cache(ictx);
+    if (r < 0) {
+      *ss << "invalidate_cache: " << cpp_strerror(r);
+      return false;
+    }
+    return true;
+  }
+
+private:
+  ImageCtx *ictx;
+};
+
+LibrbdAdminSocketHook::LibrbdAdminSocketHook(ImageCtx *ictx) :
+  admin_socket(ictx->cct->get_admin_socket()) {
+
+  std::string command;
+  int r;
+
+  command = "rbd cache flush " + ictx->name;
+  r = admin_socket->register_command(command, command, this,
+                                    "flush rbd image " + ictx->name +
+                                    " cache");
+  if (r == 0) {
+    commands[command] = new FlushCacheCommand(ictx);
+  }
+
+  command = "rbd cache invalidate " + ictx->name;
+  r = admin_socket->register_command(command, command, this,
+                                    "invalidate rbd image " + ictx->name +
+                                    " cache");
+  if (r == 0) {
+    commands[command] = new InvalidateCacheCommand(ictx);
+  }
+}
+
+LibrbdAdminSocketHook::~LibrbdAdminSocketHook() {
+  for (Commands::const_iterator i = commands.begin(); i != commands.end();
+       i++) {
+    (void)admin_socket->unregister_command(i->first);
+    delete i->second;
+  }
+}
+
+bool LibrbdAdminSocketHook::call(std::string command, cmdmap_t& cmdmap,
+                                std::string format, bufferlist& out) {
+  Commands::const_iterator i = commands.find(command);
+  assert(i != commands.end());
+  stringstream ss;
+  bool r = i->second->call(&ss);
+  out.append(ss);
+  return r;
+}
+
+} // namespace librbd
diff --git a/src/librbd/LibrbdAdminSocketHook.h b/src/librbd/LibrbdAdminSocketHook.h
new file mode 100644 (file)
index 0000000..ecd8988
--- /dev/null
@@ -0,0 +1,31 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+#ifndef CEPH_LIBRBD_LIBRBDADMINSOCKETHOOK_H
+#define CEPH_LIBRBD_LIBRBDADMINSOCKETHOOK_H
+
+#include <map>
+
+#include "common/admin_socket.h"
+
+namespace librbd {
+
+  struct ImageCtx;
+  class LibrbdAdminSocketCommand;
+
+  class LibrbdAdminSocketHook : public AdminSocketHook {
+  public:
+    LibrbdAdminSocketHook(ImageCtx *ictx);
+    ~LibrbdAdminSocketHook();
+
+    bool call(std::string command, cmdmap_t& cmdmap, std::string format,
+             bufferlist& out);
+
+  private:
+    typedef std::map<std::string,LibrbdAdminSocketCommand*> Commands;
+
+    AdminSocket *admin_socket;
+    Commands commands;
+  };
+}
+
+#endif
index 43604979461971d94474d7494aeaa631b55e3a58..96390931141f5701cb071e12f914f42497e6a2d5 100644 (file)
@@ -20,6 +20,7 @@ librbd_internal_la_SOURCES = \
        librbd/ImageCtx.cc \
        librbd/ImageWatcher.cc \
        librbd/internal.cc \
+       librbd/LibrbdAdminSocketHook.cc \
        librbd/LibrbdWriteback.cc \
        librbd/ObjectMap.cc \
        librbd/RebuildObjectMapRequest.cc
@@ -60,6 +61,7 @@ noinst_HEADERS += \
        librbd/ImageCtx.h \
        librbd/ImageWatcher.h \
        librbd/internal.h \
+       librbd/LibrbdAdminSocketHook.h \
        librbd/LibrbdWriteback.h \
        librbd/ObjectMap.h \
        librbd/parent_types.h \