]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/ClusterWatcher.cc
e193b8ccdf516b6f46b9354136aefcce86918dd6
[ceph.git] / ceph / src / tools / rbd_mirror / ClusterWatcher.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "ClusterWatcher.h"
5 #include "common/debug.h"
6 #include "common/errno.h"
7 #include "librbd/internal.h"
8 #include "librbd/api/Mirror.h"
9
10 #define dout_context g_ceph_context
11 #define dout_subsys ceph_subsys_rbd_mirror
12 #undef dout_prefix
13 #define dout_prefix *_dout << "rbd::mirror::ClusterWatcher:" << this << " " \
14 << __func__ << ": "
15
16 using std::list;
17 using std::map;
18 using std::set;
19 using std::string;
20 using std::unique_ptr;
21 using std::vector;
22
23 using librados::Rados;
24 using librados::IoCtx;
25
26 namespace rbd {
27 namespace mirror {
28
29 ClusterWatcher::ClusterWatcher(RadosRef cluster, Mutex &lock) :
30 m_lock(lock),
31 m_cluster(cluster)
32 {
33 }
34
35 const ClusterWatcher::PoolPeers& ClusterWatcher::get_pool_peers() const
36 {
37 assert(m_lock.is_locked());
38 return m_pool_peers;
39 }
40
41 void ClusterWatcher::refresh_pools()
42 {
43 dout(20) << "enter" << dendl;
44
45 PoolPeers pool_peers;
46 PoolNames pool_names;
47 read_pool_peers(&pool_peers, &pool_names);
48
49 Mutex::Locker l(m_lock);
50 m_pool_peers = pool_peers;
51 // TODO: perhaps use a workqueue instead, once we get notifications
52 // about config changes for existing pools
53 }
54
55 void ClusterWatcher::read_pool_peers(PoolPeers *pool_peers,
56 PoolNames *pool_names)
57 {
58 list<pair<int64_t, string> > pools;
59 int r = m_cluster->pool_list2(pools);
60 if (r < 0) {
61 derr << "error listing pools: " << cpp_strerror(r) << dendl;
62 return;
63 }
64
65 for (auto kv : pools) {
66 int64_t pool_id = kv.first;
67 string pool_name = kv.second;
68 int64_t base_tier;
69 r = m_cluster->pool_get_base_tier(pool_id, &base_tier);
70 if (r == -ENOENT) {
71 dout(10) << "pool " << pool_name << " no longer exists" << dendl;
72 continue;
73 } else if (r < 0) {
74 derr << "Error retrieving base tier for pool " << pool_name << dendl;
75 continue;
76 }
77 if (pool_id != base_tier) {
78 // pool is a cache; skip it
79 continue;
80 }
81
82 IoCtx ioctx;
83 r = m_cluster->ioctx_create2(pool_id, ioctx);
84 if (r == -ENOENT) {
85 dout(10) << "pool " << pool_id << " no longer exists" << dendl;
86 continue;
87 } else if (r < 0) {
88 derr << "Error accessing pool " << pool_name << cpp_strerror(r) << dendl;
89 continue;
90 }
91
92 rbd_mirror_mode_t mirror_mode;
93 r = librbd::api::Mirror<>::mode_get(ioctx, &mirror_mode);
94 if (r < 0) {
95 derr << "could not tell whether mirroring was enabled for " << pool_name
96 << " : " << cpp_strerror(r) << dendl;
97 continue;
98 }
99 if (mirror_mode == RBD_MIRROR_MODE_DISABLED) {
100 dout(10) << "mirroring is disabled for pool " << pool_name << dendl;
101 continue;
102 }
103
104 vector<librbd::mirror_peer_t> configs;
105 r = librbd::api::Mirror<>::peer_list(ioctx, &configs);
106 if (r < 0) {
107 derr << "error reading mirroring config for pool " << pool_name
108 << cpp_strerror(r) << dendl;
109 continue;
110 }
111
112 pool_peers->insert({pool_id, Peers{configs.begin(), configs.end()}});
113 pool_names->insert(pool_name);
114 }
115 }
116
117 } // namespace mirror
118 } // namespace rbd