]>
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 | ||
15 | #ifndef CEPH_RBD_MIRROR_IMAGEDELETER_H | |
16 | #define CEPH_RBD_MIRROR_IMAGEDELETER_H | |
17 | ||
18 | #include "common/Mutex.h" | |
19 | #include "common/Cond.h" | |
20 | #include "common/Thread.h" | |
21 | #include "common/Timer.h" | |
22 | #include "types.h" | |
23 | ||
24 | #include <deque> | |
25 | #include <vector> | |
26 | #include <atomic> | |
27 | ||
c07f9fc5 | 28 | class AdminSocketHook; |
7c673cae | 29 | class ContextWQ; |
c07f9fc5 | 30 | namespace librbd { struct ImageCtx; } |
7c673cae FG |
31 | |
32 | namespace rbd { | |
33 | namespace mirror { | |
34 | ||
c07f9fc5 | 35 | template <typename> class ServiceDaemon; |
7c673cae FG |
36 | |
37 | /** | |
38 | * Manage deletion of non-primary images. | |
39 | */ | |
c07f9fc5 | 40 | template <typename ImageCtxT = librbd::ImageCtx> |
7c673cae FG |
41 | class ImageDeleter { |
42 | public: | |
43 | static const int EISPRM = 1000; | |
44 | ||
c07f9fc5 FG |
45 | ImageDeleter(ContextWQ *work_queue, SafeTimer *timer, Mutex *timer_lock, |
46 | ServiceDaemon<librbd::ImageCtx>* service_daemon); | |
7c673cae FG |
47 | ~ImageDeleter(); |
48 | ImageDeleter(const ImageDeleter&) = delete; | |
49 | ImageDeleter& operator=(const ImageDeleter&) = delete; | |
50 | ||
51 | void schedule_image_delete(RadosRef local_rados, | |
52 | int64_t local_pool_id, | |
c07f9fc5 FG |
53 | const std::string& global_image_id, |
54 | bool ignore_orphaned); | |
7c673cae FG |
55 | void wait_for_scheduled_deletion(int64_t local_pool_id, |
56 | const std::string &global_image_id, | |
57 | Context *ctx, | |
58 | bool notify_on_failed_retry=true); | |
59 | void cancel_waiter(int64_t local_pool_id, | |
60 | const std::string &global_image_id); | |
61 | ||
62 | void print_status(Formatter *f, std::stringstream *ss); | |
63 | ||
64 | // for testing purposes | |
65 | std::vector<std::string> get_delete_queue_items(); | |
66 | std::vector<std::pair<std::string, int> > get_failed_queue_items(); | |
67 | void set_failed_timer_interval(double interval); | |
68 | ||
69 | private: | |
70 | ||
71 | class ImageDeleterThread : public Thread { | |
72 | ImageDeleter *m_image_deleter; | |
73 | public: | |
74 | ImageDeleterThread(ImageDeleter *image_deleter) : | |
75 | m_image_deleter(image_deleter) {} | |
76 | void *entry() override { | |
77 | m_image_deleter->run(); | |
78 | return 0; | |
79 | } | |
80 | }; | |
81 | ||
82 | struct DeleteInfo { | |
83 | RadosRef local_rados; | |
84 | int64_t local_pool_id; | |
85 | std::string global_image_id; | |
c07f9fc5 | 86 | bool ignore_orphaned; |
7c673cae FG |
87 | int error_code = 0; |
88 | int retries = 0; | |
89 | bool notify_on_failed_retry = true; | |
90 | Context *on_delete = nullptr; | |
91 | ||
92 | DeleteInfo(RadosRef local_rados, int64_t local_pool_id, | |
c07f9fc5 FG |
93 | const std::string& global_image_id, |
94 | bool ignore_orphaned) | |
95 | : local_rados(local_rados), local_pool_id(local_pool_id), | |
96 | global_image_id(global_image_id), ignore_orphaned(ignore_orphaned) { | |
7c673cae FG |
97 | } |
98 | ||
99 | bool match(int64_t local_pool_id, const std::string &global_image_id) { | |
100 | return (this->local_pool_id == local_pool_id && | |
101 | this->global_image_id == global_image_id); | |
102 | } | |
103 | void notify(int r); | |
104 | void to_string(std::stringstream& ss); | |
105 | void print_status(Formatter *f, std::stringstream *ss, | |
106 | bool print_failure_info=false); | |
107 | }; | |
108 | ||
c07f9fc5 | 109 | std::atomic<unsigned> m_running { 1 }; |
7c673cae FG |
110 | |
111 | ContextWQ *m_work_queue; | |
c07f9fc5 | 112 | ServiceDaemon<librbd::ImageCtx>* m_service_daemon; |
7c673cae FG |
113 | |
114 | std::deque<std::unique_ptr<DeleteInfo> > m_delete_queue; | |
115 | Mutex m_delete_lock; | |
116 | Cond m_delete_queue_cond; | |
117 | ||
118 | unique_ptr<DeleteInfo> m_active_delete; | |
119 | ||
120 | ImageDeleterThread m_image_deleter_thread; | |
121 | ||
122 | std::deque<std::unique_ptr<DeleteInfo>> m_failed_queue; | |
123 | double m_failed_interval; | |
124 | SafeTimer *m_failed_timer; | |
125 | Mutex *m_failed_timer_lock; | |
126 | ||
c07f9fc5 | 127 | AdminSocketHook *m_asok_hook; |
7c673cae FG |
128 | |
129 | void run(); | |
130 | bool process_image_delete(); | |
131 | int image_has_snapshots_and_children(librados::IoCtx *ioctx, | |
132 | std::string& image_id, | |
133 | bool *has_snapshots); | |
134 | ||
135 | void complete_active_delete(int r); | |
136 | void enqueue_failed_delete(int error_code); | |
137 | void retry_failed_deletions(); | |
138 | ||
139 | unique_ptr<DeleteInfo> const* | |
140 | find_delete_info(int64_t local_pool_id, const std::string &global_image_id); | |
141 | ||
142 | }; | |
143 | ||
144 | } // namespace mirror | |
145 | } // namespace rbd | |
146 | ||
c07f9fc5 FG |
147 | extern template class rbd::mirror::ImageDeleter<librbd::ImageCtx>; |
148 | ||
7c673cae | 149 | #endif // CEPH_RBD_MIRROR_IMAGEDELETER_H |