rbd-mirror: persist image mapping timestamp on map update

Signed-off-by: Venky Shankar <vshankar@redhat.com>
This commit is contained in:
Venky Shankar 2017-11-28 23:04:39 -05:00
parent c3ae008994
commit dbf08e5177
4 changed files with 59 additions and 34 deletions

View File

@ -69,10 +69,10 @@ void ImageMap<I>::queue_update_map(const std::string &global_image_id) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
std::string instance_id = m_policy->lookup(global_image_id);
assert(instance_id != Policy::UNMAPPED_INSTANCE_ID);
Policy::LookupInfo info = m_policy->lookup(global_image_id);
assert(info.instance_id != Policy::UNMAPPED_INSTANCE_ID);
m_updates.emplace_back(global_image_id, instance_id);
m_updates.emplace_back(global_image_id, info.instance_id, info.mapped_time);
}
template<typename I>
@ -89,10 +89,10 @@ void ImageMap<I>::queue_acquire_image(const std::string &global_image_id) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
std::string instance_id = m_policy->lookup(global_image_id);
assert(instance_id != Policy::UNMAPPED_INSTANCE_ID);
Policy::LookupInfo info = m_policy->lookup(global_image_id);
assert(info.instance_id != Policy::UNMAPPED_INSTANCE_ID);
m_acquire_updates.emplace_back(global_image_id, instance_id);
m_acquire_updates.emplace_back(global_image_id, info.instance_id);
}
template <typename I>
@ -101,10 +101,10 @@ void ImageMap<I>::queue_release_image(const std::string &global_image_id) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
std::string instance_id = m_policy->lookup(global_image_id);
assert(instance_id != Policy::UNMAPPED_INSTANCE_ID);
Policy::LookupInfo info = m_policy->lookup(global_image_id);
assert(info.instance_id != Policy::UNMAPPED_INSTANCE_ID);
m_release_updates.emplace_back(global_image_id, instance_id);
m_release_updates.emplace_back(global_image_id, info.instance_id);
}
template <typename I>
@ -171,8 +171,8 @@ void ImageMap<I>::update_image_mapping() {
// prepare update map
std::map<std::string, cls::rbd::MirrorImageMap> update_mapping;
for (auto const &update : updates) {
update_mapping.emplace(update.global_image_id,
cls::rbd::MirrorImageMap(update.instance_id, bl));
update_mapping.emplace(
update.global_image_id, cls::rbd::MirrorImageMap(update.instance_id, update.mapped_time, bl));
}
start_async_op();
@ -404,9 +404,9 @@ void ImageMap<I>::update_images_removed(const std::string &peer_uuid,
schedule_remove_action(global_image_id);
}
std::string instance_id = m_policy->lookup(global_image_id);
if (instance_id != Policy::UNMAPPED_INSTANCE_ID) {
to_remove.emplace_back(global_image_id, instance_id);
Policy::LookupInfo info = m_policy->lookup(global_image_id);
if (info.instance_id != Policy::UNMAPPED_INSTANCE_ID) {
to_remove.emplace_back(global_image_id, info.instance_id);
}
}

View File

@ -57,10 +57,16 @@ private:
struct Update {
std::string global_image_id;
std::string instance_id;
utime_t mapped_time;
Update(const std::string &global_image_id, const std::string &instance_id)
Update(const std::string &global_image_id, const std::string &instance_id,
utime_t mapped_time)
: global_image_id(global_image_id),
instance_id(instance_id) {
instance_id(instance_id),
mapped_time(mapped_time) {
}
Update(const std::string &global_image_id, const std::string &instance_id)
: Update(global_image_id, instance_id, ceph_clock_now()) {
}
};
typedef std::list<Update> Updates;

View File

@ -36,11 +36,11 @@ void Policy::init(const std::map<std::string, cls::rbd::MirrorImageMap> &image_m
RWLock::WLocker map_lock(m_map_lock);
for (auto const &it : image_mapping) {
map(it.first, it.second.instance_id, utime_t(0, 0), m_map_lock);
map(it.first, it.second.instance_id, it.second.mapped_time, m_map_lock);
}
}
std::string Policy::lookup(const std::string &global_image_id) {
Policy::LookupInfo Policy::lookup(const std::string &global_image_id) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
RWLock::RLocker map_lock(m_map_lock);
@ -334,16 +334,19 @@ bool Policy::remove_pending(const std::string &global_image_id) {
return r_it != it->second.actions.rend();
}
std::string Policy::lookup(const std::string &global_image_id, const RWLock &lock) {
Policy::LookupInfo Policy::lookup(const std::string &global_image_id, const RWLock &lock) {
assert(m_map_lock.is_locked());
LookupInfo info;
for (auto it = m_map.begin(); it != m_map.end(); ++it) {
if (it->second.find(global_image_id) != it->second.end()) {
return it->first;
info.instance_id = it->first;
info.mapped_time = get_image_mapped_timestamp(global_image_id);
}
}
return UNMAPPED_INSTANCE_ID;
return info;
}
void Policy::map(const std::string &global_image_id, const std::string &instance_id,
@ -353,9 +356,7 @@ void Policy::map(const std::string &global_image_id, const std::string &instance
auto ins = m_map[instance_id].emplace(global_image_id);
assert(ins.second);
auto it = m_actions.find(global_image_id);
assert(it != m_actions.end());
it->second.map_time = map_time;
set_image_mapped_timestamp(global_image_id, map_time);
}
void Policy::unmap(const std::string &global_image_id, const std::string &instance_id,
@ -375,7 +376,9 @@ void Policy::map(const std::string &global_image_id, utime_t map_time) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
assert(m_map_lock.is_wlocked());
std::string instance_id = lookup(global_image_id, m_map_lock);
LookupInfo info = lookup(global_image_id, m_map_lock);
std::string instance_id = info.instance_id;
if (instance_id != UNMAPPED_INSTANCE_ID && !is_dead_instance(instance_id)) {
return;
}
@ -391,12 +394,12 @@ void Policy::unmap(const std::string &global_image_id) {
dout(20) << ": global_image_id=" << global_image_id << dendl;
assert(m_map_lock.is_wlocked());
std::string instance_id = lookup(global_image_id, m_map_lock);
if (instance_id == UNMAPPED_INSTANCE_ID) {
LookupInfo info = lookup(global_image_id, m_map_lock);
if (info.instance_id == UNMAPPED_INSTANCE_ID) {
return;
}
unmap(global_image_id, instance_id, m_map_lock);
unmap(global_image_id, info.instance_id, m_map_lock);
}
bool Policy::can_shuffle_image(const std::string &global_image_id) {
@ -406,10 +409,7 @@ bool Policy::can_shuffle_image(const std::string &global_image_id) {
CephContext *cct = reinterpret_cast<CephContext *>(m_ioctx.cct());
int migration_throttle = cct->_conf->get_val<int64_t>("rbd_mirror_image_policy_migration_throttle");
auto it = m_actions.find(global_image_id);
assert(it != m_actions.end());
utime_t last_shuffled_time = it->second.map_time;
utime_t last_shuffled_time = get_image_mapped_timestamp(global_image_id);
dout(10) << ": migration_throttle=" << migration_throttle << ", last_shuffled_time="
<< last_shuffled_time << dendl;

View File

@ -30,7 +30,11 @@ public:
void init(const std::map<std::string, cls::rbd::MirrorImageMap> &image_mapping);
// lookup an image from the map
std::string lookup(const std::string &global_image_id);
struct LookupInfo {
std::string instance_id = UNMAPPED_INSTANCE_ID;
utime_t mapped_time;
};
LookupInfo lookup(const std::string &global_image_id);
// add, remove, shuffle
bool add_image(const std::string &global_image_id,
@ -67,6 +71,21 @@ private:
utime_t map_time; // (re)mapped time
};
void set_image_mapped_timestamp(const std::string &global_image_id, utime_t time) {
assert(m_map_lock.is_wlocked());
auto it = m_actions.find(global_image_id);
assert(it != m_actions.end());
it->second.map_time = time;
}
utime_t get_image_mapped_timestamp(const std::string &global_image_id) {
assert(m_map_lock.is_locked());
auto it = m_actions.find(global_image_id);
assert(it != m_actions.end());
return it->second.map_time;
}
librados::IoCtx &m_ioctx;
std::map<std::string, ActionState> m_actions;
std::set<std::string> m_dead_instances;
@ -98,7 +117,7 @@ private:
bool actions_pending(const std::string &global_image_id, const RWLock &lock);
bool remove_pending(const std::string &glolbal_image_id);
std::string lookup(const std::string &global_image_id, const RWLock &lock);
LookupInfo lookup(const std::string &global_image_id, const RWLock &lock);
void map(const std::string &global_image_id,
const std::string &instance_id, utime_t map_time, const RWLock &lock);
void unmap(const std::string &global_image_id, const std::string &instance_id, const RWLock &lock);