summaryrefslogtreecommitdiffstats
path: root/src/librbd/mirror/DisableRequest.h
blob: f45d1a14cee7d5b52a91c8c218876411df54ebf7 (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
140
141
142
143
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_LIBRBD_MIRROR_DISABLE_REQUEST_H
#define CEPH_LIBRBD_MIRROR_DISABLE_REQUEST_H

#include "include/buffer.h"
#include "common/ceph_mutex.h"
#include "cls/journal/cls_journal_types.h"
#include "cls/rbd/cls_rbd_types.h"
#include "librbd/mirror/Types.h"

#include <map>
#include <string>

class Context;

namespace librbd {

class ImageCtx;

namespace mirror {

template <typename ImageCtxT = ImageCtx>
class DisableRequest {
public:
  static DisableRequest *create(ImageCtxT *image_ctx, bool force,
                                bool remove, Context *on_finish) {
    return new DisableRequest(image_ctx, force, remove, on_finish);
  }

  DisableRequest(ImageCtxT *image_ctx, bool force, bool remove,
                 Context *on_finish);

  void send();

private:
  /**
   * @verbatim
   *
   * <start>
   *    |
   *    v
   * GET_MIRROR_INFO  * * * * * * * * * * * * * * * * * * * * * * *
   *    |                                                         *
   *    v                                                         *
   * IMAGE_STATE_UPDATE * * * * * * * * * * * * * * * * * * * * * *
   *    |                                                         *
   *    v                                                         *
   * PROMOTE_IMAGE (skip if primary)                              *
   *    |                                                         *
   *    v                                                         *
   * REFRESH_IMAGE (skip if necessary)                            *
   *    |                                                         *
   *    v                                                         *
   * GET_CLIENTS <----------------------------------------\ * * * *
   *    |     | (unregister clients)                      |       *  (on error)
   *    |     |/----------------------------\             |       *
   *    |     |                             |             |       *
   *    |     |   /-----------\ (repeat     | (repeat     | (repeat
   *    |     |   |           |  as needed) |  as needed) |  as needed)
   *    |     v   v           |             |             |       *
   *    |  REMOVE_SYNC_SNAP --/ * * * * * * | * * * * * * | * * * *
   *    |     |                             |             |       *
   *    |     v                             |             |       *
   *    |  UNREGISTER_CLIENT ---------------/-------------/ * * * *
   *    |                                                         *
   *    | (no more clients                                        *
   *    |  to unregister)                                         *
   *    v                                                         *
   * REMOVE_MIRROR_IMAGE  * * * * * * * * * * * * * * * * * * * * *
   *    |         (skip if no remove)                             *
   *    v                                                         *
   * <finish> < * * * * * * * * * * * * * * * * * * * * * * * * * *
   *
   * @endverbatim
   */

  ImageCtxT *m_image_ctx;
  bool m_force;
  bool m_remove;
  Context *m_on_finish;

  bool m_is_primary = false;
  cls::rbd::MirrorImage m_mirror_image;
  PromotionState m_promotion_state = PROMOTION_STATE_NON_PRIMARY;
  std::string m_primary_mirror_uuid;
  std::set<cls::journal::Client> m_clients;
  std::map<std::string, int> m_ret;
  std::map<std::string, int> m_current_ops;
  int m_error_result = 0;
  mutable ceph::mutex m_lock =
    ceph::make_mutex("mirror::DisableRequest::m_lock");

  void send_get_mirror_info();
  Context *handle_get_mirror_info(int *result);

  void send_image_state_update();
  Context *handle_image_state_update(int *result);

  void send_notify_mirroring_watcher();
  Context *handle_notify_mirroring_watcher(int *result);

  void send_promote_image();
  Context *handle_promote_image(int *result);

  void send_refresh_image();
  Context* handle_refresh_image(int* result);

  void clean_mirror_state();

  void send_get_clients();
  Context *handle_get_clients(int *result);

  void remove_mirror_snapshots();

  void send_remove_snap(const std::string &client_id,
                        const cls::rbd::SnapshotNamespace &snap_namespace,
			const std::string &snap_name);
  Context *handle_remove_snap(int *result, const std::string &client_id);

  void send_unregister_client(const std::string &client_id);
  Context *handle_unregister_client(int *result, const std::string &client_id);

  void send_remove_mirror_image();
  Context *handle_remove_mirror_image(int *result);

  void send_notify_mirroring_watcher_removed();
  Context *handle_notify_mirroring_watcher_removed(int *result);

  Context *create_context_callback(
    Context*(DisableRequest<ImageCtxT>::*handle)(
      int*, const std::string &client_id),
    const std::string &client_id);

};

} // namespace mirror
} // namespace librbd

extern template class librbd::mirror::DisableRequest<librbd::ImageCtx>;

#endif // CEPH_LIBRBD_MIRROR_DISABLE_REQUEST_H