1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2015 Red Hat
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.
20 #include "include/buffer.h"
21 #include "include/encoding.h"
23 #include "osd/osd_types.h"
24 #include "osd/OSDMap.h"
26 typedef uint8_t sectiontype_t
;
27 typedef uint32_t mymagic_t
;
28 typedef int64_t mysize_t
;
43 END_OF_TYPES
, //Keep at the end
46 const uint16_t shortmagic
= 0xffce; //goes into stream as "ceff"
47 //endmagic goes into stream as "ceff ffec"
48 const mymagic_t endmagic
= (0xecff << 16) | shortmagic
;
50 //The first FIXED_LENGTH bytes are a fixed
51 //portion of the export output. This includes the overall
52 //version number, and size of header and footer.
53 //THIS STRUCTURE CAN ONLY BE APPENDED TO. If it needs to expand,
54 //the version can be bumped and then anything
55 //can be added to the export format.
57 static const uint32_t super_magic
= (shortmagic
<< 16) | shortmagic
;
58 // ver = 1, Initial version
59 // ver = 2, Add OSDSuperblock to pg_begin
60 static const uint32_t super_ver
= 2;
61 static const uint32_t FIXED_LENGTH
= 16;
67 super_header() : magic(0), version(0), header_size(0), footer_size(0) { }
69 void encode(bufferlist
& bl
) const {
73 encode(header_size
, bl
);
74 encode(footer_size
, bl
);
76 void decode(bufferlist::const_iterator
& bl
) {
80 decode(header_size
, bl
);
81 decode(footer_size
, bl
);
88 header(sectiontype_t type
, mysize_t size
) :
89 type(type
), size(size
) { }
90 header(): type(0), size(0) { }
92 void encode(bufferlist
& bl
) const {
93 uint32_t debug_type
= (type
<< 24) | (type
<< 16) | shortmagic
;
94 ENCODE_START(1, 1, bl
);
95 encode(debug_type
, bl
);
99 void decode(bufferlist::const_iterator
& bl
) {
102 decode(debug_type
, bl
);
103 type
= debug_type
>> 24;
111 footer() : magic(endmagic
) { }
113 void encode(bufferlist
& bl
) const {
114 ENCODE_START(1, 1, bl
);
118 void decode(bufferlist::const_iterator
& bl
) {
127 OSDSuperblock superblock
;
129 pg_begin(spg_t pg
, const OSDSuperblock
& sb
):
130 pgid(pg
), superblock(sb
) { }
133 void encode(bufferlist
& bl
) const {
134 // If superblock doesn't include CEPH_FS_FEATURE_INCOMPAT_SHARDS then
135 // shard will be NO_SHARD for a replicated pool. This means
136 // that we allow the decode by struct_v 2.
137 ENCODE_START(3, 2, bl
);
138 encode(pgid
.pgid
, bl
);
139 encode(superblock
, bl
);
140 encode(pgid
.shard
, bl
);
143 // NOTE: New super_ver prevents decode from ver 1
144 void decode(bufferlist::const_iterator
& bl
) {
146 decode(pgid
.pgid
, bl
);
148 decode(superblock
, bl
);
151 decode(pgid
.shard
, bl
);
153 pgid
.shard
= shard_id_t::NO_SHARD
;
159 struct object_begin
{
162 // Duplicate what is in the OI_ATTR so we have it at the start
163 // of object processing.
166 explicit object_begin(const ghobject_t
&hoid
): hoid(hoid
) { }
169 // If superblock doesn't include CEPH_FS_FEATURE_INCOMPAT_SHARDS then
170 // generation will be NO_GEN, shard_id will be NO_SHARD for a replicated
171 // pool. This means we will allow the decode by struct_v 1.
172 void encode(bufferlist
& bl
) const {
173 ENCODE_START(3, 1, bl
);
174 encode(hoid
.hobj
, bl
);
175 encode(hoid
.generation
, bl
);
176 encode(hoid
.shard_id
, bl
);
177 encode(oi
, bl
, -1); /* FIXME: we always encode with full features */
180 void decode(bufferlist::const_iterator
& bl
) {
182 decode(hoid
.hobj
, bl
);
184 decode(hoid
.generation
, bl
);
185 decode(hoid
.shard_id
, bl
);
187 hoid
.generation
= ghobject_t::NO_GEN
;
188 hoid
.shard_id
= shard_id_t::NO_SHARD
;
197 struct data_section
{
201 data_section(uint64_t offset
, uint64_t len
, bufferlist bl
):
202 offset(offset
), len(len
), databl(bl
) { }
203 data_section(): offset(0), len(0) { }
205 void encode(bufferlist
& bl
) const {
206 ENCODE_START(1, 1, bl
);
212 void decode(bufferlist::const_iterator
& bl
) {
221 struct attr_section
{
222 map
<string
,bufferlist
> data
;
223 explicit attr_section(const map
<string
,bufferlist
> &data
) : data(data
) { }
224 explicit attr_section(map
<string
, bufferptr
> &data_
)
226 for (std::map
<std::string
, bufferptr
>::iterator i
= data_
.begin();
227 i
!= data_
.end(); ++i
) {
229 bl
.push_back(i
->second
);
236 void encode(bufferlist
& bl
) const {
237 ENCODE_START(1, 1, bl
);
241 void decode(bufferlist::const_iterator
& bl
) {
248 struct omap_hdr_section
{
250 explicit omap_hdr_section(bufferlist hdr
) : hdr(hdr
) { }
251 omap_hdr_section() { }
253 void encode(bufferlist
& bl
) const {
254 ENCODE_START(1, 1, bl
);
258 void decode(bufferlist::const_iterator
& bl
) {
265 struct omap_section
{
266 map
<string
, bufferlist
> omap
;
267 explicit omap_section(const map
<string
, bufferlist
> &omap
) :
271 void encode(bufferlist
& bl
) const {
272 ENCODE_START(1, 1, bl
);
276 void decode(bufferlist::const_iterator
& bl
) {
283 struct metadata_section
{
284 // struct_ver is the on-disk version of original pg
285 __u8 struct_ver
; // for reference
289 PastIntervals past_intervals
;
291 bufferlist osdmap_bl
; // Used in lieu of encoding osdmap due to crc checking
292 map
<eversion_t
, hobject_t
> divergent_priors
;
293 pg_missing_t missing
;
298 const pg_info_t
&info
,
300 const PastIntervals
&past_intervals
,
301 const pg_missing_t
&missing
)
302 : struct_ver(struct_ver
),
303 map_epoch(map_epoch
),
306 past_intervals(past_intervals
),
312 void encode(bufferlist
& bl
) const {
313 ENCODE_START(6, 6, bl
);
314 encode(struct_ver
, bl
);
315 encode(map_epoch
, bl
);
318 encode(past_intervals
, bl
);
319 // Equivalent to osdmap.encode(bl, features); but
320 // preserving exact layout for CRC checking.
321 bl
.append(osdmap_bl
);
322 encode(divergent_priors
, bl
);
326 void decode(bufferlist::const_iterator
& bl
) {
328 decode(struct_ver
, bl
);
329 decode(map_epoch
, bl
);
333 decode(past_intervals
, bl
);
334 } else if (struct_v
> 1) {
335 cout
<< "NOTICE: Older export with classic past_intervals" << std::endl
;
337 cout
<< "NOTICE: Older export without past_intervals" << std::endl
;
342 cout
<< "WARNING: Older export without OSDMap information" << std::endl
;
345 decode(divergent_priors
, bl
);
355 * Superclass for classes that will need to handle a serialized RADOS
356 * dump. Requires that the serialized dump be opened with a known FD.
366 RadosDump(int file_fd_
, bool dry_run_
)
367 : file_fd(file_fd_
), dry_run(dry_run_
)
371 int get_header(header
*h
);
372 int get_footer(footer
*f
);
373 int read_section(sectiontype_t
*type
, bufferlist
*bl
);
374 int skip_object(bufferlist
&bl
);
377 // Define this in .h because it's templated
378 template <typename T
>
379 int write_section(sectiontype_t type
, const T
& obj
, int fd
) {
382 bufferlist blhdr
, bl
, blftr
;
384 header
hdr(type
, bl
.length());
389 int ret
= blhdr
.write_fd(fd
);
391 ret
= bl
.write_fd(fd
);
393 ret
= blftr
.write_fd(fd
);
397 int write_simple(sectiontype_t type
, int fd
)
405 return hbl
.write_fd(fd
);