librbd: flush and invalidate cache via admin socket

Fixes: #2468
Signed-off-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
Mykola Golub 2015-11-03 08:55:23 +02:00
parent 39503f5841
commit 0996f9dfce
5 changed files with 140 additions and 1 deletions

View 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();

View 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);

View File

@ -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

View File

@ -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

View 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 \