1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
10 #include "include/encoding.h"
11 #include "include/utime.h"
13 #include "osd/osd_types.h"
15 struct creating_pgs_t
{
16 epoch_t last_scan_epoch
= 0;
18 struct pg_create_info
{
22 // NOTE: pre-octopus instances of this class will have a
26 std::vector
<int> acting
;
27 int acting_primary
= -1;
29 PastIntervals past_intervals
;
31 void encode(ceph::buffer::list
& bl
, uint64_t features
) const {
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
);
39 ENCODE_START(1, 1, bl
);
40 encode(create_epoch
, bl
);
41 encode(create_stamp
, bl
);
43 encode(up_primary
, bl
);
45 encode(acting_primary
, bl
);
47 encode(past_intervals
, bl
);
50 void decode_legacy(ceph::buffer::list::const_iterator
& p
) {
52 decode(create_epoch
, p
);
53 decode(create_stamp
, p
);
55 void decode(ceph::buffer::list::const_iterator
& p
) {
58 decode(create_epoch
, p
);
59 decode(create_stamp
, p
);
61 decode(up_primary
, p
);
63 decode(acting_primary
, p
);
65 decode(past_intervals
, p
);
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");
73 f
->dump_unsigned("osd", i
);
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
);
82 f
->dump_int("acting_primary", up_primary
);
83 f
->dump_object("pg_history", history
);
84 f
->dump_object("past_intervals", past_intervals
);
88 pg_create_info(epoch_t e
, utime_t t
)
91 // NOTE: we don't initialize the other fields here; see
92 // OSDMonitor::update_pending_pgs()
96 /// pgs we are currently creating
97 std::map
<pg_t
, pg_create_info
> pgs
;
99 struct pool_create_info
{
107 void encode(ceph::buffer::list
& bl
) const {
110 encode(modified
, bl
);
114 void decode(ceph::buffer::list::const_iterator
& p
) {
123 /// queue of pgs we still need to create (poolid -> <created, set of ps>)
124 std::map
<int64_t,pool_create_info
> queue
;
126 /// pools that exist in the osdmap for which at least one pg has been created
127 std::set
<int64_t> created_pools
;
129 bool still_creating_pool(int64_t poolid
) {
130 for (auto& i
: pgs
) {
131 if (i
.first
.pool() == poolid
) {
135 if (queue
.count(poolid
)) {
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
];
145 c
.modified
= modified
;
147 created_pools
.insert(poolid
);
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();
158 void encode(ceph::buffer::list
& bl
, uint64_t features
) const {
160 if (!HAVE_FEATURE(features
, SERVER_OCTOPUS
)) {
163 ENCODE_START(v
, 1, bl
);
164 encode(last_scan_epoch
, bl
);
165 encode(pgs
, bl
, features
);
166 encode(created_pools
, bl
);
170 void decode(ceph::buffer::list::const_iterator
& bl
) {
172 decode(last_scan_epoch
, bl
);
176 // legacy pg encoding
183 pgs
[pgid
].decode_legacy(bl
);
186 decode(created_pools
, bl
);
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
);
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
);
212 f
->open_array_section("created_pools");
213 for (auto pool
: created_pools
) {
214 f
->dump_unsigned("pool", pool
);
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};
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
= {};
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
)