]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/test_ImageDeleter.cc
update sources to v12.1.2
[ceph.git] / ceph / src / test / rbd_mirror / test_ImageDeleter.cc
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"
20 #include "tools/rbd_mirror/ImageReplayer.h"
21 #include "tools/rbd_mirror/ServiceDaemon.h"
22 #include "tools/rbd_mirror/Threads.h"
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"
29 #include "librbd/api/Mirror.h"
30 #include "librbd/journal/DisabledPolicy.h"
31 #include "test/rbd_mirror/test_fixture.h"
32
33 #include "test/librados/test.h"
34 #include "gtest/gtest.h"
35
36 #define GLOBAL_IMAGE_ID "global_image_id"
37 #define GLOBAL_CLONE_IMAGE_ID "global_image_id_clone"
38
39 #define dout_subsys ceph_subsys_rbd_mirror
40
41 using rbd::mirror::RadosRef;
42 using rbd::mirror::TestFixture;
43 using namespace librbd;
44 using cls::rbd::MirrorImageState;
45
46
47 void register_test_rbd_mirror_image_deleter() {
48 }
49
50 class TestImageDeleter : public TestFixture {
51 public:
52
53 static int64_t m_local_pool_id;
54
55 const std::string m_local_mirror_uuid = "local mirror uuid";
56 const std::string m_remote_mirror_uuid = "remote mirror uuid";
57
58 static void SetUpTestCase() {
59 TestFixture::SetUpTestCase();
60
61 m_local_pool_id = _rados->pool_lookup(_local_pool_name.c_str());
62 }
63
64 void SetUp() override {
65 TestFixture::SetUp();
66 m_service_daemon.reset(new rbd::mirror::ServiceDaemon<>(g_ceph_context,
67 _rados, m_threads));
68
69 librbd::api::Mirror<>::mode_set(m_local_io_ctx, RBD_MIRROR_MODE_IMAGE);
70
71 m_deleter = new rbd::mirror::ImageDeleter<>(m_threads->work_queue,
72 m_threads->timer,
73 &m_threads->timer_lock,
74 m_service_daemon.get());
75
76 m_local_image_id = librbd::util::generate_image_id(m_local_io_ctx);
77 librbd::ImageOptions image_opts;
78 image_opts.set(RBD_IMAGE_OPTION_FEATURES, RBD_FEATURES_ALL);
79 EXPECT_EQ(0, librbd::create(m_local_io_ctx, m_image_name, m_local_image_id,
80 1 << 20, image_opts, GLOBAL_IMAGE_ID,
81 m_remote_mirror_uuid, true));
82
83 cls::rbd::MirrorImage mirror_image(
84 GLOBAL_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
85 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
86 mirror_image));
87 }
88
89 void TearDown() override {
90 remove_image();
91 delete m_deleter;
92 m_service_daemon.reset();
93
94 TestFixture::TearDown();
95 }
96
97 void remove_image(bool force=false) {
98 if (!force) {
99 cls::rbd::MirrorImage mirror_image;
100 int r = cls_client::mirror_image_get(&m_local_io_ctx, m_local_image_id,
101 &mirror_image);
102 EXPECT_EQ(1, r == 0 || r == -ENOENT);
103 if (r != -ENOENT) {
104 mirror_image.state = MirrorImageState::MIRROR_IMAGE_STATE_ENABLED;
105 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx,
106 m_local_image_id,
107 mirror_image));
108 }
109 promote_image();
110 }
111 NoOpProgressContext ctx;
112 int r = remove(m_local_io_ctx, m_image_name, "", ctx, force);
113 EXPECT_EQ(1, r == 0 || r == -ENOENT);
114 }
115
116 void promote_image(ImageCtx *ictx=nullptr) {
117 bool close = false;
118 int r = 0;
119 if (!ictx) {
120 ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
121 false);
122 r = ictx->state->open(false);
123 close = (r == 0);
124 }
125
126 EXPECT_EQ(1, r == 0 || r == -ENOENT);
127
128 if (r == 0) {
129 int r2 = librbd::api::Mirror<>::image_promote(ictx, true);
130 EXPECT_EQ(1, r2 == 0 || r2 == -EINVAL);
131 }
132
133 if (close) {
134 EXPECT_EQ(0, ictx->state->close());
135 }
136 }
137
138 void demote_image(ImageCtx *ictx=nullptr) {
139 bool close = false;
140 if (!ictx) {
141 ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
142 false);
143 EXPECT_EQ(0, ictx->state->open(false));
144 close = true;
145 }
146
147 EXPECT_EQ(0, librbd::api::Mirror<>::image_demote(ictx));
148
149 if (close) {
150 EXPECT_EQ(0, ictx->state->close());
151 }
152 }
153
154 void create_snapshot(std::string snap_name="snap1", bool protect=false) {
155 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
156 false);
157 EXPECT_EQ(0, ictx->state->open(false));
158 {
159 RWLock::WLocker snap_locker(ictx->snap_lock);
160 ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
161 }
162
163 EXPECT_EQ(0, ictx->operations->snap_create(
164 cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
165
166 if (protect) {
167 EXPECT_EQ(0, ictx->operations->snap_protect(
168 cls::rbd::UserSnapshotNamespace(), snap_name.c_str()));
169 }
170
171 EXPECT_EQ(0, ictx->state->close());
172 }
173
174 std::string create_clone() {
175 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
176 false);
177 EXPECT_EQ(0, ictx->state->open(false));
178 {
179 RWLock::WLocker snap_locker(ictx->snap_lock);
180 ictx->set_journal_policy(new librbd::journal::DisabledPolicy());
181 }
182
183 EXPECT_EQ(0, ictx->operations->snap_create(
184 cls::rbd::UserSnapshotNamespace(), "snap1"));
185 EXPECT_EQ(0, ictx->operations->snap_protect(
186 cls::rbd::UserSnapshotNamespace(), "snap1"));
187 EXPECT_EQ(0, librbd::snap_set(ictx, cls::rbd::UserSnapshotNamespace(),
188 "snap1"));
189
190 std::string clone_id = librbd::util::generate_image_id(m_local_io_ctx);
191 librbd::ImageOptions clone_opts;
192 clone_opts.set(RBD_IMAGE_OPTION_FEATURES, ictx->features);
193 EXPECT_EQ(0, librbd::clone(ictx, m_local_io_ctx, "clone1", clone_id,
194 clone_opts, GLOBAL_CLONE_IMAGE_ID,
195 m_remote_mirror_uuid));
196
197 cls::rbd::MirrorImage mirror_image(
198 GLOBAL_CLONE_IMAGE_ID, MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
199 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, clone_id,
200 mirror_image));
201 EXPECT_EQ(0, ictx->state->close());
202 return clone_id;
203 }
204
205 void check_image_deleted() {
206 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
207 false);
208 EXPECT_EQ(-ENOENT, ictx->state->open(false));
209
210 cls::rbd::MirrorImage mirror_image;
211 EXPECT_EQ(-ENOENT, cls_client::mirror_image_get(&m_local_io_ctx,
212 m_local_image_id,
213 &mirror_image));
214 }
215
216
217 librbd::RBD rbd;
218 std::string m_local_image_id;
219 std::unique_ptr<rbd::mirror::ServiceDaemon<>> m_service_daemon;
220 rbd::mirror::ImageDeleter<> *m_deleter;
221 };
222
223 int64_t TestImageDeleter::m_local_pool_id;
224
225
226 TEST_F(TestImageDeleter, Delete_NonPrimary_Image) {
227 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
228 false);
229
230 C_SaferCond ctx;
231 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
232 &ctx);
233 EXPECT_EQ(0, ctx.wait());
234
235 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
236 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
237
238 check_image_deleted();
239 }
240
241 TEST_F(TestImageDeleter, Delete_Split_Brain_Image) {
242 promote_image();
243 demote_image();
244
245 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
246 true);
247
248 C_SaferCond ctx;
249 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
250 &ctx);
251 EXPECT_EQ(0, ctx.wait());
252
253 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
254 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
255
256 check_image_deleted();
257 }
258
259 TEST_F(TestImageDeleter, Fail_Delete_Primary_Image) {
260 promote_image();
261
262 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
263 false);
264
265 C_SaferCond ctx;
266 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
267 &ctx);
268 EXPECT_EQ(-rbd::mirror::ImageDeleter<>::EISPRM, ctx.wait());
269
270 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
271 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
272 }
273
274 TEST_F(TestImageDeleter, Fail_Delete_Orphan_Image) {
275 promote_image();
276 demote_image();
277
278 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
279 false);
280
281 C_SaferCond ctx;
282 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
283 &ctx);
284 EXPECT_EQ(-rbd::mirror::ImageDeleter<>::EISPRM, ctx.wait());
285
286 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
287 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
288 }
289
290 TEST_F(TestImageDeleter, Delete_Image_With_Child) {
291 create_snapshot();
292
293 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
294 false);
295
296 C_SaferCond ctx;
297 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
298 &ctx);
299 EXPECT_EQ(0, ctx.wait());
300
301 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
302 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
303 }
304
305 TEST_F(TestImageDeleter, Delete_Image_With_Children) {
306 create_snapshot("snap1");
307 create_snapshot("snap2");
308
309 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
310 false);
311
312 C_SaferCond ctx;
313 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
314 &ctx);
315 EXPECT_EQ(0, ctx.wait());
316
317 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
318 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
319 }
320
321 TEST_F(TestImageDeleter, Delete_Image_With_ProtectedChild) {
322 create_snapshot("snap1", true);
323
324 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
325 false);
326
327 C_SaferCond ctx;
328 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
329 &ctx);
330 EXPECT_EQ(0, ctx.wait());
331
332 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
333 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
334 }
335
336 TEST_F(TestImageDeleter, Delete_Image_With_ProtectedChildren) {
337 create_snapshot("snap1", true);
338 create_snapshot("snap2", true);
339
340 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
341 false);
342
343 C_SaferCond ctx;
344 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
345 &ctx);
346 EXPECT_EQ(0, ctx.wait());
347
348 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
349 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
350 }
351
352 TEST_F(TestImageDeleter, Delete_Image_With_Clone) {
353 std::string clone_id = create_clone();
354
355 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
356 false);
357
358 C_SaferCond ctx;
359 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
360 &ctx);
361 EXPECT_EQ(-EBUSY, ctx.wait());
362
363 ASSERT_EQ(1u, m_deleter->get_delete_queue_items().size());
364 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
365
366 m_deleter->schedule_image_delete(_rados, m_local_pool_id,
367 GLOBAL_CLONE_IMAGE_ID, false);
368
369 C_SaferCond ctx2;
370 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_CLONE_IMAGE_ID,
371 &ctx2);
372 EXPECT_EQ(0, ctx2.wait());
373
374 C_SaferCond ctx3;
375 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
376 &ctx3);
377 EXPECT_EQ(0, ctx3.wait());
378
379 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
380 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
381 }
382
383 TEST_F(TestImageDeleter, Delete_NonExistent_Image) {
384 remove_image();
385
386 cls::rbd::MirrorImage mirror_image(GLOBAL_IMAGE_ID,
387 MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
388 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
389 mirror_image));
390
391 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
392 false);
393
394 C_SaferCond ctx;
395 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
396 &ctx);
397 EXPECT_EQ(0, ctx.wait());
398
399 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
400 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
401
402 check_image_deleted();
403 }
404
405 TEST_F(TestImageDeleter, Delete_NonExistent_Image_With_MirroringState) {
406 remove_image(true);
407
408 cls::rbd::MirrorImage mirror_image(GLOBAL_IMAGE_ID,
409 MirrorImageState::MIRROR_IMAGE_STATE_ENABLED);
410 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
411 mirror_image));
412 mirror_image.state = MirrorImageState::MIRROR_IMAGE_STATE_DISABLING;
413 EXPECT_EQ(0, cls_client::mirror_image_set(&m_local_io_ctx, m_local_image_id,
414 mirror_image));
415
416 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
417 false);
418
419 C_SaferCond ctx;
420 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
421 &ctx);
422 EXPECT_EQ(0, ctx.wait());
423
424 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
425 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
426
427 check_image_deleted();
428 }
429
430 TEST_F(TestImageDeleter, Delete_NonExistent_Image_Without_MirroringState) {
431 remove_image();
432
433 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
434 false);
435
436 C_SaferCond ctx;
437 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
438 &ctx);
439 EXPECT_EQ(-ENOENT, ctx.wait());
440
441 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
442 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
443
444 check_image_deleted();
445 }
446
447 TEST_F(TestImageDeleter, Fail_Delete_NonPrimary_Image) {
448 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
449 false);
450 EXPECT_EQ(0, ictx->state->open(false));
451
452 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
453 false);
454
455 C_SaferCond ctx;
456 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
457 &ctx);
458 EXPECT_EQ(-EBUSY, ctx.wait());
459
460 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
461 ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
462
463 EXPECT_EQ(0, ictx->state->close());
464 }
465
466 TEST_F(TestImageDeleter, Retry_Failed_Deletes) {
467 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
468 false);
469 EXPECT_EQ(0, ictx->state->open(false));
470
471 m_deleter->set_failed_timer_interval(2);
472
473 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
474 false);
475
476 C_SaferCond ctx;
477 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
478 &ctx);
479 EXPECT_EQ(-EBUSY, ctx.wait());
480
481 EXPECT_EQ(0, ictx->state->close());
482
483 C_SaferCond ctx2;
484 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
485 &ctx2);
486 EXPECT_EQ(0, ctx2.wait());
487
488 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
489 ASSERT_EQ(0u, m_deleter->get_failed_queue_items().size());
490
491 check_image_deleted();
492 }
493
494 TEST_F(TestImageDeleter, Delete_Is_Idempotent) {
495 ImageCtx *ictx = new ImageCtx("", m_local_image_id, "", m_local_io_ctx,
496 false);
497 EXPECT_EQ(0, ictx->state->open(false));
498
499 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
500 false);
501
502 C_SaferCond ctx;
503 m_deleter->wait_for_scheduled_deletion(m_local_pool_id, GLOBAL_IMAGE_ID,
504 &ctx);
505 EXPECT_EQ(-EBUSY, ctx.wait());
506
507 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
508 ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
509
510 m_deleter->schedule_image_delete(_rados, m_local_pool_id, GLOBAL_IMAGE_ID,
511 false);
512
513 ASSERT_EQ(0u, m_deleter->get_delete_queue_items().size());
514 ASSERT_EQ(1u, m_deleter->get_failed_queue_items().size());
515
516 EXPECT_EQ(0, ictx->state->close());
517 }
518
519