summaryrefslogtreecommitdiffstats
path: root/src/librbd/LibrbdAdminSocketHook.cc
blob: 15b8fb970294e45240655316cbee99025f1ea183 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// -*- 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"
#include "librbd/io/ImageRequestWQ.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:
  explicit FlushCacheCommand(ImageCtx *ictx) : ictx(ictx) {}

  bool call(stringstream *ss) override {
    int r = ictx->io_work_queue->flush();
    if (r < 0) {
      *ss << "flush: " << cpp_strerror(r);
      return false;
    }
    return true;
  }

private:
  ImageCtx *ictx;
};

struct InvalidateCacheCommand : public LibrbdAdminSocketCommand {
public:
  explicit InvalidateCacheCommand(ImageCtx *ictx) : ictx(ictx) {}

  bool call(stringstream *ss) override {
    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;
  std::string imagename;
  int r;

  imagename = ictx->md_ctx.get_pool_name() + "/" + ictx->name;
  command = "rbd cache flush " + imagename;

  r = admin_socket->register_command(command, command, this,
				     "flush rbd image " + imagename +
				     " cache");
  if (r == 0) {
    commands[command] = new FlushCacheCommand(ictx);
  }

  command = "rbd cache invalidate " + imagename;
  r = admin_socket->register_command(command, command, this,
				     "invalidate rbd image " + imagename + 
				     " 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_view command,
				 const cmdmap_t& cmdmap,
				 std::string_view format,
				 bufferlist& out) {
  Commands::const_iterator i = commands.find(command);
  ceph_assert(i != commands.end());
  stringstream ss;
  bool r = i->second->call(&ss);
  out.append(ss);
  return r;
}

} // namespace librbd