pstore2
file_header.hpp
Go to the documentation of this file.
1 //===- include/pstore/core/file_header.hpp ----------------*- mode: C++ -*-===//
2 //* __ _ _ _ _ *
3 //* / _(_) | ___ | |__ ___ __ _ __| | ___ _ __ *
4 //* | |_| | |/ _ \ | '_ \ / _ \/ _` |/ _` |/ _ \ '__| *
5 //* | _| | | __/ | | | | __/ (_| | (_| | __/ | *
6 //* |_| |_|_|\___| |_| |_|\___|\__,_|\__,_|\___|_| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
38 
39 #ifndef PSTORE_CORE_FILE_HEADER_HPP
40 #define PSTORE_CORE_FILE_HEADER_HPP
41 
42 #include <atomic>
43 
44 #include "pstore/core/address.hpp"
45 #include "pstore/core/uuid.hpp"
47 
48 namespace pstore {
49 
50  namespace serialize {
53  template <typename T>
54  struct serializer<extent<T>> {
55  using value_type = extent<T>;
56 
57  template <typename Archive>
58  static auto write (Archive && archive, value_type const & r)
59  -> archive_result_type<Archive> {
60  auto const resl =
61  serialize::write (std::forward<Archive> (archive), r.addr.absolute ());
62  serialize::write (std::forward<Archive> (archive), r.size);
63  return resl;
64  }
65  template <typename Archive>
66  static void read (Archive && archive, value_type & r) {
67  auto const addr = typed_address<T>::make (
68  serialize::read<std::uint64_t> (std::forward<Archive> (archive)));
69  auto const size = serialize::read<std::uint64_t> (std::forward<Archive> (archive));
70  new (&r) extent<T> (addr, size);
71  }
72  };
73  } // namespace serialize
74 
75  struct trailer;
76 
78  class header {
79  public:
80  header ();
81 
82  bool is_valid () const noexcept;
83 
85  std::uint32_t get_crc () const noexcept;
86 
90  uuid id () const noexcept { return a.id; }
91  void set_id (uuid const & id) noexcept;
92 
94  std::array<std::uint16_t, 2> const & version () const noexcept { return a.version; }
95 
96  static constexpr std::uint16_t major_version = 1;
97  static constexpr std::uint16_t minor_version = 12;
98 
99  static std::array<std::uint8_t, 4> const file_signature1;
100  static std::uint32_t const file_signature2 = 0x0507FFFF;
101 
104  struct body {
110 
111  std::array<std::uint8_t, 4> signature1;
112 
115  std::uint32_t signature2;
116 
118  std::array<std::uint16_t, 2> version;
119  std::uint32_t header_size = sizeof (header);
121  class uuid id;
122  };
123 
124  body a;
125 
134  std::uint32_t crc = 0;
135  std::uint32_t unused1 = 0;
136 
139  std::atomic<typed_address<trailer>> footer_pos;
140  };
141 
142  // Assert the size, offset, and alignment of the structure and its fields to ensure file format
143  // compatibility across compilers and hosts.
144  PSTORE_STATIC_ASSERT (offsetof (header::body, signature1) == 0);
145  PSTORE_STATIC_ASSERT (offsetof (header::body, signature2) == 4);
146  PSTORE_STATIC_ASSERT (offsetof (header::body, version) == 8);
147  PSTORE_STATIC_ASSERT (offsetof (header::body, header_size) == 12);
148  PSTORE_STATIC_ASSERT (offsetof (header::body, id) == 16);
149  PSTORE_STATIC_ASSERT (sizeof (header::body) == 32);
150 
151  PSTORE_STATIC_ASSERT (offsetof (header, a) == 0);
152  PSTORE_STATIC_ASSERT (offsetof (header, crc) == 32);
153  PSTORE_STATIC_ASSERT (offsetof (header, footer_pos) == 40);
154  PSTORE_STATIC_ASSERT (alignof (header) == 8);
155  PSTORE_STATIC_ASSERT (sizeof (header) == 48);
156 
162  struct lock_block {
163  std::uint64_t vacuum_lock{chars_to_uint64 ('V', 'a', 'c', 'u', 'u', 'm', 'L', 'k')};
164  std::uint64_t transaction_lock{chars_to_uint64 ('T', 'r', 'n', 's', 'a', 'c', 't', 'L')};
165 
166  static constexpr auto file_offset = std::uint64_t{sizeof (header)};
167  static constexpr std::uint64_t chars_to_uint64 (char const c1, char const c2, char const c3,
168  char const c4, char const c5, char const c6,
169  char const c7, char const c8) noexcept {
170  return static_cast<std::uint64_t> (c1) | static_cast<std::uint64_t> (c2) << 8U |
171  static_cast<std::uint64_t> (c3) << 16U | static_cast<std::uint64_t> (c4) << 24U |
172  static_cast<std::uint64_t> (c5) << 32U | static_cast<std::uint64_t> (c6) << 40U |
173  static_cast<std::uint64_t> (c7) << 48U | static_cast<std::uint64_t> (c8) << 56U;
174  }
175  };
176 
177  // Assert the size, offset, and alignment of the structure and its fields to ensure file format
178  // compatibility across compilers and hosts.
179  PSTORE_STATIC_ASSERT (offsetof (lock_block, vacuum_lock) == 0);
180  PSTORE_STATIC_ASSERT (offsetof (lock_block, transaction_lock) == 8);
181  PSTORE_STATIC_ASSERT (alignof (lock_block) == 8);
182  PSTORE_STATIC_ASSERT (sizeof (lock_block) == 16);
183 
184  constexpr auto leader_size = sizeof (header) + sizeof (lock_block);
185 
186  class database;
187 
188  namespace index {
189 
190 #define PSTORE_INDICES \
191  X (compilation) \
192  X (debug_line_header) \
193  X (fragment) \
194  X (name) \
195  X (path) \
196  X (write)
197 
198  struct header_block;
199  } // namespace index
200 
206  struct trailer {
207  static std::array<std::uint8_t, 8> const default_signature1;
208  static std::array<std::uint8_t, 8> const default_signature2;
209 
210  bool crc_is_valid () const noexcept;
211  bool signature_is_valid () const noexcept;
212 
215  static bool validate (database const & db, typed_address<trailer> pos);
216 
218  std::uint32_t get_crc () const noexcept;
219 
220 
221 #define X(a) a,
222  // Note that the first enum member must have the value 0 or flush_indices() will need to
223  // change.
224  enum class indices : unsigned { PSTORE_INDICES last };
225 #undef X
226  using index_records_array =
227  std::array<typed_address<index::header_block>,
228  static_cast<std::underlying_type<indices>::type> (indices::last)>;
229 
232  struct body {
233  std::array<std::uint8_t, 8> signature1 = default_signature1;
234  std::atomic<std::uint32_t> generation{0};
235  std::uint32_t unused1{0};
236 
239  std::atomic<std::uint64_t> size{0};
240 
242  std::atomic<std::uint64_t> time{0};
243 
248 
249  index_records_array index_records;
250  std::uint32_t unused2{0};
251  std::uint32_t unused3{0};
252  };
253 
254 
255  body a;
256 
262  std::uint32_t crc = 0;
263  std::uint32_t unused1 = 0;
264  std::array<std::uint8_t, 8> signature2 = default_signature2;
265  };
266 
267  // Assert the size, offset, and alignment of the structure and its fields to ensure file format
268  // compatibility across compilers and hosts.
269  PSTORE_STATIC_ASSERT (offsetof (trailer::body, signature1) == 0);
270  PSTORE_STATIC_ASSERT (offsetof (trailer::body, generation) == 8);
271  PSTORE_STATIC_ASSERT (offsetof (trailer::body, unused1) == 12);
272  PSTORE_STATIC_ASSERT (offsetof (trailer::body, size) == 16);
273  PSTORE_STATIC_ASSERT (offsetof (trailer::body, time) == 24);
274  PSTORE_STATIC_ASSERT (offsetof (trailer::body, prev_generation) == 32);
275  PSTORE_STATIC_ASSERT (offsetof (trailer::body, index_records) == 40);
276  PSTORE_STATIC_ASSERT (offsetof (trailer::body, unused2) == 88);
277  PSTORE_STATIC_ASSERT (offsetof (trailer::body, unused3) == 92);
278  PSTORE_STATIC_ASSERT (alignof (trailer::body) == 8);
279  PSTORE_STATIC_ASSERT (sizeof (trailer::body) == 96);
280 
281  PSTORE_STATIC_ASSERT (offsetof (trailer, a) == 0);
282  PSTORE_STATIC_ASSERT (offsetof (trailer, crc) == 96);
283  PSTORE_STATIC_ASSERT (offsetof (trailer, signature2) == 104);
284  PSTORE_STATIC_ASSERT (alignof (trailer) == 8);
285  PSTORE_STATIC_ASSERT (sizeof (trailer) == 112);
286 
287 } // namespace pstore
288 #endif // PSTORE_CORE_FILE_HEADER_HPP
std::atomic< typed_address< trailer > > footer_pos
The file offset of the current (most recent) file footer.
Definition: file_header.hpp:139
lock_guard fills a similar role as a type such as std::scoped_lock<> in that it provides convenient R...
Definition: transaction.hpp:236
Represents the portion of the header structure which is covered by the computed CRC value...
Definition: file_header.hpp:104
The lock-block is a small struct placed immediately after the file header which is used by the transa...
Definition: file_header.hpp:162
typed_address< T > addr
The address of the data associated with this extent.
Definition: address.hpp:456
The primary template for serialization of non standard layout types.
Definition: types.hpp:118
An extent is a contiguous area of storage reserved for a data BLOB, represented as a range...
Definition: address.hpp:441
The transaction footer structure.
Definition: file_header.hpp:206
std::array< std::uint16_t, 2 > const & version() const noexcept
Returns the file format version number (major, minor).
Definition: file_header.hpp:94
static auto write(Archive &&archive, Ty const &v) -> archive_result_type< Archive >
Writes an single value of type Ty to an archive.
Definition: types.hpp:133
Represents the portion of the trailer structure which is covered by the computed CRC value...
Definition: file_header.hpp:232
Provides serialization capabilities for trivial and user-defined types.
Definition: address.hpp:231
std::array< std::uint16_t, 2 > version
The file format version number (major, minor).
Definition: file_header.hpp:118
std::uint64_t size
The size of the data associated with this extent.
Definition: address.hpp:461
static void read(Archive &&archive, Ty &v)
Reads a value of type Ty from an archive.
Definition: types.hpp:153
Definition: nonpod2.cpp:40
Definition: database.hpp:40
std::uint32_t signature2
The second half of the file signature.
Definition: file_header.hpp:115
std::array< std::uint8_t, 4 > signature1
The file signature is split into two pieces of four bytes each.
Definition: file_header.hpp:111
The uuid class is used to represent Universally Unique Identifiers (UUID) as defined by RFC 4122...
Definition: uuid.hpp:40
Defines the uuid class which supports RFC4122 UUIDs.
uuid id() const noexcept
Returns the database ID.
Definition: file_header.hpp:90
The data store file header.
Definition: file_header.hpp:78