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