]>
git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_realm_reloader.cc
8df554a5f3b31415947178be4ddf3af538f27e67
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "rgw_realm_reloader.h"
7 #include "rgw_bucket.h"
12 #define dout_subsys ceph_subsys_rgw
15 #define dout_prefix (*_dout << "rgw realm reloader: ")
18 // safe callbacks from SafeTimer are unneccessary. reload() can take a long
19 // time, so we don't want to hold the mutex and block handle_notify() for the
21 static constexpr bool USE_SAFE_TIMER_CALLBACKS
= false;
24 RGWRealmReloader::RGWRealmReloader(RGWRados
*& store
, Pauser
* frontends
)
27 timer(store
->ctx(), mutex
, USE_SAFE_TIMER_CALLBACKS
),
28 mutex("RGWRealmReloader"),
29 reload_scheduled(nullptr)
34 RGWRealmReloader::~RGWRealmReloader()
36 Mutex::Locker
lock(mutex
);
40 class RGWRealmReloader::C_Reload
: public Context
{
41 RGWRealmReloader
* reloader
;
43 C_Reload(RGWRealmReloader
* reloader
) : reloader(reloader
) {}
44 void finish(int r
) override
{ reloader
->reload(); }
47 void RGWRealmReloader::handle_notify(RGWRealmNotify type
,
48 bufferlist::iterator
& p
)
51 /* we're in the middle of reload */
55 CephContext
*const cct
= store
->ctx();
57 Mutex::Locker
lock(mutex
);
58 if (reload_scheduled
) {
59 ldout(cct
, 4) << "Notification on realm, reconfiguration "
60 "already scheduled" << dendl
;
64 reload_scheduled
= new C_Reload(this);
65 cond
.SignalOne(); // wake reload() if it blocked on a bad configuration
67 // schedule reload() without delay
68 timer
.add_event_after(0, reload_scheduled
);
70 ldout(cct
, 4) << "Notification on realm, reconfiguration scheduled" << dendl
;
73 void RGWRealmReloader::reload()
75 CephContext
*const cct
= store
->ctx();
76 ldout(cct
, 1) << "Pausing frontends for realm update..." << dendl
;
80 ldout(cct
, 1) << "Frontends paused" << dendl
;
82 // TODO: make RGWRados responsible for rgw_log_usage lifetime
83 rgw_log_usage_finalize();
85 // destroy the existing store
86 RGWStoreManager::close_storage(store
);
89 ldout(cct
, 1) << "Store closed" << dendl
;
91 // allow a new notify to reschedule us. it's important that we do this
92 // before we start loading the new realm, or we could miss some updates
93 Mutex::Locker
lock(mutex
);
94 reload_scheduled
= nullptr;
98 // recreate and initialize a new store
99 store
= RGWStoreManager::get_storage(cct
,
100 cct
->_conf
->rgw_enable_gc_threads
,
101 cct
->_conf
->rgw_enable_lc_threads
,
102 cct
->_conf
->rgw_enable_quota_threads
,
103 cct
->_conf
->rgw_run_sync_thread
,
104 cct
->_conf
->rgw_dynamic_resharding
);
106 ldout(cct
, 1) << "Creating new store" << dendl
;
108 RGWRados
* store_cleanup
= nullptr;
110 Mutex::Locker
lock(mutex
);
112 // failure to recreate RGWRados is not a recoverable error, but we
113 // don't want to assert or abort the entire cluster. instead, just
114 // sleep until we get another notification, and retry until we get
115 // a working configuration
116 if (store
== nullptr) {
117 lderr(cct
) << "Failed to reinitialize RGWRados after a realm "
118 "configuration update. Waiting for a new update." << dendl
;
120 // sleep until another event is scheduled
121 while (!reload_scheduled
)
124 ldout(cct
, 1) << "Woke up with a new configuration, retrying "
125 "RGWRados initialization." << dendl
;
128 if (reload_scheduled
) {
129 // cancel the event; we'll handle it now
130 timer
.cancel_event(reload_scheduled
);
131 reload_scheduled
= nullptr;
133 // if we successfully created a store, clean it up outside of the lock,
134 // then continue to loop and recreate another
135 std::swap(store
, store_cleanup
);
140 ldout(cct
, 4) << "Got another notification, restarting RGWRados "
141 "initialization." << dendl
;
143 RGWStoreManager::close_storage(store_cleanup
);
147 ldout(cct
, 1) << "Finishing initialization of new store" << dendl
;
148 // finish initializing the new store
149 ldout(cct
, 1) << " - REST subsystem init" << dendl
;
150 rgw_rest_init(cct
, store
, store
->get_zonegroup());
151 ldout(cct
, 1) << " - user subsystem init" << dendl
;
152 rgw_user_init(store
);
153 ldout(cct
, 1) << " - user subsystem init" << dendl
;
154 rgw_bucket_init(store
->meta_mgr
);
155 ldout(cct
, 1) << " - usage subsystem init" << dendl
;
156 rgw_log_usage_init(cct
, store
);
158 ldout(cct
, 1) << "Resuming frontends with new realm configuration." << dendl
;
160 frontends
->resume(store
);