summaryrefslogtreecommitdiffstats
path: root/src/tools/rbd_mirror/image_deleter/TrashWatcher.h
blob: e818a102c920199b895274874b7059926dd6997e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_RBD_MIRROR_IMAGE_DELETE_TRASH_WATCHER_H
#define CEPH_RBD_MIRROR_IMAGE_DELETE_TRASH_WATCHER_H

#include "include/rados/librados.hpp"
#include "common/AsyncOpTracker.h"
#include "common/ceph_mutex.h"
#include "librbd/TrashWatcher.h"
#include <set>
#include <string>

struct Context;
namespace librbd { struct ImageCtx; }

namespace rbd {
namespace mirror {

template <typename> struct Threads;

namespace image_deleter {

struct TrashListener;

template <typename ImageCtxT = librbd::ImageCtx>
class TrashWatcher : public librbd::TrashWatcher<ImageCtxT> {
public:
  static TrashWatcher* create(librados::IoCtx &io_ctx,
                              Threads<ImageCtxT> *threads,
                              TrashListener& trash_listener) {
    return new TrashWatcher(io_ctx, threads, trash_listener);
  }

  TrashWatcher(librados::IoCtx &io_ctx, Threads<ImageCtxT> *threads,
               TrashListener& trash_listener);
  TrashWatcher(const TrashWatcher&) = delete;
  TrashWatcher& operator=(const TrashWatcher&) = delete;

  void init(Context *on_finish);
  void shut_down(Context *on_finish);

protected:
  void handle_image_added(const std::string &image_id,
                          const cls::rbd::TrashImageSpec& spec) override;

  void handle_image_removed(const std::string &image_id) override;

  void handle_rewatch_complete(int r) override;

private:
  /**
   * @verbatim
   *
   * <start>
   *    |
   *    v
   *  INIT
   *    |
   *    v
   * CREATE_TRASH
   *    |
   *    v
   * REGISTER_WATCHER
   *    |
   *    |/--------------------------------\
   *    |                                 |
   *    |/---------\                      |
   *    |          |                      |
   *    v          | (more images)        |
   * TRASH_LIST ---/                      |
   *    |                                 |
   *    |/----------------------------\   |
   *    |                             |   |
   *    v                             |   |
   * <idle> --\                       |   |
   *    |     |                       |   |
   *    |     |\---> IMAGE_ADDED -----/   |
   *    |     |                           |
   *    |     \----> WATCH_ERROR ---------/
   *    v
   * SHUT_DOWN
   *    |
   *    v
   * UNREGISTER_WATCHER
   *    |
   *    v
   * <finish>
   *
   * @endverbatim
   */

  librados::IoCtx m_io_ctx;
  Threads<ImageCtxT> *m_threads;
  TrashListener& m_trash_listener;

  std::string m_last_image_id;
  bufferlist m_out_bl;

  mutable ceph::mutex m_lock;

  Context *m_on_init_finish = nullptr;
  Context *m_timer_ctx = nullptr;

  AsyncOpTracker m_async_op_tracker;
  bool m_trash_list_in_progress = false;
  bool m_deferred_trash_list = false;
  bool m_shutting_down = false;

  void register_watcher();
  void handle_register_watcher(int r);

  void create_trash();
  void handle_create_trash(int r);

  void unregister_watcher(Context* on_finish);
  void handle_unregister_watcher(int r, Context* on_finish);

  void trash_list(bool initial_request);
  void handle_trash_list(int r);

  void schedule_trash_list(double interval);
  void process_trash_list();

  void get_mirror_uuid();
  void handle_get_mirror_uuid(int r);

  void add_image(const std::string& image_id,
                 const cls::rbd::TrashImageSpec& spec);

};

} // namespace image_deleter
} // namespace mirror
} // namespace rbd

extern template class rbd::mirror::image_deleter::TrashWatcher<librbd::ImageCtx>;

#endif // CEPH_RBD_MIRROR_IMAGE_DELETE_TRASH_WATCHER_H