Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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_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
28 class AdminSocketHook;
29 class ContextWQ;
30 namespace librbd { struct ImageCtx; }
31
32 namespace rbd {
33 namespace mirror {
34
35 template <typename> class ServiceDaemon;
36
37 /**
38  * Manage deletion of non-primary images.
39  */
40 template <typename ImageCtxT = librbd::ImageCtx>
41 class ImageDeleter {
42 public:
43   static const int EISPRM = 1000;
44
45   ImageDeleter(ContextWQ *work_queue, SafeTimer *timer, Mutex *timer_lock,
46                ServiceDaemon<librbd::ImageCtx>* service_daemon);
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,
53                              const std::string& global_image_id,
54                              bool ignore_orphaned);
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;
86     bool ignore_orphaned;
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,
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) {
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
109   std::atomic<unsigned> m_running { 1 };
110
111   ContextWQ *m_work_queue;
112   ServiceDaemon<librbd::ImageCtx>* m_service_daemon;
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
127   AdminSocketHook *m_asok_hook;
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
147 extern template class rbd::mirror::ImageDeleter<librbd::ImageCtx>;
148
149 #endif // CEPH_RBD_MIRROR_IMAGEDELETER_H