diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-08-15 09:52:38 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-08-24 15:25:38 +0200 |
commit | 6b0651df60ef3cbb69911d44461bab2a64396b8c (patch) | |
tree | 52853afe0191f10f2f9a1a21a5227ce3a01886a1 | |
parent | alloc-util: add free_many() helper (diff) | |
download | systemd-6b0651df60ef3cbb69911d44461bab2a64396b8c.tar.xz systemd-6b0651df60ef3cbb69911d44461bab2a64396b8c.zip |
gpt: move basic header/partition structure of GPT into common code
This way we can use it at other places too, not just when dissecting
images.
-rw-r--r-- | src/shared/dissect-image.c | 37 | ||||
-rw-r--r-- | src/shared/gpt.c | 21 | ||||
-rw-r--r-- | src/shared/gpt.h | 31 |
3 files changed, 56 insertions, 33 deletions
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 12c805f449..8acf3c232b 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -111,27 +111,10 @@ int dissect_fstype_ok(const char *fstype) { int probe_sector_size(int fd, uint32_t *ret) { - struct gpt_header { - char signature[8]; - le32_t revision; - le32_t header_size; - le32_t crc32; - le32_t reserved; - le64_t my_lba; - le64_t alternate_lba; - le64_t first_usable_lba; - le64_t last_usable_lba; - sd_id128_t disk_guid; - le64_t partition_entry_lba; - le32_t number_of_partition_entries; - le32_t size_of_partition_entry; - le32_t partition_entry_array_crc32; - } _packed_; - /* Disk images might be for 512B or for 4096 sector sizes, let's try to auto-detect that by searching * for the GPT headers at the relevant byte offsets */ - assert_cc(sizeof(struct gpt_header) == 92); + assert_cc(sizeof(GptHeader) == 92); /* We expect a sector size in the range 512…4096. The GPT header is located in the second * sector. Hence it could be at byte 512 at the earliest, and at byte 4096 at the latest. And we must @@ -151,24 +134,12 @@ int probe_sector_size(int fd, uint32_t *ret) { /* Let's see if we find the GPT partition header with various expected sector sizes */ for (uint32_t sz = 512; sz <= 4096; sz <<= 1) { - struct gpt_header *p; + const GptHeader *p; assert(sizeof(sectors) >= sz * 2); - p = (struct gpt_header*) (sectors + sz); - - if (memcmp(p->signature, (const char[8]) { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }, 8) != 0) - continue; - - if (le32toh(p->revision) != UINT32_C(0x00010000)) /* the only known revision of the spec: 1.0 */ - continue; - - if (le32toh(p->header_size) < sizeof(struct gpt_header)) - continue; - - if (le32toh(p->header_size) > 4096) /* larger than a sector? something is off… */ - continue; + p = (const GptHeader*) (sectors + sz); - if (le64toh(p->my_lba) != 1) /* this sector must claim to be at sector offset 1 */ + if (!gpt_header_has_signature(p)) continue; if (found != 0) diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 34180a32c5..2846bad5b8 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -336,3 +336,24 @@ bool gpt_partition_type_knows_no_auto(GptPartitionType type) { PARTITION_XBOOTLDR, PARTITION_SWAP); } + +bool gpt_header_has_signature(const GptHeader *p) { + assert(p); + + if (memcmp(p->signature, (const char[8]) { 'E', 'F', 'I', ' ', 'P', 'A', 'R', 'T' }, 8) != 0) + return false; + + if (le32toh(p->revision) != UINT32_C(0x00010000)) /* the only known revision of the spec: 1.0 */ + return false; + + if (le32toh(p->header_size) < sizeof(GptHeader)) + return false; + + if (le32toh(p->header_size) > 4096) /* larger than a sector? something is off… */ + return false; + + if (le64toh(p->my_lba) != 1) /* this sector must claim to be at sector offset 1 */ + return false; + + return true; +} diff --git a/src/shared/gpt.h b/src/shared/gpt.h index 8623a8664e..21976e5311 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include <uchar.h> + #include "sd-gpt.h" #include "sd-id128.h" #include "architecture.h" #include "id128-util.h" +#include "sparse-endian.h" /* maximum length of gpt label */ #define GPT_LABEL_MAX 36 @@ -69,3 +72,31 @@ const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type); bool gpt_partition_type_knows_read_only(GptPartitionType type); bool gpt_partition_type_knows_growfs(GptPartitionType type); bool gpt_partition_type_knows_no_auto(GptPartitionType type); + +typedef struct { + uint8_t partition_type_guid[16]; + uint8_t unique_partition_guid[16]; + le64_t starting_lba; + le64_t ending_lba; + le64_t attributes; + char16_t partition_name[36]; +} _packed_ GptPartitionEntry; + +typedef struct { + char signature[8]; + le32_t revision; + le32_t header_size; + le32_t crc32; + le32_t reserved; + le64_t my_lba; + le64_t alternate_lba; + le64_t first_usable_lba; + le64_t last_usable_lba; + uint8_t disk_guid[16]; + le64_t partition_entry_lba; + le32_t number_of_partition_entries; + le32_t size_of_partition_entry; + le32_t partition_entry_array_crc32; +} _packed_ GptHeader; + +bool gpt_header_has_signature(const GptHeader *p); |