sdq_cv.notify_all();
}
+void PeerReplayer::SyncMechanism::wait_for_sync() {
+ std::unique_lock lock(sdq_lock);
+ dout(20) << ": Waiting for data sync to be done to take snapshot - dir_root=" << m_dir_root
+ << " current=" << m_current << " prev=" << (m_prev ? stringify(m_prev) : "")
+ << " syncm=" << this << dendl;
+ sdq_cv.wait(lock, [this]{return m_sync_done;});
+ dout(20) << ": Woke up to take snapshot - dir_root=" << m_dir_root
+ << " current=" << m_current << " prev=" << (m_prev ? stringify(m_prev) : "")
+ << " syncm=" << this << dendl;
+ m_sync_done = false;
+}
+
int PeerReplayer::SyncMechanism::get_changed_blocks(const std::string &epath,
const struct ceph_statx &stx, bool sync_check,
const std::function<int (uint64_t, struct cblock *)> &callback) {
dout(10) << ": tree traversal done for dir_root=" << dir_root << dendl;
break;
}
-
}
syncm->finish_crawl();
// there is no need to close this fd manually.
ceph_close(fh.p_mnt, fh.p_fd);
+ if (r == 0 ) { //Bail out without taking snap if r < 0
+ syncm->wait_for_sync();
+
+ // All good, take the snapshot
+ auto cur_snap_id_str{stringify(current.second)};
+ snap_metadata snap_meta[] = {{PRIMARY_SNAP_ID_KEY.c_str(), cur_snap_id_str.c_str()}};
+ r = ceph_mksnap(m_remote_mount, dir_root.c_str(), current.first.c_str(), 0755,
+ snap_meta, sizeof(snap_meta)/sizeof(snap_metadata));
+ if (r < 0) {
+ derr << ": failed to snap remote directory dir_root=" << dir_root
+ << ": " << cpp_strerror(r) << dendl;
+ }
+ }
+
return r;
}
r = do_synchronize(dir_root, current);
}
}
-
// snap sync failed -- bail out!
if (r < 0) {
return r;
}
- auto cur_snap_id_str{stringify(current.second)};
- snap_metadata snap_meta[] = {{PRIMARY_SNAP_ID_KEY.c_str(), cur_snap_id_str.c_str()}};
- r = ceph_mksnap(m_remote_mount, dir_root.c_str(), current.first.c_str(), 0755,
- snap_meta, sizeof(snap_meta)/sizeof(snap_metadata));
- if (r < 0) {
- derr << ": failed to snap remote directory dir_root=" << dir_root
- << ": " << cpp_strerror(r) << dendl;
- }
-
return r;
}
&& syncm->get_in_flight_unlocked() == 0
&& syncm->get_crawl_finished_unlocked() == true) {
dout(20) << ": Dequeue syncm object=" << syncm << dendl;
+ syncm->set_sync_finished_and_notify_unlocked(); // To wake up crawler thread waiting to take snapshot
syncm_q.pop();
smq_cv.notify_all();
}
boost::optional<Snapshot> get_m_prev() const {
return m_prev;
}
+ void set_sync_finished_and_notify_unlocked() {
+ m_sync_done = true;
+ sdq_cv.notify_all();
+ }
+ void sdq_cv_notify_all_unlocked() {
+ sdq_cv.notify_all();
+ }
+ void wait_for_sync();
int remote_mkdir(const std::string &epath, const struct ceph_statx &stx);
protected:
std::queue<PeerReplayer::SyncEntry> m_sync_dataq;
int m_in_flight = 0;
bool m_crawl_finished = false;
+ bool m_sync_done = false;
// It's not used in RemoteSync but required to be accessed in datasync threads
std::string m_dir_root;
};