]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rbd_mirror/test_ImageDeleter.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / rbd_mirror / test_ImageDeleter.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2016 SUSE LINUX GmbH
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14#include "include/rados/librados.hpp"
15#include "include/rbd/librbd.hpp"
16#include "include/stringify.h"
17#include "cls/rbd/cls_rbd_types.h"
18#include "cls/rbd/cls_rbd_client.h"
19#include "tools/rbd_mirror/ImageDeleter.h"
c07f9fc5 20#include "tools/rbd_mirror/ServiceDaemon.h"
7c673cae 21#include "tools/rbd_mirror/Threads.h"
11fdf7f2 22#include "tools/rbd_mirror/Types.h"
7c673cae
FG
23#include "librbd/ImageCtx.h"
24#include "librbd/ImageState.h"
25#include "librbd/Operations.h"
26#include "librbd/Journal.h"
27#include "librbd/internal.h"
28#include "librbd/Utils.h"
11fdf7f2 29#include "librbd/api/Image.h"
7c673cae 30#include "librbd/api/Mirror.h"
c07f9fc5 31#include "librbd/journal/DisabledPolicy.h"
7c673cae
FG
32#include "test/rbd_mirror/test_fixture.h"
33
34#include "test/librados/test.h"
35#include "gtest/gtest.h"
36
37#define GLOBAL_IMAGE_ID "global_image_id"
38#define GLOBAL_CLONE_IMAGE_ID "global_image_id_clone"
39
40#define dout_subsys ceph_subsys_rbd_mirror
41
42using rbd::mirror::RadosRef;
43using rbd::mirror::TestFixture;
44using namespace librbd;
45using cls::rbd::MirrorImageState;
46
47
48void register_test_rbd_mirror_image_deleter() {
49}
50
51class TestImageDeleter : public TestFixture {
52public:
7c673cae
FG
53 const std::string m_local_mirror_uuid = "local mirror uuid";
54 const std::string m_remote_mirror_uuid = "remote mirror uuid";
55
7c673cae
FG
56 void SetUp() override {
57 TestFixture::SetUp();
11fdf7f2 58
c07f9fc5
FG
59 m_service_daemon.reset(new rbd::mirror::ServiceDaemon<>(g_ceph_context,
60 _rados, m_threads));
7c673cae
FG
61
62 librbd::api::Mirror<>::mode_set(m_local_io_ctx, RBD_MIRROR_MODE_IMAGE);
63
11fdf7f2 64 m_deleter = new rbd::mirror::ImageDeleter<>(m_local_io_ctx, m_threads,
c07f9fc5
FG
65 m_service_daemon.get());
66
67 m_local_image_id = librbd::util::generate_image_id(m_local_io_ctx);
68 librbd::ImageOptions image_opts;
11fdf7f2
TL
69 image_opts.set(RBD_IMAGE_OPTION_FEATURES,
70 (RBD_FEATURES_ALL & ~RBD_FEATURES_IMPLICIT_ENABLE));
c07f9fc5
FG
71 EXPECT_EQ(0, librbd::create(m_local_io_ctx, m_image_name, m_local_image_id,
72 1 << 20, image_opts, GLOBAL_IMAGE_ID,
73 m_remote_mirror_uuid, true));
74
75 cls::rbd::MirrorImage mirror_image(
76 GLOBAL_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
77 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
7c673cae 78 mirror_image));
7c673cae
FG
79 }
80
81 void TearDown() override {
82 remove_image();
11fdf7f2
TL
83
84 C_SaferCond ctx;
85 m_deleter->shut_down(&ctx);
86 ctx.wait();
87
7c673cae 88 delete m_deleter;
c07f9fc5
FG
89 m_service_daemon.reset();
90
91 TestFixture::TearDown();
7c673cae
FG
92 }
93
11fdf7f2
TL
94 void init_image_deleter() {
95 C_SaferCond ctx;
96 m_deleter->init(&ctx);
97 ASSERT_EQ(0, ctx.wait());
98 }
99
100 void remove_image() {
101 cls::rbd::MirrorImage mirror_image;
102 int r = cls_client::mirror_image_get(&m_local_io_ctx, m_local_image_id,
103 &mirror_image);
104 EXPECT_EQ(1, r == 0 || r == -ENOENT);
105 if (r != -ENOENT) {
106 mirror_image.state = MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
107 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx,
108 m_local_image_id,
109 mirror_image));
7c673cae 110 }
11fdf7f2
TL
111 promote_image();
112
7c673cae 113 NoOpProgressContext ctx;
11fdf7f2 114 r = librbd::api::Image<>::remove(m_local_io_ctx, m_image_name, ctx);
7c673cae
FG
115 EXPECT_EQ(1, r == 0 || r == -ENOENT);
116 }
117
118 void promote_image(ImageCtx *ictx=nullptr) {
119 bool close = false;
120 int r = 0;
121 if (!ictx) {
122 ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
123 false);
11fdf7f2 124 r = ictx->state->open(0);
7c673cae
FG
125 close = (r == 0);
126 }
127
128 EXPECT_EQ(1, r == 0 || r == -ENOENT);
129
130 if (r == 0) {
131 int r2 = librbd::api::Mirror<>::image_promote(ictx, true);
132 EXPECT_EQ(1, r2 == 0 || r2 == -EINVAL);
133 }
134
135 if (close) {
136 EXPECT_EQ(0, ictx->state->close());
137 }
138 }
139
140 void demote_image(ImageCtx *ictx=nullptr) {
141 bool close = false;
142 if (!ictx) {
143 ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
144 false);
11fdf7f2 145 EXPECT_EQ(0, ictx->state->open(0));
7c673cae
FG
146 close = true;
147 }
148
149 EXPECT_EQ(0, librbd::api::Mirror<>::image_demote(ictx));
150
151 if (close) {
152 EXPECT_EQ(0, ictx->state->close());
153 }
154 }
155
156 void create_snapshot(std::string snap_name="snap1", bool protect=false) {
157 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
158 false);
11fdf7f2 159 EXPECT_EQ(0, ictx->state->open(0));
c07f9fc5
FG
160 {
161 RWLock::WLocker snap_locker(ictx->snap_lock);
162 ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
163 }
7c673cae 164
c07f9fc5
FG
165 EXPECT_EQ(0, ictx->operations->snap_create(
166 cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
7c673cae
FG
167
168 if (protect) {
c07f9fc5
FG
169 EXPECT_EQ(0, ictx->operations->snap_protect(
170 cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
7c673cae
FG
171 }
172
7c673cae
FG
173 EXPECT_EQ(0, ictx->state->close());
174 }
175
176 std::string create_clone() {
177 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
178 false);
11fdf7f2 179 EXPECT_EQ(0, ictx->state->open(0));
c07f9fc5
FG
180 {
181 RWLock::WLocker snap_locker(ictx->snap_lock);
182 ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
183 }
184
185 EXPECT_EQ(0, ictx->operations->snap_create(
186 cls::rbd::UserSnapshotNamespace(), "snap1"));
187 EXPECT_EQ(0, ictx->operations->snap_protect(
188 cls::rbd::UserSnapshotNamespace(), "snap1"));
11fdf7f2
TL
189 EXPECT_EQ(0, librbd::api::Image<>::snap_set(
190 ictx, cls::rbd::UserSnapshotNamespace(), "snap1"));
c07f9fc5
FG
191
192 std::string clone_id = librbd::util::generate_image_id(m_local_io_ctx);
193 librbd::ImageOptions clone_opts;
194 clone_opts.set(RBD_IMAGE_OPTION_FEATURES, ictx->features);
11fdf7f2
TL
195 EXPECT_EQ(0, librbd::clone(m_local_io_ctx, m_local_image_id.c_str(),
196 nullptr, "snap1", m_local_io_ctx,
197 clone_id.c_str(), "clone1", clone_opts,
198 GLOBAL_CLONE_IMAGE_ID, m_remote_mirror_uuid));
c07f9fc5
FG
199
200 cls::rbd::MirrorImage mirror_image(
201 GLOBAL_CLONE_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
7c673cae
FG
202 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, clone_id,
203 mirror_image));
7c673cae 204 EXPECT_EQ(0, ictx->state->close());
7c673cae
FG
205 return clone_id;
206 }
207
208 void check_image_deleted() {
209 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
210 false);
11fdf7f2 211 EXPECT_EQ(-ENOENT, ictx->state->open(0));
7c673cae
FG
212
213 cls::rbd::MirrorImage mirror_image;
214 EXPECT_EQ(-ENOENT, cls_client::mirror_image_get(&m_local_io_ctx,
215 m_local_image_id,
216 &mirror_image));
217 }
218
11fdf7f2
TL
219 int trash_move(const std::string& global_image_id) {
220 C_SaferCond ctx;
221 rbd::mirror::ImageDeleter<>::trash_move(m_local_io_ctx, global_image_id,
222 true, m_threads->work_queue, &ctx);
223 return ctx.wait();
224 }
7c673cae
FG
225
226 librbd::RBD rbd;
227 std::string m_local_image_id;
c07f9fc5
FG
228 std::unique_ptr<rbd::mirror::ServiceDaemon<>> m_service_daemon;
229 rbd::mirror::ImageDeleter<> *m_deleter;
7c673cae
FG
230};
231
11fdf7f2
TL
232TEST_F(TestImageDeleter, ExistingTrashMove) {
233 ASSERT_EQ(0, trash_move(GLOBAL_IMAGE_ID));
c07f9fc5
FG
234
235 C_SaferCond ctx;
11fdf7f2
TL
236 m_deleter->wait_for_deletion(m_local_image_id, false, &ctx);
237 init_image_deleter();
c07f9fc5 238
11fdf7f2 239 ASSERT_EQ(0, ctx.wait());
c07f9fc5
FG
240}
241
11fdf7f2
TL
242TEST_F(TestImageDeleter, LiveTrashMove) {
243 init_image_deleter();
7c673cae
FG
244
245 C_SaferCond ctx;
11fdf7f2 246 m_deleter->wait_for_deletion(m_local_image_id, false, &ctx);
7c673cae 247
11fdf7f2
TL
248 ASSERT_EQ(0, trash_move(GLOBAL_IMAGE_ID));
249 ASSERT_EQ(0, ctx.wait());
7c673cae
FG
250}
251
11fdf7f2
TL
252TEST_F(TestImageDeleter, Delete_Image_With_Snapshots) {
253 init_image_deleter();
7c673cae
FG
254 create_snapshot("snap1");
255 create_snapshot("snap2");
256
7c673cae 257 C_SaferCond ctx;
11fdf7f2
TL
258 m_deleter->wait_for_deletion(m_local_image_id, false, &ctx);
259 ASSERT_EQ(0, trash_move(GLOBAL_IMAGE_ID));
7c673cae
FG
260 EXPECT_EQ(0, ctx.wait());
261
262 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
263 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
264}
265
11fdf7f2
TL
266TEST_F(TestImageDeleter, Delete_Image_With_ProtectedSnapshots) {
267 init_image_deleter();
7c673cae
FG
268 create_snapshot("snap1", true);
269 create_snapshot("snap2", true);
270
7c673cae 271 C_SaferCond ctx;
11fdf7f2
TL
272 m_deleter->wait_for_deletion(m_local_image_id, false, &ctx);
273 ASSERT_EQ(0, trash_move(GLOBAL_IMAGE_ID));
7c673cae
FG
274 EXPECT_EQ(0, ctx.wait());
275
276 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
277 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
278}
279
280TEST_F(TestImageDeleter, Delete_Image_With_Clone) {
11fdf7f2 281 init_image_deleter();
7c673cae
FG
282 std::string clone_id = create_clone();
283
11fdf7f2
TL
284 C_SaferCond ctx1;
285 m_deleter->set_busy_timer_interval(0.1);
286 m_deleter->wait_for_deletion(m_local_image_id, false, &ctx1);
287 ASSERT_EQ(0, trash_move(GLOBAL_IMAGE_ID));
288 EXPECT_EQ(-EBUSY, ctx1.wait());
7c673cae
FG
289
290 C_SaferCond ctx2;
11fdf7f2
TL
291 m_deleter->wait_for_deletion(clone_id, false, &ctx2);
292 ASSERT_EQ(0, trash_move(GLOBAL_CLONE_IMAGE_ID));
7c673cae
FG
293 EXPECT_EQ(0, ctx2.wait());
294
295 C_SaferCond ctx3;
11fdf7f2 296 m_deleter->wait_for_deletion(m_local_image_id, true, &ctx3);
7c673cae
FG
297 EXPECT_EQ(0, ctx3.wait());
298
299 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
300 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
301}
302