summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-08-15 09:52:38 +0200
committerLennart Poettering <lennart@poettering.net>2023-08-24 15:25:38 +0200
commit6b0651df60ef3cbb69911d44461bab2a64396b8c (patch)
tree52853afe0191f10f2f9a1a21a5227ce3a01886a1
parentalloc-util: add free_many() helper (diff)
downloadsystemd-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.c37
-rw-r--r--src/shared/gpt.c21
-rw-r--r--src/shared/gpt.h31
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);