1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/errno.h"
6 #include "rgw_realm_watcher.h"
9 #define dout_subsys ceph_subsys_rgw
12 #define dout_prefix (*_dout << "rgw realm watcher: ")
15 RGWRealmWatcher::RGWRealmWatcher(CephContext* cct, RGWRealm& realm)
18 // no default realm, nothing to watch
19 if (realm.get_id().empty()) {
20 ldout(cct, 4) << "No realm, disabling dynamic reconfiguration." << dendl;
24 // establish the watch on RGWRealm
25 int r = watch_start(realm);
27 lderr(cct) << "Failed to establish a watch on RGWRealm, "
28 "disabling dynamic reconfiguration." << dendl;
33 RGWRealmWatcher::~RGWRealmWatcher()
38 void RGWRealmWatcher::add_watcher(RGWRealmNotify type, Watcher& watcher)
40 watchers.emplace(type, watcher);
43 void RGWRealmWatcher::handle_notify(uint64_t notify_id, uint64_t cookie,
44 uint64_t notifier_id, bufferlist& bl)
46 if (cookie != watch_handle)
49 // send an empty notify ack
51 pool_ctx.notify_ack(watch_oid, notify_id, cookie, reply);
56 RGWRealmNotify notify;
58 auto watcher = watchers.find(notify);
59 if (watcher == watchers.end()) {
60 lderr(cct) << "Failed to find a watcher for notify type "
61 << static_cast<int>(notify) << dendl;
64 watcher->second.handle_notify(notify, p);
66 } catch (const buffer::error &e) {
67 lderr(cct) << "Failed to decode realm notifications." << dendl;
71 void RGWRealmWatcher::handle_error(uint64_t cookie, int err)
73 if (cookie != watch_handle)
76 if (err == -ENOTCONN) {
77 ldout(cct, 4) << "Disconnected watch on " << watch_oid << dendl;
82 int RGWRealmWatcher::watch_start(RGWRealm& realm)
84 // initialize a Rados client
85 int r = rados.init_with_context(cct);
87 lderr(cct) << "Rados client initialization failed with "
88 << cpp_strerror(-r) << dendl;
93 lderr(cct) << "Rados client connection failed with "
94 << cpp_strerror(-r) << dendl;
98 // open an IoCtx for the realm's pool
99 rgw_pool pool(realm.get_pool(cct));
100 r = rgw_init_ioctx(&rados, pool, pool_ctx);
102 lderr(cct) << "Failed to open pool " << pool
103 << " with " << cpp_strerror(-r) << dendl;
108 // register a watch on the realm's control object
109 auto oid = realm.get_control_oid();
110 r = pool_ctx.watch2(oid, &watch_handle, this);
112 lderr(cct) << "Failed to watch " << oid
113 << " with " << cpp_strerror(-r) << dendl;
119 ldout(cct, 10) << "Watching " << oid << dendl;
120 std::swap(watch_oid, oid);
124 int RGWRealmWatcher::watch_restart()
126 assert(!watch_oid.empty());
127 int r = pool_ctx.unwatch2(watch_handle);
129 lderr(cct) << "Failed to unwatch on " << watch_oid
130 << " with " << cpp_strerror(-r) << dendl;
132 r = pool_ctx.watch2(watch_oid, &watch_handle, this);
134 lderr(cct) << "Failed to restart watch on " << watch_oid
135 << " with " << cpp_strerror(-r) << dendl;
142 void RGWRealmWatcher::watch_stop()
144 if (!watch_oid.empty()) {
145 pool_ctx.unwatch2(watch_handle);