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