]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/mirror/snapshot/DemoteRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / mirror / snapshot / DemoteRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "librbd/mirror/snapshot/DemoteRequest.h"
5 #include "common/dout.h"
6 #include "common/errno.h"
7 #include "cls/rbd/cls_rbd_client.h"
8 #include "librbd/ImageCtx.h"
9 #include "librbd/ImageState.h"
10 #include "librbd/Operations.h"
11 #include "librbd/Utils.h"
12 #include "librbd/mirror/snapshot/CreatePrimaryRequest.h"
13
14 #define dout_subsys ceph_subsys_rbd
15 #undef dout_prefix
16 #define dout_prefix *_dout << "librbd::mirror::snapshot::DemoteRequest: " \
17 << this << " " << __func__ << ": "
18
19 namespace librbd {
20 namespace mirror {
21 namespace snapshot {
22
23 using librbd::util::create_context_callback;
24 using librbd::util::create_rados_callback;
25
26 template <typename I>
27 void DemoteRequest<I>::send() {
28 enable_non_primary_feature();
29 }
30
31 template <typename I>
32 void DemoteRequest<I>::enable_non_primary_feature() {
33 CephContext *cct = m_image_ctx->cct;
34 ldout(cct, 10) << dendl;
35
36 // ensure image is flagged with non-primary feature so that
37 // standard RBD clients cannot write to it.
38 librados::ObjectWriteOperation op;
39 cls_client::set_features(&op, RBD_FEATURE_NON_PRIMARY,
40 RBD_FEATURE_NON_PRIMARY);
41
42 auto aio_comp = create_rados_callback<
43 DemoteRequest<I>,
44 &DemoteRequest<I>::handle_enable_non_primary_feature>(this);
45 int r = m_image_ctx->md_ctx.aio_operate(m_image_ctx->header_oid, aio_comp,
46 &op);
47 ceph_assert(r == 0);
48 aio_comp->release();
49 }
50
51 template <typename I>
52 void DemoteRequest<I>::handle_enable_non_primary_feature(int r) {
53 CephContext *cct = m_image_ctx->cct;
54 ldout(cct, 10) << "r=" << r << dendl;
55
56 if (r < 0) {
57 lderr(cct) << "failed to enable non-primary feature: "
58 << cpp_strerror(r) << dendl;
59 finish(r);
60 return;
61 }
62
63 create_snapshot();
64 }
65
66 template <typename I>
67 void DemoteRequest<I>::create_snapshot() {
68 CephContext *cct = m_image_ctx->cct;
69 ldout(cct, 20) << dendl;
70
71 auto ctx = create_context_callback<
72 DemoteRequest<I>, &DemoteRequest<I>::handle_create_snapshot>(this);
73
74 auto req = CreatePrimaryRequest<I>::create(
75 m_image_ctx, m_global_image_id,
76 (snapshot::CREATE_PRIMARY_FLAG_IGNORE_EMPTY_PEERS |
77 snapshot::CREATE_PRIMARY_FLAG_DEMOTED), nullptr, ctx);
78 req->send();
79 }
80
81 template <typename I>
82 void DemoteRequest<I>::handle_create_snapshot(int r) {
83 CephContext *cct = m_image_ctx->cct;
84 ldout(cct, 20) << "r=" << r << dendl;
85
86 if (r < 0) {
87 lderr(cct) << "failed to create mirror snapshot: " << cpp_strerror(r)
88 << dendl;
89 finish(r);
90 return;
91 }
92
93 finish(0);
94 }
95
96 template <typename I>
97 void DemoteRequest<I>::finish(int r) {
98 CephContext *cct = m_image_ctx->cct;
99 ldout(cct, 20) << "r=" << r << dendl;
100
101 m_on_finish->complete(r);
102 delete this;
103 }
104
105 } // namespace snapshot
106 } // namespace mirror
107 } // namespace librbd
108
109 template class librbd::mirror::snapshot::DemoteRequest<librbd::ImageCtx>;