xref: /aosp_15_r20/external/crosvm/disk/src/gpt.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2021 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Functions for writing GUID Partition Tables for use in a composite disk image.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use std::convert::TryInto;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::io;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::io::Write;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::num::TryFromIntError;
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker use crc32fast::Hasher;
13*bb4ee6a4SAndroid Build Coastguard Worker use remain::sorted;
14*bb4ee6a4SAndroid Build Coastguard Worker use thiserror::Error as ThisError;
15*bb4ee6a4SAndroid Build Coastguard Worker use uuid::Uuid;
16*bb4ee6a4SAndroid Build Coastguard Worker 
17*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes of a disk sector (also called a block).
18*bb4ee6a4SAndroid Build Coastguard Worker pub const SECTOR_SIZE: u64 = 1 << 9;
19*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes on an MBR partition entry.
20*bb4ee6a4SAndroid Build Coastguard Worker const MBR_PARTITION_ENTRY_SIZE: usize = 16;
21*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes of a GPT header.
22*bb4ee6a4SAndroid Build Coastguard Worker pub const GPT_HEADER_SIZE: u32 = 92;
23*bb4ee6a4SAndroid Build Coastguard Worker /// The number of partition entries in the GPT, which is the maximum number of partitions which are
24*bb4ee6a4SAndroid Build Coastguard Worker /// supported.
25*bb4ee6a4SAndroid Build Coastguard Worker pub const GPT_NUM_PARTITIONS: u32 = 128;
26*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes of a single GPT partition entry.
27*bb4ee6a4SAndroid Build Coastguard Worker pub const GPT_PARTITION_ENTRY_SIZE: u32 = 128;
28*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes of everything before the first partition: i.e. the MBR, GPT header and GPT
29*bb4ee6a4SAndroid Build Coastguard Worker /// partition entries.
30*bb4ee6a4SAndroid Build Coastguard Worker pub const GPT_BEGINNING_SIZE: u64 = SECTOR_SIZE * 40;
31*bb4ee6a4SAndroid Build Coastguard Worker /// The size in bytes of everything after the last partition: i.e. the GPT partition entries and GPT
32*bb4ee6a4SAndroid Build Coastguard Worker /// footer.
33*bb4ee6a4SAndroid Build Coastguard Worker pub const GPT_END_SIZE: u64 = SECTOR_SIZE * 33;
34*bb4ee6a4SAndroid Build Coastguard Worker 
35*bb4ee6a4SAndroid Build Coastguard Worker #[sorted]
36*bb4ee6a4SAndroid Build Coastguard Worker #[derive(ThisError, Debug)]
37*bb4ee6a4SAndroid Build Coastguard Worker pub enum Error {
38*bb4ee6a4SAndroid Build Coastguard Worker     /// The disk size was invalid (too large).
39*bb4ee6a4SAndroid Build Coastguard Worker     #[error("invalid disk size: {0}")]
40*bb4ee6a4SAndroid Build Coastguard Worker     InvalidDiskSize(TryFromIntError),
41*bb4ee6a4SAndroid Build Coastguard Worker     /// There was an error writing data to one of the image files.
42*bb4ee6a4SAndroid Build Coastguard Worker     #[error("failed to write data: {0}")]
43*bb4ee6a4SAndroid Build Coastguard Worker     WritingData(io::Error),
44*bb4ee6a4SAndroid Build Coastguard Worker }
45*bb4ee6a4SAndroid Build Coastguard Worker 
46*bb4ee6a4SAndroid Build Coastguard Worker /// Write a protective MBR for a disk of the given total size (in bytes).
47*bb4ee6a4SAndroid Build Coastguard Worker ///
48*bb4ee6a4SAndroid Build Coastguard Worker /// This should be written at the start of the disk, before the GPT header. It is one `SECTOR_SIZE`
49*bb4ee6a4SAndroid Build Coastguard Worker /// long.
write_protective_mbr(file: &mut impl Write, disk_size: u64) -> Result<(), Error>50*bb4ee6a4SAndroid Build Coastguard Worker pub fn write_protective_mbr(file: &mut impl Write, disk_size: u64) -> Result<(), Error> {
51*bb4ee6a4SAndroid Build Coastguard Worker     // Bootstrap code
52*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0; 446]).map_err(Error::WritingData)?;
53*bb4ee6a4SAndroid Build Coastguard Worker 
54*bb4ee6a4SAndroid Build Coastguard Worker     // Partition status
55*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0x00]).map_err(Error::WritingData)?;
56*bb4ee6a4SAndroid Build Coastguard Worker     // Begin CHS
57*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0; 3]).map_err(Error::WritingData)?;
58*bb4ee6a4SAndroid Build Coastguard Worker     // Partition type
59*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0xEE]).map_err(Error::WritingData)?;
60*bb4ee6a4SAndroid Build Coastguard Worker     // End CHS
61*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0; 3]).map_err(Error::WritingData)?;
62*bb4ee6a4SAndroid Build Coastguard Worker     let first_lba: u32 = 1;
63*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&first_lba.to_le_bytes())
64*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(Error::WritingData)?;
65*bb4ee6a4SAndroid Build Coastguard Worker     let number_of_sectors: u32 = (disk_size / SECTOR_SIZE)
66*bb4ee6a4SAndroid Build Coastguard Worker         .try_into()
67*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(Error::InvalidDiskSize)?;
68*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&number_of_sectors.to_le_bytes())
69*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(Error::WritingData)?;
70*bb4ee6a4SAndroid Build Coastguard Worker 
71*bb4ee6a4SAndroid Build Coastguard Worker     // Three more empty partitions
72*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0; MBR_PARTITION_ENTRY_SIZE * 3])
73*bb4ee6a4SAndroid Build Coastguard Worker         .map_err(Error::WritingData)?;
74*bb4ee6a4SAndroid Build Coastguard Worker 
75*bb4ee6a4SAndroid Build Coastguard Worker     // Boot signature
76*bb4ee6a4SAndroid Build Coastguard Worker     file.write_all(&[0x55, 0xAA]).map_err(Error::WritingData)?;
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
79*bb4ee6a4SAndroid Build Coastguard Worker }
80*bb4ee6a4SAndroid Build Coastguard Worker 
81*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Default, Eq, PartialEq)]
82*bb4ee6a4SAndroid Build Coastguard Worker struct GptHeader {
83*bb4ee6a4SAndroid Build Coastguard Worker     signature: [u8; 8],
84*bb4ee6a4SAndroid Build Coastguard Worker     revision: [u8; 4],
85*bb4ee6a4SAndroid Build Coastguard Worker     header_size: u32,
86*bb4ee6a4SAndroid Build Coastguard Worker     header_crc32: u32,
87*bb4ee6a4SAndroid Build Coastguard Worker     current_lba: u64,
88*bb4ee6a4SAndroid Build Coastguard Worker     backup_lba: u64,
89*bb4ee6a4SAndroid Build Coastguard Worker     first_usable_lba: u64,
90*bb4ee6a4SAndroid Build Coastguard Worker     last_usable_lba: u64,
91*bb4ee6a4SAndroid Build Coastguard Worker     disk_guid: Uuid,
92*bb4ee6a4SAndroid Build Coastguard Worker     partition_entries_lba: u64,
93*bb4ee6a4SAndroid Build Coastguard Worker     num_partition_entries: u32,
94*bb4ee6a4SAndroid Build Coastguard Worker     partition_entry_size: u32,
95*bb4ee6a4SAndroid Build Coastguard Worker     partition_entries_crc32: u32,
96*bb4ee6a4SAndroid Build Coastguard Worker }
97*bb4ee6a4SAndroid Build Coastguard Worker 
98*bb4ee6a4SAndroid Build Coastguard Worker impl GptHeader {
write_bytes(&self, out: &mut impl Write) -> Result<(), Error>99*bb4ee6a4SAndroid Build Coastguard Worker     fn write_bytes(&self, out: &mut impl Write) -> Result<(), Error> {
100*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.signature).map_err(Error::WritingData)?;
101*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.revision).map_err(Error::WritingData)?;
102*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.header_size.to_le_bytes())
103*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
104*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.header_crc32.to_le_bytes())
105*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
106*bb4ee6a4SAndroid Build Coastguard Worker         // Reserved
107*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&[0; 4]).map_err(Error::WritingData)?;
108*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.current_lba.to_le_bytes())
109*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
110*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.backup_lba.to_le_bytes())
111*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
112*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.first_usable_lba.to_le_bytes())
113*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
114*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.last_usable_lba.to_le_bytes())
115*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
116*bb4ee6a4SAndroid Build Coastguard Worker 
117*bb4ee6a4SAndroid Build Coastguard Worker         // GUID is mixed-endian for some reason, so we can't just use `Uuid::as_bytes()`.
118*bb4ee6a4SAndroid Build Coastguard Worker         write_guid(out, self.disk_guid).map_err(Error::WritingData)?;
119*bb4ee6a4SAndroid Build Coastguard Worker 
120*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.partition_entries_lba.to_le_bytes())
121*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
122*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.num_partition_entries.to_le_bytes())
123*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
124*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.partition_entry_size.to_le_bytes())
125*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
126*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.partition_entries_crc32.to_le_bytes())
127*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
128*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
129*bb4ee6a4SAndroid Build Coastguard Worker     }
130*bb4ee6a4SAndroid Build Coastguard Worker }
131*bb4ee6a4SAndroid Build Coastguard Worker 
132*bb4ee6a4SAndroid Build Coastguard Worker /// Write a GPT header for the disk.
133*bb4ee6a4SAndroid Build Coastguard Worker ///
134*bb4ee6a4SAndroid Build Coastguard Worker /// It may either be a primary header (which should go at LBA 1) or a secondary header (which should
135*bb4ee6a4SAndroid Build Coastguard Worker /// go at the end of the disk).
write_gpt_header( out: &mut impl Write, disk_guid: Uuid, partition_entries_crc32: u32, secondary_table_offset: u64, secondary: bool, ) -> Result<(), Error>136*bb4ee6a4SAndroid Build Coastguard Worker pub fn write_gpt_header(
137*bb4ee6a4SAndroid Build Coastguard Worker     out: &mut impl Write,
138*bb4ee6a4SAndroid Build Coastguard Worker     disk_guid: Uuid,
139*bb4ee6a4SAndroid Build Coastguard Worker     partition_entries_crc32: u32,
140*bb4ee6a4SAndroid Build Coastguard Worker     secondary_table_offset: u64,
141*bb4ee6a4SAndroid Build Coastguard Worker     secondary: bool,
142*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<(), Error> {
143*bb4ee6a4SAndroid Build Coastguard Worker     let primary_header_lba = 1;
144*bb4ee6a4SAndroid Build Coastguard Worker     let secondary_header_lba = (secondary_table_offset + GPT_END_SIZE) / SECTOR_SIZE - 1;
145*bb4ee6a4SAndroid Build Coastguard Worker     let mut gpt_header = GptHeader {
146*bb4ee6a4SAndroid Build Coastguard Worker         signature: *b"EFI PART",
147*bb4ee6a4SAndroid Build Coastguard Worker         revision: [0, 0, 1, 0],
148*bb4ee6a4SAndroid Build Coastguard Worker         header_size: GPT_HEADER_SIZE,
149*bb4ee6a4SAndroid Build Coastguard Worker         current_lba: if secondary {
150*bb4ee6a4SAndroid Build Coastguard Worker             secondary_header_lba
151*bb4ee6a4SAndroid Build Coastguard Worker         } else {
152*bb4ee6a4SAndroid Build Coastguard Worker             primary_header_lba
153*bb4ee6a4SAndroid Build Coastguard Worker         },
154*bb4ee6a4SAndroid Build Coastguard Worker         backup_lba: if secondary {
155*bb4ee6a4SAndroid Build Coastguard Worker             primary_header_lba
156*bb4ee6a4SAndroid Build Coastguard Worker         } else {
157*bb4ee6a4SAndroid Build Coastguard Worker             secondary_header_lba
158*bb4ee6a4SAndroid Build Coastguard Worker         },
159*bb4ee6a4SAndroid Build Coastguard Worker         first_usable_lba: GPT_BEGINNING_SIZE / SECTOR_SIZE,
160*bb4ee6a4SAndroid Build Coastguard Worker         last_usable_lba: secondary_table_offset / SECTOR_SIZE - 1,
161*bb4ee6a4SAndroid Build Coastguard Worker         disk_guid,
162*bb4ee6a4SAndroid Build Coastguard Worker         partition_entries_lba: 2,
163*bb4ee6a4SAndroid Build Coastguard Worker         num_partition_entries: GPT_NUM_PARTITIONS,
164*bb4ee6a4SAndroid Build Coastguard Worker         partition_entry_size: GPT_PARTITION_ENTRY_SIZE,
165*bb4ee6a4SAndroid Build Coastguard Worker         partition_entries_crc32,
166*bb4ee6a4SAndroid Build Coastguard Worker         header_crc32: 0,
167*bb4ee6a4SAndroid Build Coastguard Worker     };
168*bb4ee6a4SAndroid Build Coastguard Worker 
169*bb4ee6a4SAndroid Build Coastguard Worker     // Write once to a temporary buffer to calculate the CRC.
170*bb4ee6a4SAndroid Build Coastguard Worker     let mut header_without_crc = [0u8; GPT_HEADER_SIZE as usize];
171*bb4ee6a4SAndroid Build Coastguard Worker     gpt_header.write_bytes(&mut &mut header_without_crc[..])?;
172*bb4ee6a4SAndroid Build Coastguard Worker     let mut hasher = Hasher::new();
173*bb4ee6a4SAndroid Build Coastguard Worker     hasher.update(&header_without_crc);
174*bb4ee6a4SAndroid Build Coastguard Worker     gpt_header.header_crc32 = hasher.finalize();
175*bb4ee6a4SAndroid Build Coastguard Worker 
176*bb4ee6a4SAndroid Build Coastguard Worker     gpt_header.write_bytes(out)?;
177*bb4ee6a4SAndroid Build Coastguard Worker 
178*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
179*bb4ee6a4SAndroid Build Coastguard Worker }
180*bb4ee6a4SAndroid Build Coastguard Worker 
181*bb4ee6a4SAndroid Build Coastguard Worker /// A GPT entry for a particular partition.
182*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Clone, Debug, Eq, PartialEq)]
183*bb4ee6a4SAndroid Build Coastguard Worker pub struct GptPartitionEntry {
184*bb4ee6a4SAndroid Build Coastguard Worker     pub partition_type_guid: Uuid,
185*bb4ee6a4SAndroid Build Coastguard Worker     pub unique_partition_guid: Uuid,
186*bb4ee6a4SAndroid Build Coastguard Worker     pub first_lba: u64,
187*bb4ee6a4SAndroid Build Coastguard Worker     pub last_lba: u64,
188*bb4ee6a4SAndroid Build Coastguard Worker     pub attributes: u64,
189*bb4ee6a4SAndroid Build Coastguard Worker     /// UTF-16LE
190*bb4ee6a4SAndroid Build Coastguard Worker     pub partition_name: [u16; 36],
191*bb4ee6a4SAndroid Build Coastguard Worker }
192*bb4ee6a4SAndroid Build Coastguard Worker 
193*bb4ee6a4SAndroid Build Coastguard Worker // This is implemented manually because `Default` isn't implemented in the standard library for
194*bb4ee6a4SAndroid Build Coastguard Worker // arrays of more than 32 elements. If that gets implemented (now than const generics are in) then
195*bb4ee6a4SAndroid Build Coastguard Worker // we can derive this instead.
196*bb4ee6a4SAndroid Build Coastguard Worker impl Default for GptPartitionEntry {
default() -> Self197*bb4ee6a4SAndroid Build Coastguard Worker     fn default() -> Self {
198*bb4ee6a4SAndroid Build Coastguard Worker         Self {
199*bb4ee6a4SAndroid Build Coastguard Worker             partition_type_guid: Default::default(),
200*bb4ee6a4SAndroid Build Coastguard Worker             unique_partition_guid: Default::default(),
201*bb4ee6a4SAndroid Build Coastguard Worker             first_lba: 0,
202*bb4ee6a4SAndroid Build Coastguard Worker             last_lba: 0,
203*bb4ee6a4SAndroid Build Coastguard Worker             attributes: 0,
204*bb4ee6a4SAndroid Build Coastguard Worker             partition_name: [0; 36],
205*bb4ee6a4SAndroid Build Coastguard Worker         }
206*bb4ee6a4SAndroid Build Coastguard Worker     }
207*bb4ee6a4SAndroid Build Coastguard Worker }
208*bb4ee6a4SAndroid Build Coastguard Worker 
209*bb4ee6a4SAndroid Build Coastguard Worker impl GptPartitionEntry {
210*bb4ee6a4SAndroid Build Coastguard Worker     /// Write out the partition table entry. It will take
211*bb4ee6a4SAndroid Build Coastguard Worker     /// `GPT_PARTITION_ENTRY_SIZE` bytes.
write_bytes(&self, out: &mut impl Write) -> Result<(), Error>212*bb4ee6a4SAndroid Build Coastguard Worker     pub fn write_bytes(&self, out: &mut impl Write) -> Result<(), Error> {
213*bb4ee6a4SAndroid Build Coastguard Worker         write_guid(out, self.partition_type_guid).map_err(Error::WritingData)?;
214*bb4ee6a4SAndroid Build Coastguard Worker         write_guid(out, self.unique_partition_guid).map_err(Error::WritingData)?;
215*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.first_lba.to_le_bytes())
216*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
217*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.last_lba.to_le_bytes())
218*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
219*bb4ee6a4SAndroid Build Coastguard Worker         out.write_all(&self.attributes.to_le_bytes())
220*bb4ee6a4SAndroid Build Coastguard Worker             .map_err(Error::WritingData)?;
221*bb4ee6a4SAndroid Build Coastguard Worker         for code_unit in &self.partition_name {
222*bb4ee6a4SAndroid Build Coastguard Worker             out.write_all(&code_unit.to_le_bytes())
223*bb4ee6a4SAndroid Build Coastguard Worker                 .map_err(Error::WritingData)?;
224*bb4ee6a4SAndroid Build Coastguard Worker         }
225*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
226*bb4ee6a4SAndroid Build Coastguard Worker     }
227*bb4ee6a4SAndroid Build Coastguard Worker }
228*bb4ee6a4SAndroid Build Coastguard Worker 
229*bb4ee6a4SAndroid Build Coastguard Worker /// Write a UUID in the mixed-endian format which GPT uses for GUIDs.
write_guid(out: &mut impl Write, guid: Uuid) -> Result<(), io::Error>230*bb4ee6a4SAndroid Build Coastguard Worker fn write_guid(out: &mut impl Write, guid: Uuid) -> Result<(), io::Error> {
231*bb4ee6a4SAndroid Build Coastguard Worker     let guid_fields = guid.as_fields();
232*bb4ee6a4SAndroid Build Coastguard Worker     out.write_all(&guid_fields.0.to_le_bytes())?;
233*bb4ee6a4SAndroid Build Coastguard Worker     out.write_all(&guid_fields.1.to_le_bytes())?;
234*bb4ee6a4SAndroid Build Coastguard Worker     out.write_all(&guid_fields.2.to_le_bytes())?;
235*bb4ee6a4SAndroid Build Coastguard Worker     out.write_all(guid_fields.3)?;
236*bb4ee6a4SAndroid Build Coastguard Worker 
237*bb4ee6a4SAndroid Build Coastguard Worker     Ok(())
238*bb4ee6a4SAndroid Build Coastguard Worker }
239*bb4ee6a4SAndroid Build Coastguard Worker 
240*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
241*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
242*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
243*bb4ee6a4SAndroid Build Coastguard Worker 
244*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
protective_mbr_size()245*bb4ee6a4SAndroid Build Coastguard Worker     fn protective_mbr_size() {
246*bb4ee6a4SAndroid Build Coastguard Worker         let mut buffer = vec![];
247*bb4ee6a4SAndroid Build Coastguard Worker         write_protective_mbr(&mut buffer, 1000 * SECTOR_SIZE).unwrap();
248*bb4ee6a4SAndroid Build Coastguard Worker 
249*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(buffer.len(), SECTOR_SIZE as usize);
250*bb4ee6a4SAndroid Build Coastguard Worker     }
251*bb4ee6a4SAndroid Build Coastguard Worker 
252*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
header_size()253*bb4ee6a4SAndroid Build Coastguard Worker     fn header_size() {
254*bb4ee6a4SAndroid Build Coastguard Worker         let mut buffer = vec![];
255*bb4ee6a4SAndroid Build Coastguard Worker         write_gpt_header(
256*bb4ee6a4SAndroid Build Coastguard Worker             &mut buffer,
257*bb4ee6a4SAndroid Build Coastguard Worker             Uuid::from_u128(0x12345678_1234_5678_abcd_12345678abcd),
258*bb4ee6a4SAndroid Build Coastguard Worker             42,
259*bb4ee6a4SAndroid Build Coastguard Worker             1000 * SECTOR_SIZE,
260*bb4ee6a4SAndroid Build Coastguard Worker             false,
261*bb4ee6a4SAndroid Build Coastguard Worker         )
262*bb4ee6a4SAndroid Build Coastguard Worker         .unwrap();
263*bb4ee6a4SAndroid Build Coastguard Worker 
264*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(buffer.len(), GPT_HEADER_SIZE as usize);
265*bb4ee6a4SAndroid Build Coastguard Worker     }
266*bb4ee6a4SAndroid Build Coastguard Worker 
267*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
partition_entry_size()268*bb4ee6a4SAndroid Build Coastguard Worker     fn partition_entry_size() {
269*bb4ee6a4SAndroid Build Coastguard Worker         let mut buffer = vec![];
270*bb4ee6a4SAndroid Build Coastguard Worker         GptPartitionEntry::default()
271*bb4ee6a4SAndroid Build Coastguard Worker             .write_bytes(&mut buffer)
272*bb4ee6a4SAndroid Build Coastguard Worker             .unwrap();
273*bb4ee6a4SAndroid Build Coastguard Worker 
274*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(buffer.len(), GPT_PARTITION_ENTRY_SIZE as usize);
275*bb4ee6a4SAndroid Build Coastguard Worker     }
276*bb4ee6a4SAndroid Build Coastguard Worker }
277