summaryrefslogtreecommitdiffstats
path: root/src/tools/rbd_mirror/RemotePoolPoller.h
blob: 19d803ca11b7f54f79d8a1ad1408e1eb4ed6d34b (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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_RBD_MIRROR_REMOTE_POOL_POLLER_H
#define CEPH_RBD_MIRROR_REMOTE_POOL_POLLER_H

#include "include/rados/librados.hpp"
#include "tools/rbd_mirror/Types.h"
#include <string>

struct Context;
namespace librbd { struct ImageCtx; }

namespace rbd {
namespace mirror {

template <typename> struct Threads;

namespace remote_pool_poller {

struct Listener {
  virtual ~Listener() {}

  virtual void handle_updated(const RemotePoolMeta& remote_pool_meta) = 0;
};

}; // namespace remote_pool_poller

template <typename ImageCtxT>
class RemotePoolPoller {
public:
  static RemotePoolPoller* create(
      Threads<ImageCtxT>* threads,
      librados::IoCtx& remote_io_ctx,
      const std::string& site_name,
      const std::string& local_mirror_uuid,
      remote_pool_poller::Listener& listener) {
    return new RemotePoolPoller(threads, remote_io_ctx, site_name,
                                local_mirror_uuid, listener);
  }

  RemotePoolPoller(
      Threads<ImageCtxT>* threads,
      librados::IoCtx& remote_io_ctx,
      const std::string& site_name,
      const std::string& local_mirror_uuid,
      remote_pool_poller::Listener& listener)
    : m_threads(threads),
      m_remote_io_ctx(remote_io_ctx),
      m_site_name(site_name),
      m_local_mirror_uuid(local_mirror_uuid),
      m_listener(listener) {
  }
  ~RemotePoolPoller();

  void init(Context* on_finish);
  void shut_down(Context* on_finish);

private:
  /**
   * @verbatim
   *
   * <start>
   *    |
   *    |/----------------------------\
   *    |                             |
   *    v                             |
   * MIRROR_UUID_GET                  |
   *    |                             |
   *    v                             |
   * MIRROR_PEER_PING                 |
   *    |                             |
   *    v                             |
   * MIRROR_PEER_LIST                 |
   *    |                             |
   *    v                             |
   * MIRROR_UUID_GET                  |
   *    |                             |
   *    v (skip if no changes)        |
   * NOTIFY_LISTENER                  |
   *    |                             |
   *    |   (repeat periodically)     |
   *    |\----------------------------/
   *    |
   *    v
   * <finish>
   *
   * @endverbatim
   */

  enum State {
    STATE_INITIALIZING,
    STATE_POLLING,
    STATE_SHUTTING_DOWN
  };

  Threads<ImageCtxT>* m_threads;
  librados::IoCtx& m_remote_io_ctx;
  std::string m_site_name;
  std::string m_local_mirror_uuid;
  remote_pool_poller::Listener& m_listener;

  bufferlist m_out_bl;

  RemotePoolMeta m_remote_pool_meta;
  bool m_updated = false;

  State m_state = STATE_INITIALIZING;
  Context* m_timer_task = nullptr;
  Context* m_on_finish = nullptr;

  void get_mirror_uuid();
  void handle_get_mirror_uuid(int r);

  void mirror_peer_ping();
  void handle_mirror_peer_ping(int r);

  void mirror_peer_list();
  void handle_mirror_peer_list(int r);

  void notify_listener();

  void schedule_task(int r);
  void handle_task();

};

} // namespace mirror
} // namespace rbd

extern template class rbd::mirror::RemotePoolPoller<librbd::ImageCtx>;

#endif // CEPH_RBD_MIRROR_REMOTE_POOL_POLLER_H