]>
Commit | Line | Data |
---|---|---|
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 | ||
11fdf7f2 TL |
15 | #ifndef CEPH_RBD_MIRROR_IMAGE_DELETER_H |
16 | #define CEPH_RBD_MIRROR_IMAGE_DELETER_H | |
7c673cae | 17 | |
11fdf7f2 TL |
18 | #include "include/utime.h" |
19 | #include "common/AsyncOpTracker.h" | |
9f95a23c | 20 | #include "common/ceph_mutex.h" |
a4b75251 | 21 | #include "common/Timer.h" |
11fdf7f2 TL |
22 | #include "tools/rbd_mirror/Types.h" |
23 | #include "tools/rbd_mirror/image_deleter/Types.h" | |
24 | #include <atomic> | |
7c673cae | 25 | #include <deque> |
11fdf7f2 TL |
26 | #include <iosfwd> |
27 | #include <map> | |
28 | #include <memory> | |
7c673cae | 29 | #include <vector> |
7c673cae | 30 | |
c07f9fc5 | 31 | class AdminSocketHook; |
11fdf7f2 | 32 | class Context; |
f67539c2 TL |
33 | namespace librbd { |
34 | struct ImageCtx; | |
35 | namespace asio { struct ContextWQ; } | |
36 | } // namespace librbd | |
7c673cae FG |
37 | |
38 | namespace rbd { | |
39 | namespace mirror { | |
40 | ||
c07f9fc5 | 41 | template <typename> class ServiceDaemon; |
11fdf7f2 | 42 | template <typename> class Threads; |
9f95a23c | 43 | template <typename> class Throttler; |
11fdf7f2 TL |
44 | |
45 | namespace image_deleter { template <typename> struct TrashWatcher; } | |
7c673cae FG |
46 | |
47 | /** | |
48 | * Manage deletion of non-primary images. | |
49 | */ | |
c07f9fc5 | 50 | template <typename ImageCtxT = librbd::ImageCtx> |
7c673cae FG |
51 | class ImageDeleter { |
52 | public: | |
9f95a23c TL |
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); | |
11fdf7f2 TL |
59 | } |
60 | ||
61 | ImageDeleter(librados::IoCtx& local_io_ctx, | |
62 | Threads<librbd::ImageCtx>* threads, | |
9f95a23c | 63 | Throttler<librbd::ImageCtx>* image_deletion_throttler, |
c07f9fc5 | 64 | ServiceDaemon<librbd::ImageCtx>* service_daemon); |
11fdf7f2 | 65 | |
7c673cae FG |
66 | ImageDeleter(const ImageDeleter&) = delete; |
67 | ImageDeleter& operator=(const ImageDeleter&) = delete; | |
68 | ||
11fdf7f2 TL |
69 | static void trash_move(librados::IoCtx& local_io_ctx, |
70 | const std::string& global_image_id, bool resync, | |
f67539c2 TL |
71 | librbd::asio::ContextWQ* work_queue, |
72 | Context* on_finish); | |
11fdf7f2 TL |
73 | |
74 | void init(Context* on_finish); | |
75 | void shut_down(Context* on_finish); | |
7c673cae | 76 | |
9f95a23c | 77 | void print_status(Formatter *f); |
7c673cae FG |
78 | |
79 | // for testing purposes | |
11fdf7f2 TL |
80 | void wait_for_deletion(const std::string &image_id, |
81 | bool scheduled_only, Context* on_finish); | |
82 | ||
7c673cae FG |
83 | std::vector<std::string> get_delete_queue_items(); |
84 | std::vector<std::pair<std::string, int> > get_failed_queue_items(); | |
11fdf7f2 TL |
85 | |
86 | inline void set_busy_timer_interval(double interval) { | |
87 | m_busy_interval = interval; | |
88 | } | |
7c673cae FG |
89 | |
90 | private: | |
9f95a23c | 91 | using clock_t = ceph::real_clock; |
11fdf7f2 TL |
92 | struct TrashListener : public image_deleter::TrashListener { |
93 | ImageDeleter *image_deleter; | |
94 | ||
95 | TrashListener(ImageDeleter *image_deleter) : image_deleter(image_deleter) { | |
96 | } | |
7c673cae | 97 | |
11fdf7f2 | 98 | void handle_trash_image(const std::string& image_id, |
9f95a23c | 99 | const ceph::real_clock::time_point& deferment_end_time) override { |
11fdf7f2 | 100 | image_deleter->handle_trash_image(image_id, deferment_end_time); |
7c673cae FG |
101 | } |
102 | }; | |
103 | ||
104 | struct DeleteInfo { | |
11fdf7f2 TL |
105 | std::string image_id; |
106 | ||
107 | image_deleter::ErrorResult error_result = {}; | |
7c673cae | 108 | int error_code = 0; |
9f95a23c | 109 | clock_t::time_point retry_time; |
7c673cae | 110 | int retries = 0; |
11fdf7f2 TL |
111 | |
112 | DeleteInfo(const std::string& image_id) | |
113 | : image_id(image_id) { | |
7c673cae FG |
114 | } |
115 | ||
11fdf7f2 TL |
116 | inline bool operator==(const DeleteInfo& delete_info) const { |
117 | return (image_id == delete_info.image_id); | |
7c673cae | 118 | } |
11fdf7f2 TL |
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 | ||
9f95a23c | 125 | void print_status(Formatter *f, |
7c673cae FG |
126 | bool print_failure_info=false); |
127 | }; | |
11fdf7f2 TL |
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; | |
9f95a23c | 134 | Throttler<librbd::ImageCtx>* m_image_deletion_throttler; |
11fdf7f2 TL |
135 | ServiceDaemon<librbd::ImageCtx>* m_service_daemon; |
136 | ||
137 | image_deleter::TrashWatcher<ImageCtxT>* m_trash_watcher = nullptr; | |
138 | TrashListener m_trash_listener; | |
7c673cae | 139 | |
c07f9fc5 | 140 | std::atomic<unsigned> m_running { 1 }; |
7c673cae | 141 | |
11fdf7f2 | 142 | double m_busy_interval = 1; |
7c673cae | 143 | |
11fdf7f2 | 144 | AsyncOpTracker m_async_op_tracker; |
7c673cae | 145 | |
9f95a23c | 146 | ceph::mutex m_lock; |
11fdf7f2 TL |
147 | DeleteQueue m_delete_queue; |
148 | DeleteQueue m_retry_delete_queue; | |
149 | DeleteQueue m_in_flight_delete_queue; | |
7c673cae | 150 | |
11fdf7f2 | 151 | OnDeleteContexts m_on_delete_contexts; |
7c673cae | 152 | |
11fdf7f2 | 153 | AdminSocketHook *m_asok_hook = nullptr; |
7c673cae | 154 | |
11fdf7f2 | 155 | Context *m_timer_ctx = nullptr; |
7c673cae | 156 | |
7c673cae | 157 | bool process_image_delete(); |
7c673cae | 158 | |
11fdf7f2 TL |
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, | |
9f95a23c | 174 | const clock_t::time_point& deferment_end_time); |
11fdf7f2 TL |
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); | |
7c673cae | 179 | |
11fdf7f2 | 180 | void notify_on_delete(const std::string& image_id, int r); |
7c673cae FG |
181 | |
182 | }; | |
183 | ||
184 | } // namespace mirror | |
185 | } // namespace rbd | |
186 | ||
c07f9fc5 FG |
187 | extern template class rbd::mirror::ImageDeleter<librbd::ImageCtx>; |
188 | ||
11fdf7f2 | 189 | #endif // CEPH_RBD_MIRROR_IMAGE_DELETER_H |