#include "librbd/internal.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageWatcher.h"
+#include "librbd/LibrbdAdminSocketHook.h"
#include "librbd/ObjectMap.h"
#include <boost/bind.hpp>
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);
delete op_work_queue;
delete aio_work_queue;
+
+ delete asok_hook;
}
int ImageCtx::init() {
C_SaferCond ctx;
invalidate_cache(&ctx);
result = ctx.wait();
+ ldout(cct, 20) << "finished invalidating cache" << dendl;
if (result && purge_on_error) {
cache_lock.Lock();
template <typename ImageCtxT> class AsyncRequest;
class AsyncResizeRequest;
class CopyupRequest;
+ class LibrbdAdminSocketHook;
class ImageWatcher;
struct ImageCtx {
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);
--- /dev/null
+// -*- 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
--- /dev/null
+// -*- 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
librbd/ImageCtx.cc \
librbd/ImageWatcher.cc \
librbd/internal.cc \
+ librbd/LibrbdAdminSocketHook.cc \
librbd/LibrbdWriteback.cc \
librbd/ObjectMap.cc \
librbd/RebuildObjectMapRequest.cc
librbd/ImageCtx.h \
librbd/ImageWatcher.h \
librbd/internal.h \
+ librbd/LibrbdAdminSocketHook.h \
librbd/LibrbdWriteback.h \
librbd/ObjectMap.h \
librbd/parent_types.h \