]> git.proxmox.com Git - ceph.git/blob - ceph/src/tools/rbd_mirror/ImageDeleter.h
import ceph quincy 17.2.4
[ceph.git] / ceph / src / tools / rbd_mirror / ImageDeleter.h
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
15 #ifndef CEPH_RBD_MIRROR_IMAGE_DELETER_H
16 #define CEPH_RBD_MIRROR_IMAGE_DELETER_H
17
18 #include "include/utime.h"
19 #include "common/AsyncOpTracker.h"
20 #include "common/ceph_mutex.h"
21 #include "common/Timer.h"
22 #include "tools/rbd_mirror/Types.h"
23 #include "tools/rbd_mirror/image_deleter/Types.h"
24 #include <atomic>
25 #include <deque>
26 #include <iosfwd>
27 #include <map>
28 #include <memory>
29 #include <vector>
30
31 class AdminSocketHook;
32 class Context;
33 namespace librbd {
34 struct ImageCtx;
35 namespace asio { struct ContextWQ; }
36 } // namespace librbd
37
38 namespace rbd {
39 namespace mirror {
40
41 template <typename> class ServiceDaemon;
42 template <typename> class Threads;
43 template <typename> class Throttler;
44
45 namespace image_deleter { template <typename> struct TrashWatcher; }
46
47 /**
48 * Manage deletion of non-primary images.
49 */
50 template <typename ImageCtxT = librbd::ImageCtx>
51 class ImageDeleter {
52 public:
53 static ImageDeleter* create(
54 librados::IoCtx& local_io_ctx, Threads<librbd::ImageCtx>* threads,
55 Throttler<librbd::ImageCtx>* image_deletion_throttler,
56 ServiceDaemon<librbd::ImageCtx>* service_daemon) {
57 return new ImageDeleter(local_io_ctx, threads, image_deletion_throttler,
58 service_daemon);
59 }
60
61 ImageDeleter(librados::IoCtx& local_io_ctx,
62 Threads<librbd::ImageCtx>* threads,
63 Throttler<librbd::ImageCtx>* image_deletion_throttler,
64 ServiceDaemon<librbd::ImageCtx>* service_daemon);
65
66 ImageDeleter(const ImageDeleter&) = delete;
67 ImageDeleter& operator=(const ImageDeleter&) = delete;
68
69 static void trash_move(librados::IoCtx& local_io_ctx,
70 const std::string& global_image_id, bool resync,
71 librbd::asio::ContextWQ* work_queue,
72 Context* on_finish);
73
74 void init(Context* on_finish);
75 void shut_down(Context* on_finish);
76
77 void print_status(Formatter *f);
78
79 // for testing purposes
80 void wait_for_deletion(const std::string &image_id,
81 bool scheduled_only, Context* on_finish);
82
83 std::vector<std::string> get_delete_queue_items();
84 std::vector<std::pair<std::string, int> > get_failed_queue_items();
85
86 inline void set_busy_timer_interval(double interval) {
87 m_busy_interval = interval;
88 }
89
90 private:
91 using clock_t = ceph::real_clock;
92 struct TrashListener : public image_deleter::TrashListener {
93 ImageDeleter *image_deleter;
94
95 TrashListener(ImageDeleter *image_deleter) : image_deleter(image_deleter) {
96 }
97
98 void handle_trash_image(const std::string& image_id,
99 const ceph::real_clock::time_point& deferment_end_time) override {
100 image_deleter->handle_trash_image(image_id, deferment_end_time);
101 }
102 };
103
104 struct DeleteInfo {
105 std::string image_id;
106
107 image_deleter::ErrorResult error_result = {};
108 int error_code = 0;
109 clock_t::time_point retry_time;
110 int retries = 0;
111
112 DeleteInfo(const std::string& image_id)
113 : image_id(image_id) {
114 }
115
116 inline bool operator==(const DeleteInfo& delete_info) const {
117 return (image_id == delete_info.image_id);
118 }
119
120 friend std::ostream& operator<<(std::ostream& os, DeleteInfo& delete_info) {
121 os << "[image_id=" << delete_info.image_id << "]";
122 return os;
123 }
124
125 void print_status(Formatter *f,
126 bool print_failure_info=false);
127 };
128 typedef std::shared_ptr<DeleteInfo> DeleteInfoRef;
129 typedef std::deque<DeleteInfoRef> DeleteQueue;
130 typedef std::map<std::string, Context*> OnDeleteContexts;
131
132 librados::IoCtx& m_local_io_ctx;
133 Threads<librbd::ImageCtx>* m_threads;
134 Throttler<librbd::ImageCtx>* m_image_deletion_throttler;
135 ServiceDaemon<librbd::ImageCtx>* m_service_daemon;
136
137 image_deleter::TrashWatcher<ImageCtxT>* m_trash_watcher = nullptr;
138 TrashListener m_trash_listener;
139
140 std::atomic<unsigned> m_running { 1 };
141
142 double m_busy_interval = 1;
143
144 AsyncOpTracker m_async_op_tracker;
145
146 ceph::mutex m_lock;
147 DeleteQueue m_delete_queue;
148 DeleteQueue m_retry_delete_queue;
149 DeleteQueue m_in_flight_delete_queue;
150
151 OnDeleteContexts m_on_delete_contexts;
152
153 AdminSocketHook *m_asok_hook = nullptr;
154
155 Context *m_timer_ctx = nullptr;
156
157 bool process_image_delete();
158
159 void complete_active_delete(DeleteInfoRef* delete_info, int r);
160 void enqueue_failed_delete(DeleteInfoRef* delete_info, int error_code,
161 double retry_delay);
162
163 DeleteInfoRef find_delete_info(const std::string &image_id);
164
165 void remove_images();
166 void remove_image(DeleteInfoRef delete_info);
167 void handle_remove_image(DeleteInfoRef delete_info, int r);
168
169 void schedule_retry_timer();
170 void cancel_retry_timer();
171 void handle_retry_timer();
172
173 void handle_trash_image(const std::string& image_id,
174 const clock_t::time_point& deferment_end_time);
175
176 void shut_down_trash_watcher(Context* on_finish);
177 void wait_for_ops(Context* on_finish);
178 void cancel_all_deletions(Context* on_finish);
179
180 void notify_on_delete(const std::string& image_id, int r);
181
182 };
183
184 } // namespace mirror
185 } // namespace rbd
186
187 extern template class rbd::mirror::ImageDeleter<librbd::ImageCtx>;
188
189 #endif // CEPH_RBD_MIRROR_IMAGE_DELETER_H