]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
gpt: move basic header/partition structure of GPT into common code
authorLennart Poettering <lennart@poettering.net>
Tue, 15 Aug 2023 07:52:38 +0000 (09:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 24 Aug 2023 13:25:38 +0000 (15:25 +0200)
This way we can use it at other places too, not just when dissecting
images.

src/shared/dissect-image.c
src/shared/gpt.c
src/shared/gpt.h

index 12c805f449d0b5b3939b4a8c240cdc6e72a47b0e..8acf3c232b857761f7230882cebbf6ec5c6212f8 100644 (file)
@@ -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)
index 34180a32c5b7cb91cac9c11cff4d21dc97adff90..2846bad5b802a76ec572adac72a61ed9a96beb99 100644 (file)
@@ -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;
+}
index 8623a8664e5413bdb368bfc449e8b68f81d80ae2..21976e5311f95d9e3bbabf1c36afc86c6c800f79 100644 (file)
@@ -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);