]> git.proxmox.com Git - ceph.git/blob - ceph/src/mon/CreatingPGs.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / mon / CreatingPGs.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #pragma once
5
6 #include <map>
7 #include <set>
8 #include <vector>
9
10 #include "include/encoding.h"
11 #include "include/utime.h"
12
13 #include "osd/osd_types.h"
14
15 struct creating_pgs_t {
16 epoch_t last_scan_epoch = 0;
17
18 struct pg_create_info {
19 epoch_t create_epoch;
20 utime_t create_stamp;
21
22 // NOTE: pre-octopus instances of this class will have a
23 // zeroed-out history
24 std::vector<int> up;
25 int up_primary = -1;
26 std::vector<int> acting;
27 int acting_primary = -1;
28 pg_history_t history;
29 PastIntervals past_intervals;
30
31 void encode(ceph::buffer::list& bl, uint64_t features) const {
32 using ceph::encode;
33 if (!HAVE_FEATURE(features, SERVER_OCTOPUS)) {
34 // was pair<epoch_t,utime_t> prior to octopus
35 encode(create_epoch, bl);
36 encode(create_stamp, bl);
37 return;
38 }
39 ENCODE_START(1, 1, bl);
40 encode(create_epoch, bl);
41 encode(create_stamp, bl);
42 encode(up, bl);
43 encode(up_primary, bl);
44 encode(acting, bl);
45 encode(acting_primary, bl);
46 encode(history, bl);
47 encode(past_intervals, bl);
48 ENCODE_FINISH(bl);
49 }
50 void decode_legacy(ceph::buffer::list::const_iterator& p) {
51 using ceph::decode;
52 decode(create_epoch, p);
53 decode(create_stamp, p);
54 }
55 void decode(ceph::buffer::list::const_iterator& p) {
56 using ceph::decode;
57 DECODE_START(1, p);
58 decode(create_epoch, p);
59 decode(create_stamp, p);
60 decode(up, p);
61 decode(up_primary, p);
62 decode(acting, p);
63 decode(acting_primary, p);
64 decode(history, p);
65 decode(past_intervals, p);
66 DECODE_FINISH(p);
67 }
68 void dump(ceph::Formatter *f) const {
69 f->dump_unsigned("create_epoch", create_epoch);
70 f->dump_stream("create_stamp") << create_stamp;
71 f->open_array_section("up");
72 for (auto& i : up) {
73 f->dump_unsigned("osd", i);
74 }
75 f->close_section();
76 f->dump_int("up_primary", up_primary);
77 f->open_array_section("acting");
78 for (auto& i : acting) {
79 f->dump_unsigned("osd", i);
80 }
81 f->close_section();
82 f->dump_int("acting_primary", up_primary);
83 f->dump_object("pg_history", history);
84 f->dump_object("past_intervals", past_intervals);
85 }
86
87 pg_create_info() {}
88 pg_create_info(epoch_t e, utime_t t)
89 : create_epoch(e),
90 create_stamp(t) {
91 // NOTE: we don't initialize the other fields here; see
92 // OSDMonitor::update_pending_pgs()
93 }
94 };
95
96 /// pgs we are currently creating
97 std::map<pg_t, pg_create_info> pgs;
98
99 struct pool_create_info {
100 epoch_t created;
101 utime_t modified;
102 uint64_t start = 0;
103 uint64_t end = 0;
104 bool done() const {
105 return start >= end;
106 }
107 void encode(ceph::buffer::list& bl) const {
108 using ceph::encode;
109 encode(created, bl);
110 encode(modified, bl);
111 encode(start, bl);
112 encode(end, bl);
113 }
114 void decode(ceph::buffer::list::const_iterator& p) {
115 using ceph::decode;
116 decode(created, p);
117 decode(modified, p);
118 decode(start, p);
119 decode(end, p);
120 }
121 };
122
123 /// queue of pgs we still need to create (poolid -> <created, set of ps>)
124 std::map<int64_t,pool_create_info> queue;
125
126 /// pools that exist in the osdmap for which at least one pg has been created
127 std::set<int64_t> created_pools;
128
129 bool still_creating_pool(int64_t poolid) {
130 for (auto& i : pgs) {
131 if (i.first.pool() == poolid) {
132 return true;
133 }
134 }
135 if (queue.count(poolid)) {
136 return true;
137 }
138 return false;
139 }
140 void create_pool(int64_t poolid, uint32_t pg_num,
141 epoch_t created, utime_t modified) {
142 ceph_assert(created_pools.count(poolid) == 0);
143 auto& c = queue[poolid];
144 c.created = created;
145 c.modified = modified;
146 c.end = pg_num;
147 created_pools.insert(poolid);
148 }
149 unsigned remove_pool(int64_t removed_pool) {
150 const unsigned total = pgs.size();
151 auto first = pgs.lower_bound(pg_t{0, (uint64_t)removed_pool});
152 auto last = pgs.lower_bound(pg_t{0, (uint64_t)removed_pool + 1});
153 pgs.erase(first, last);
154 created_pools.erase(removed_pool);
155 queue.erase(removed_pool);
156 return total - pgs.size();
157 }
158 void encode(ceph::buffer::list& bl, uint64_t features) const {
159 unsigned v = 3;
160 if (!HAVE_FEATURE(features, SERVER_OCTOPUS)) {
161 v = 2;
162 }
163 ENCODE_START(v, 1, bl);
164 encode(last_scan_epoch, bl);
165 encode(pgs, bl, features);
166 encode(created_pools, bl);
167 encode(queue, bl);
168 ENCODE_FINISH(bl);
169 }
170 void decode(ceph::buffer::list::const_iterator& bl) {
171 DECODE_START(3, bl);
172 decode(last_scan_epoch, bl);
173 if (struct_v >= 3) {
174 decode(pgs, bl);
175 } else {
176 // legacy pg encoding
177 pgs.clear();
178 uint32_t num;
179 decode(num, bl);
180 while (num--) {
181 pg_t pgid;
182 decode(pgid, bl);
183 pgs[pgid].decode_legacy(bl);
184 }
185 }
186 decode(created_pools, bl);
187 if (struct_v >= 2)
188 decode(queue, bl);
189 DECODE_FINISH(bl);
190 }
191 void dump(ceph::Formatter *f) const {
192 f->dump_unsigned("last_scan_epoch", last_scan_epoch);
193 f->open_array_section("creating_pgs");
194 for (auto& pg : pgs) {
195 f->open_object_section("pg");
196 f->dump_stream("pgid") << pg.first;
197 f->dump_object("pg_create_info", pg.second);
198 f->close_section();
199 }
200 f->close_section();
201 f->open_array_section("queue");
202 for (auto& p : queue) {
203 f->open_object_section("pool");
204 f->dump_unsigned("pool", p.first);
205 f->dump_unsigned("created", p.second.created);
206 f->dump_stream("modified") << p.second.modified;
207 f->dump_unsigned("ps_start", p.second.start);
208 f->dump_unsigned("ps_end", p.second.end);
209 f->close_section();
210 }
211 f->close_section();
212 f->open_array_section("created_pools");
213 for (auto pool : created_pools) {
214 f->dump_unsigned("pool", pool);
215 }
216 f->close_section();
217 }
218 static void generate_test_instances(std::list<creating_pgs_t*>& o) {
219 auto c = new creating_pgs_t;
220 c->last_scan_epoch = 17;
221 c->pgs.emplace(pg_t{42, 2}, pg_create_info(31, utime_t{891, 113}));
222 c->pgs.emplace(pg_t{44, 2}, pg_create_info(31, utime_t{891, 113}));
223 c->created_pools = {0, 1};
224 o.push_back(c);
225 c = new creating_pgs_t;
226 c->last_scan_epoch = 18;
227 c->pgs.emplace(pg_t{42, 3}, pg_create_info(31, utime_t{891, 113}));
228 c->created_pools = {};
229 o.push_back(c);
230 }
231 };
232 WRITE_CLASS_ENCODER_FEATURES(creating_pgs_t::pg_create_info)
233 WRITE_CLASS_ENCODER(creating_pgs_t::pool_create_info)
234 WRITE_CLASS_ENCODER_FEATURES(creating_pgs_t)