state == MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED);
}
+ inline bool is_orphan() const {
+ return (is_non_primary() &&
+ primary_mirror_uuid.empty() &&
+ primary_snap_id == CEPH_NOSNAP);
+ }
+
void encode(bufferlist& bl) const;
void decode(bufferlist::const_iterator& it);
std::shared_lock l{m_image_ctx.owner_lock};
if (m_image_ctx.exclusive_lock != nullptr) {
int r;
- if (m_image_ctx.exclusive_lock->accept_request(
- exclusive_lock::OPERATION_REQUEST_TYPE_GENERAL, &r)) {
+ auto request_type = exclusive_lock::OPERATION_REQUEST_TYPE_GENERAL;
+
+ // rbd-mirror needs to accept forced promotion orphan snap create requests
+ auto mirror_ns = boost::get<cls::rbd::MirrorSnapshotNamespace>(
+ &payload.snap_namespace);
+ if (mirror_ns != nullptr && mirror_ns->is_orphan()) {
+ request_type = exclusive_lock::OPERATION_REQUEST_TYPE_FORCE_PROMOTION;
+ }
+
+ if (m_image_ctx.exclusive_lock->accept_request(request_type, &r)) {
ldout(m_image_ctx.cct, 10) << this << " remote snap_create request: "
<< payload.snap_name << dendl;
enum OperationRequestType {
OPERATION_REQUEST_TYPE_GENERAL = 0,
OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE = 1,
+ OPERATION_REQUEST_TYPE_FORCE_PROMOTION = 2,
};
struct Policy {
cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY), {},
m_primary_mirror_uuid, m_primary_snap_id};
ns.snap_seqs = m_snap_seqs;
+ ns.complete = is_orphan();
ldout(cct, 20) << "ns=" << ns << dendl;
auto ctx = create_context_callback<
if (is_orphan()) {
finish(0);
+ return;
}
CephContext *cct = m_image_ctx->cct;
return;
}
+ ldout(cct, 20) << "requires_orphan=" << requires_orphan << ", "
+ << "rollback_snap_id=" << m_rollback_snap_id << dendl;
create_orphan_snapshot();
}
r = m_image_ctx->exclusive_lock->get_unlocked_op_error();
locker.unlock();
finish(r);
+ return;
}
}
bool accept_blocked_request(
librbd::exclusive_lock::OperationRequestType request_type) override {
- if (request_type ==
- librbd::exclusive_lock::OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE) {
+ switch (request_type) {
+ case librbd::exclusive_lock::OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE:
+ case librbd::exclusive_lock::OPERATION_REQUEST_TYPE_FORCE_PROMOTION:
return true;
+ default:
+ return false;
}
- return false;
}
};