From 0996f9dfce36f205fffae84a5e8e372263d36389 Mon Sep 17 00:00:00 2001 From: Mykola Golub Date: Tue, 3 Nov 2015 08:55:23 +0200 Subject: [PATCH] librbd: flush and invalidate cache via admin socket Fixes: #2468 Signed-off-by: Mykola Golub --- src/librbd/ImageCtx.cc | 7 ++- src/librbd/ImageCtx.h | 4 ++ src/librbd/LibrbdAdminSocketHook.cc | 97 +++++++++++++++++++++++++++++ src/librbd/LibrbdAdminSocketHook.h | 31 +++++++++ src/librbd/Makefile.am | 2 + 5 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 src/librbd/LibrbdAdminSocketHook.cc create mode 100644 src/librbd/LibrbdAdminSocketHook.h diff --git a/src/librbd/ImageCtx.cc b/src/librbd/ImageCtx.cc index ecb246ca39a..50c0b0295ed 100644 --- a/src/librbd/ImageCtx.cc +++ b/src/librbd/ImageCtx.cc @@ -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 @@ -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(); diff --git a/src/librbd/ImageCtx.h b/src/librbd/ImageCtx.h index 3c7f170b584..bfddf801697 100644 --- a/src/librbd/ImageCtx.h +++ b/src/librbd/ImageCtx.h @@ -41,6 +41,7 @@ namespace librbd { template 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 &configs, map &pairs, map *res); diff --git a/src/librbd/LibrbdAdminSocketHook.cc b/src/librbd/LibrbdAdminSocketHook.cc new file mode 100644 index 00000000000..ca7d64a3e79 --- /dev/null +++ b/src/librbd/LibrbdAdminSocketHook.cc @@ -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 index 00000000000..ecd8988f720 --- /dev/null +++ b/src/librbd/LibrbdAdminSocketHook.h @@ -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 + +#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 Commands; + + AdminSocket *admin_socket; + Commands commands; + }; +} + +#endif diff --git a/src/librbd/Makefile.am b/src/librbd/Makefile.am index 43604979461..96390931141 100644 --- a/src/librbd/Makefile.am +++ b/src/librbd/Makefile.am @@ -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 \