]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libfdisk/src/gpt.c
libfdisk: support extended attributes modification
[thirdparty/util-linux.git] / libfdisk / src / gpt.c
1 /*
2 * Copyright (C) 2007 Karel Zak <kzak@redhat.com>
3 * Copyright (C) 2012 Davidlohr Bueso <dave@gnu.org>
4 *
5 * GUID Partition Table (GPT) support. Based on UEFI Specs 2.3.1
6 * Chapter 5: GUID Partition Table (GPT) Disk Layout (Jun 27th, 2012).
7 * Some ideas and inspiration from GNU parted and gptfdisk.
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <inttypes.h>
13 #include <sys/stat.h>
14 #include <sys/utsname.h>
15 #include <sys/types.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <errno.h>
19 #include <ctype.h>
20 #include <uuid.h>
21
22 #include "fdiskP.h"
23
24 #include "nls.h"
25 #include "crc32.h"
26 #include "blkdev.h"
27 #include "bitops.h"
28 #include "strutils.h"
29 #include "all-io.h"
30
31 #define GPT_HEADER_SIGNATURE 0x5452415020494645LL /* EFI PART */
32 #define GPT_HEADER_REVISION_V1_02 0x00010200
33 #define GPT_HEADER_REVISION_V1_00 0x00010000
34 #define GPT_HEADER_REVISION_V0_99 0x00009900
35 #define GPT_HEADER_MINSZ 92 /* bytes */
36
37 #define GPT_PMBR_LBA 0
38 #define GPT_MBR_PROTECTIVE 1
39 #define GPT_MBR_HYBRID 2
40
41 #define GPT_PRIMARY_PARTITION_TABLE_LBA 0x00000001
42
43 #define EFI_PMBR_OSTYPE 0xEE
44 #define MSDOS_MBR_SIGNATURE 0xAA55
45 #define GPT_PART_NAME_LEN (72 / sizeof(uint16_t))
46 #define GPT_NPARTITIONS 128
47
48 /* Globally unique identifier */
49 struct gpt_guid {
50 uint32_t time_low;
51 uint16_t time_mid;
52 uint16_t time_hi_and_version;
53 uint8_t clock_seq_hi;
54 uint8_t clock_seq_low;
55 uint8_t node[6];
56 };
57
58
59 /* only checking that the GUID is 0 is enough to verify an empty partition. */
60 #define GPT_UNUSED_ENTRY_GUID \
61 ((struct gpt_guid) { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, \
62 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }})
63
64 /* Linux native partition type */
65 #define GPT_DEFAULT_ENTRY_TYPE "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
66
67 /*
68 * Attribute bits
69 */
70 struct gpt_attr {
71 uint64_t required_to_function:1;
72 uint64_t no_blockio_protocol:1;
73 uint64_t legacy_bios_bootable:1;
74 uint64_t reserved:45;
75 uint64_t guid_secific:16;
76 } __attribute__ ((packed));
77
78
79
80
81 /* The GPT Partition entry array contains an array of GPT entries. */
82 struct gpt_entry {
83 struct gpt_guid type; /* purpose and type of the partition */
84 struct gpt_guid partition_guid;
85 uint64_t lba_start;
86 uint64_t lba_end;
87 struct gpt_attr attr;
88 uint16_t name[GPT_PART_NAME_LEN];
89 } __attribute__ ((packed));
90
91 /* GPT header */
92 struct gpt_header {
93 uint64_t signature; /* header identification */
94 uint32_t revision; /* header version */
95 uint32_t size; /* in bytes */
96 uint32_t crc32; /* header CRC checksum */
97 uint32_t reserved1; /* must be 0 */
98 uint64_t my_lba; /* LBA that contains this struct (LBA 1) */
99 uint64_t alternative_lba; /* backup GPT header */
100 uint64_t first_usable_lba; /* first usable logical block for partitions */
101 uint64_t last_usable_lba; /* last usable logical block for partitions */
102 struct gpt_guid disk_guid; /* unique disk identifier */
103 uint64_t partition_entry_lba; /* stat LBA of the partition entry array */
104 uint32_t npartition_entries; /* total partition entries - normally 128 */
105 uint32_t sizeof_partition_entry; /* bytes for each GUID pt */
106 uint32_t partition_entry_array_crc32; /* partition CRC checksum */
107 uint8_t reserved2[512 - 92]; /* must be 0 */
108 } __attribute__ ((packed));
109
110 struct gpt_record {
111 uint8_t boot_indicator; /* unused by EFI, set to 0x80 for bootable */
112 uint8_t start_head; /* unused by EFI, pt start in CHS */
113 uint8_t start_sector; /* unused by EFI, pt start in CHS */
114 uint8_t start_track;
115 uint8_t os_type; /* EFI and legacy non-EFI OS types */
116 uint8_t end_head; /* unused by EFI, pt end in CHS */
117 uint8_t end_sector; /* unused by EFI, pt end in CHS */
118 uint8_t end_track; /* unused by EFI, pt end in CHS */
119 uint32_t starting_lba; /* used by EFI - start addr of the on disk pt */
120 uint32_t size_in_lba; /* used by EFI - size of pt in LBA */
121 } __attribute__ ((packed));
122
123 /* Protected MBR and legacy MBR share same structure */
124 struct gpt_legacy_mbr {
125 uint8_t boot_code[440];
126 uint32_t unique_mbr_signature;
127 uint16_t unknown;
128 struct gpt_record partition_record[4];
129 uint16_t signature;
130 } __attribute__ ((packed));
131
132 /*
133 * Here be dragons!
134 * See: http://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs
135 */
136 #define DEF_GUID(_u, _n) \
137 { \
138 .typestr = (_u), \
139 .name = (_n), \
140 }
141
142 static struct fdisk_parttype gpt_parttypes[] =
143 {
144 /* Generic OS */
145 DEF_GUID("C12A7328-F81F-11D2-BA4B-00A0C93EC93B", N_("EFI System")),
146
147 DEF_GUID("024DEE41-33E7-11D3-9D69-0008C781F39F", N_("MBR partition scheme")),
148 DEF_GUID("D3BFE2DE-3DAF-11DF-BA40-E3A556D89593", N_("Intel Fast Flash")),
149
150 /* Hah!IdontneedEFI */
151 DEF_GUID("21686148-6449-6E6F-744E-656564454649", N_("BIOS boot partition")),
152
153 /* Windows */
154 DEF_GUID("E3C9E316-0B5C-4DB8-817D-F92DF00215AE", N_("Microsoft reserved")),
155 DEF_GUID("EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", N_("Microsoft basic data")),
156 DEF_GUID("5808C8AA-7E8F-42E0-85D2-E1E90434CFB3", N_("Microsoft LDM metadata")),
157 DEF_GUID("AF9B60A0-1431-4F62-BC68-3311714A69AD", N_("Microsoft LDM data")),
158 DEF_GUID("DE94BBA4-06D1-4D40-A16A-BFD50179D6AC", N_("Windows recovery environment")),
159 DEF_GUID("37AFFC90-EF7D-4E96-91C3-2D7AE055B174", N_("IBM General Parallel Fs")),
160
161 /* HP-UX */
162 DEF_GUID("75894C1E-3AEB-11D3-B7C1-7B03A0000000", N_("HP-UX data partition")),
163 DEF_GUID("E2A1E728-32E3-11D6-A682-7B03A0000000", N_("HP-UX service partition")),
164
165 /* Linux */
166 DEF_GUID("0FC63DAF-8483-4772-8E79-3D69D8477DE4", N_("Linux filesystem")),
167 DEF_GUID("A19D880F-05FC-4D3B-A006-743F0F84911E", N_("Linux RAID")),
168 DEF_GUID("0657FD6D-A4AB-43C4-84E5-0933C84B4F4F", N_("Linux swap")),
169 DEF_GUID("E6D6D379-F507-44C2-A23C-238F2A3DF928", N_("Linux LVM")),
170 DEF_GUID("8DA63339-0007-60C0-C436-083AC8230908", N_("Linux reserved")),
171
172 /* FreeBSD */
173 DEF_GUID("516E7CB4-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD data")),
174 DEF_GUID("83BD6B9D-7F41-11DC-BE0B-001560B84F0F", N_("FreeBSD boot")),
175 DEF_GUID("516E7CB5-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD swap")),
176 DEF_GUID("516E7CB6-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD UFS")),
177 DEF_GUID("516E7CBA-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD ZFS")),
178 DEF_GUID("516E7CB8-6ECF-11D6-8FF8-00022D09712B", N_("FreeBSD Vinum")),
179
180 /* Apple OSX */
181 DEF_GUID("48465300-0000-11AA-AA11-00306543ECAC", N_("Apple HFS/HFS+")),
182 DEF_GUID("55465300-0000-11AA-AA11-00306543ECAC", N_("Apple UFS")),
183 DEF_GUID("52414944-0000-11AA-AA11-00306543ECAC", N_("Apple RAID")),
184 DEF_GUID("52414944-5F4F-11AA-AA11-00306543ECAC", N_("Apple RAID offline")),
185 DEF_GUID("426F6F74-0000-11AA-AA11-00306543ECAC", N_("Apple boot")),
186 DEF_GUID("4C616265-6C00-11AA-AA11-00306543ECAC", N_("Apple label")),
187 DEF_GUID("5265636F-7665-11AA-AA11-00306543ECAC", N_("Apple TV recovery")),
188 DEF_GUID("53746F72-6167-11AA-AA11-00306543ECAC", N_("Apple Core storage")),
189
190 /* Solaris */
191 DEF_GUID("6A82CB45-1DD2-11B2-99A6-080020736631", N_("Solaris boot")),
192 DEF_GUID("6A85CF4D-1DD2-11B2-99A6-080020736631", N_("Solaris root")),
193 /* same as Apple ZFS */
194 DEF_GUID("6A898CC3-1DD2-11B2-99A6-080020736631", N_("Solaris /usr & Apple ZFS")),
195 DEF_GUID("6A87C46F-1DD2-11B2-99A6-080020736631", N_("Solaris swap")),
196 DEF_GUID("6A8B642B-1DD2-11B2-99A6-080020736631", N_("Solaris backup")),
197 DEF_GUID("6A8EF2E9-1DD2-11B2-99A6-080020736631", N_("Solaris /var")),
198 DEF_GUID("6A90BA39-1DD2-11B2-99A6-080020736631", N_("Solaris /home")),
199 DEF_GUID("6A9283A5-1DD2-11B2-99A6-080020736631", N_("Solaris alternate sector")),
200 DEF_GUID("6A945A3B-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 1")),
201 DEF_GUID("6A9630D1-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 2")),
202 DEF_GUID("6A980767-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 3")),
203 DEF_GUID("6A96237F-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 4")),
204 DEF_GUID("6A8D2AC7-1DD2-11B2-99A6-080020736631", N_("Solaris reserved 5")),
205
206 /* NetBSD */
207 DEF_GUID("49F48D32-B10E-11DC-B99B-0019D1879648", N_("NetBSD swap")),
208 DEF_GUID("49F48D5A-B10E-11DC-B99B-0019D1879648", N_("NetBSD FFS")),
209 DEF_GUID("49F48D82-B10E-11DC-B99B-0019D1879648", N_("NetBSD LFS")),
210 DEF_GUID("2DB519C4-B10E-11DC-B99B-0019D1879648", N_("NetBSD concatenated")),
211 DEF_GUID("2DB519EC-B10E-11DC-B99B-0019D1879648", N_("NetBSD encrypted")),
212 DEF_GUID("49F48DAA-B10E-11DC-B99B-0019D1879648", N_("NetBSD RAID")),
213
214 /* ChromeOS */
215 DEF_GUID("FE3A2A5D-4F32-41A7-B725-ACCC3285A309", N_("ChromeOS kernel")),
216 DEF_GUID("3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC", N_("ChromeOS root fs")),
217 DEF_GUID("2E0A753D-9E48-43B0-8337-B15192CB1B5E", N_("ChromeOS reserved")),
218
219 /* MidnightBSD */
220 DEF_GUID("85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD data")),
221 DEF_GUID("85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD boot")),
222 DEF_GUID("85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD swap")),
223 DEF_GUID("0394Ef8B-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD UFS")),
224 DEF_GUID("85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD ZFS")),
225 DEF_GUID("85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7", N_("MidnightBSD Vinum")),
226 };
227
228 /* gpt_entry macros */
229 #define gpt_partition_start(_e) le64_to_cpu((_e)->lba_start)
230 #define gpt_partition_end(_e) le64_to_cpu((_e)->lba_end)
231
232 /*
233 * in-memory fdisk GPT stuff
234 */
235 struct fdisk_gpt_label {
236 struct fdisk_label head; /* generic part */
237
238 /* gpt specific part */
239 struct gpt_header *pheader; /* primary header */
240 struct gpt_header *bheader; /* backup header */
241 struct gpt_entry *ents; /* entries (partitions) */
242 };
243
244 static void gpt_deinit(struct fdisk_label *lb);
245 static struct fdisk_parttype *gpt_get_partition_type(struct fdisk_context *cxt, size_t i);
246
247 static inline struct fdisk_gpt_label *self_label(struct fdisk_context *cxt)
248 {
249 return (struct fdisk_gpt_label *) cxt->label;
250 }
251
252 /*
253 * Returns the partition length, or 0 if end is before beginning.
254 */
255 static uint64_t gpt_partition_size(const struct gpt_entry *e)
256 {
257 uint64_t start = gpt_partition_start(e);
258 uint64_t end = gpt_partition_end(e);
259
260 return start > end ? 0 : end - start + 1ULL;
261 }
262
263 #ifdef CONFIG_LIBFDISK_DEBUG
264 /* prints UUID in the real byte order! */
265 static void dbgprint_uuid(const char *mesg, struct gpt_guid *guid)
266 {
267 const unsigned char *uuid = (unsigned char *) guid;
268
269 fprintf(stderr, "%s: "
270 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
271 mesg,
272 uuid[0], uuid[1], uuid[2], uuid[3],
273 uuid[4], uuid[5],
274 uuid[6], uuid[7],
275 uuid[8], uuid[9],
276 uuid[10], uuid[11], uuid[12], uuid[13], uuid[14],uuid[15]);
277 }
278 #endif
279
280 /*
281 * UUID is traditionally 16 byte big-endian array, except Intel EFI
282 * specification where the UUID is a structure of little-endian fields.
283 */
284 static void swap_efi_guid(struct gpt_guid *uid)
285 {
286 uid->time_low = swab32(uid->time_low);
287 uid->time_mid = swab16(uid->time_mid);
288 uid->time_hi_and_version = swab16(uid->time_hi_and_version);
289 }
290
291 static int string_to_guid(const char *in, struct gpt_guid *guid)
292 {
293 if (uuid_parse(in, (unsigned char *) guid)) /* BE */
294 return -1;
295 swap_efi_guid(guid); /* LE */
296 return 0;
297 }
298
299 static char *guid_to_string(struct gpt_guid *guid, char *out)
300 {
301 struct gpt_guid u = *guid; /* LE */
302
303 swap_efi_guid(&u); /* BE */
304 uuid_unparse_upper((unsigned char *) &u, out);
305
306 return out;
307 }
308
309 static const char *gpt_get_header_revstr(struct gpt_header *header)
310 {
311 if (!header)
312 goto unknown;
313
314 switch (header->revision) {
315 case GPT_HEADER_REVISION_V1_02:
316 return "1.2";
317 case GPT_HEADER_REVISION_V1_00:
318 return "1.0";
319 case GPT_HEADER_REVISION_V0_99:
320 return "0.99";
321 default:
322 goto unknown;
323 }
324
325 unknown:
326 return "unknown";
327 }
328
329 static inline int partition_unused(const struct gpt_entry *e)
330 {
331 return !memcmp(&e->type, &GPT_UNUSED_ENTRY_GUID,
332 sizeof(struct gpt_guid));
333 }
334
335 /*
336 * Builds a clean new valid protective MBR - will wipe out any existing data.
337 * Returns 0 on success, otherwise < 0 on error.
338 */
339 static int gpt_mknew_pmbr(struct fdisk_context *cxt)
340 {
341 struct gpt_legacy_mbr *pmbr = NULL;
342
343 if (!cxt || !cxt->firstsector)
344 return -ENOSYS;
345
346 fdisk_zeroize_firstsector(cxt);
347
348 pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
349
350 pmbr->signature = cpu_to_le16(MSDOS_MBR_SIGNATURE);
351 pmbr->partition_record[0].os_type = EFI_PMBR_OSTYPE;
352 pmbr->partition_record[0].start_sector = 1;
353 pmbr->partition_record[0].end_head = 0xFE;
354 pmbr->partition_record[0].end_sector = 0xFF;
355 pmbr->partition_record[0].end_track = 0xFF;
356 pmbr->partition_record[0].starting_lba = cpu_to_le32(1);
357 pmbr->partition_record[0].size_in_lba =
358 cpu_to_le32(min((uint32_t) cxt->total_sectors - 1, 0xFFFFFFFF));
359
360 return 0;
361 }
362
363 /* some universal differences between the headers */
364 static void gpt_mknew_header_common(struct fdisk_context *cxt,
365 struct gpt_header *header, uint64_t lba)
366 {
367 if (!cxt || !header)
368 return;
369
370 header->my_lba = cpu_to_le64(lba);
371
372 if (lba == GPT_PRIMARY_PARTITION_TABLE_LBA) { /* primary */
373 header->alternative_lba = cpu_to_le64(cxt->total_sectors - 1);
374 header->partition_entry_lba = cpu_to_le64(2);
375 } else { /* backup */
376 uint64_t esz = le32_to_cpu(header->npartition_entries) * sizeof(struct gpt_entry);
377 uint64_t esects = (esz + cxt->sector_size - 1) / cxt->sector_size;
378
379 header->alternative_lba = cpu_to_le64(GPT_PRIMARY_PARTITION_TABLE_LBA);
380 header->partition_entry_lba = cpu_to_le64(cxt->total_sectors - 1 - esects);
381 }
382 }
383
384 /*
385 * Builds a new GPT header (at sector lba) from a backup header2.
386 * If building a primary header, then backup is the secondary, and vice versa.
387 *
388 * Always pass a new (zeroized) header to build upon as we don't
389 * explicitly zero-set some values such as CRCs and reserved.
390 *
391 * Returns 0 on success, otherwise < 0 on error.
392 */
393 static int gpt_mknew_header_from_bkp(struct fdisk_context *cxt,
394 struct gpt_header *header,
395 uint64_t lba,
396 struct gpt_header *header2)
397 {
398 if (!cxt || !header || !header2)
399 return -ENOSYS;
400
401 header->signature = header2->signature;
402 header->revision = header2->revision;
403 header->size = header2->size;
404 header->npartition_entries = header2->npartition_entries;
405 header->sizeof_partition_entry = header2->sizeof_partition_entry;
406 header->first_usable_lba = header2->first_usable_lba;
407 header->last_usable_lba = header2->last_usable_lba;
408
409 memcpy(&header->disk_guid,
410 &header2->disk_guid, sizeof(header2->disk_guid));
411 gpt_mknew_header_common(cxt, header, lba);
412
413 return 0;
414 }
415
416 /*
417 * Builds a clean new GPT header (currently under revision 1.0).
418 *
419 * Always pass a new (zeroized) header to build upon as we don't
420 * explicitly zero-set some values such as CRCs and reserved.
421 *
422 * Returns 0 on success, otherwise < 0 on error.
423 */
424 static int gpt_mknew_header(struct fdisk_context *cxt,
425 struct gpt_header *header, uint64_t lba)
426 {
427 uint64_t esz = 0, first, last;
428
429 if (!cxt || !header)
430 return -ENOSYS;
431
432 esz = sizeof(struct gpt_entry) * GPT_NPARTITIONS / cxt->sector_size;
433
434 header->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
435 header->revision = cpu_to_le32(GPT_HEADER_REVISION_V1_00);
436 header->size = cpu_to_le32(sizeof(struct gpt_header));
437
438 /*
439 * 128 partitions is the default. It can go behond this, however,
440 * we're creating a de facto header here, so no funny business.
441 */
442 header->npartition_entries = cpu_to_le32(GPT_NPARTITIONS);
443 header->sizeof_partition_entry = cpu_to_le32(sizeof(struct gpt_entry));
444
445 last = cxt->total_sectors - 2 - esz;
446 first = esz + 2;
447
448 if (first < cxt->first_lba && cxt->first_lba < last)
449 /* Align according to topology */
450 first = cxt->first_lba;
451
452 header->first_usable_lba = cpu_to_le64(first);
453 header->last_usable_lba = cpu_to_le64(last);
454
455 gpt_mknew_header_common(cxt, header, lba);
456 uuid_generate_random((unsigned char *) &header->disk_guid);
457 swap_efi_guid(&header->disk_guid);
458
459 return 0;
460 }
461
462 /*
463 * Checks if there is a valid protective MBR partition table.
464 * Returns 0 if it is invalid or failure. Otherwise, return
465 * GPT_MBR_PROTECTIVE or GPT_MBR_HYBRID, depeding on the detection.
466 */
467 static int valid_pmbr(struct fdisk_context *cxt)
468 {
469 int i, part = 0, ret = 0; /* invalid by default */
470 struct gpt_legacy_mbr *pmbr = NULL;
471 uint32_t sz_lba = 0;
472
473 if (!cxt->firstsector)
474 goto done;
475
476 pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
477
478 if (le16_to_cpu(pmbr->signature) != MSDOS_MBR_SIGNATURE)
479 goto done;
480
481 /* LBA of the GPT partition header */
482 if (pmbr->partition_record[0].starting_lba !=
483 cpu_to_le32(GPT_PRIMARY_PARTITION_TABLE_LBA))
484 goto done;
485
486 /* seems like a valid MBR was found, check DOS primary partitions */
487 for (i = 0; i < 4; i++) {
488 if (pmbr->partition_record[i].os_type == EFI_PMBR_OSTYPE) {
489 /*
490 * Ok, we at least know that there's a protective MBR,
491 * now check if there are other partition types for
492 * hybrid MBR.
493 */
494 part = i;
495 ret = GPT_MBR_PROTECTIVE;
496 goto check_hybrid;
497 }
498 }
499
500 if (ret != GPT_MBR_PROTECTIVE)
501 goto done;
502 check_hybrid:
503 for (i = 0 ; i < 4; i++) {
504 if ((pmbr->partition_record[i].os_type != EFI_PMBR_OSTYPE) &&
505 (pmbr->partition_record[i].os_type != 0x00))
506 ret = GPT_MBR_HYBRID;
507 }
508
509 /*
510 * Protective MBRs take up the lesser of the whole disk
511 * or 2 TiB (32bit LBA), ignoring the rest of the disk.
512 * Some partitioning programs, nonetheless, choose to set
513 * the size to the maximum 32-bit limitation, disregarding
514 * the disk size.
515 *
516 * Hybrid MBRs do not necessarily comply with this.
517 *
518 * Consider a bad value here to be a warning to support dd-ing
519 * an image from a smaller disk to a bigger disk.
520 */
521 if (ret == GPT_MBR_PROTECTIVE) {
522 sz_lba = le32_to_cpu(pmbr->partition_record[part].size_in_lba);
523 if (sz_lba != (uint32_t) cxt->total_sectors - 1 && sz_lba != 0xFFFFFFFF) {
524 fdisk_warnx(cxt, _("GPT PMBR size mismatch (%u != %u) "
525 "will be corrected by w(rite)."),
526 sz_lba,
527 (uint32_t) cxt->total_sectors - 1);
528 fdisk_label_set_changed(cxt->label, 1);
529 }
530 }
531 done:
532 return ret;
533 }
534
535 static uint64_t last_lba(struct fdisk_context *cxt)
536 {
537 struct stat s;
538
539 memset(&s, 0, sizeof(s));
540 if (fstat(cxt->dev_fd, &s) == -1) {
541 fdisk_warn(cxt, _("gpt: stat() failed"));
542 return 0;
543 }
544
545 if (S_ISBLK(s.st_mode))
546 return cxt->total_sectors - 1;
547 else if (S_ISREG(s.st_mode)) {
548 uint64_t sectors = s.st_size >> cxt->sector_size;
549 return (sectors / cxt->sector_size) - 1ULL;
550 } else
551 fdisk_warnx(cxt, _("gpt: cannot handle files with mode %o"), s.st_mode);
552 return 0;
553 }
554
555 static ssize_t read_lba(struct fdisk_context *cxt, uint64_t lba,
556 void *buffer, const size_t bytes)
557 {
558 off_t offset = lba * cxt->sector_size;
559
560 if (lseek(cxt->dev_fd, offset, SEEK_SET) == (off_t) -1)
561 return -1;
562 return read(cxt->dev_fd, buffer, bytes) != bytes;
563 }
564
565
566 /* Returns the GPT entry array */
567 static struct gpt_entry *gpt_read_entries(struct fdisk_context *cxt,
568 struct gpt_header *header)
569 {
570 ssize_t sz;
571 struct gpt_entry *ret = NULL;
572 off_t offset;
573
574 assert(cxt);
575 assert(header);
576
577 sz = le32_to_cpu(header->npartition_entries) *
578 le32_to_cpu(header->sizeof_partition_entry);
579
580 ret = calloc(1, sz);
581 if (!ret)
582 return NULL;
583 offset = le64_to_cpu(header->partition_entry_lba) *
584 cxt->sector_size;
585
586 if (offset != lseek(cxt->dev_fd, offset, SEEK_SET))
587 goto fail;
588 if (sz != read(cxt->dev_fd, ret, sz))
589 goto fail;
590
591 return ret;
592
593 fail:
594 free(ret);
595 return NULL;
596 }
597
598 static inline uint32_t count_crc32(const unsigned char *buf, size_t len)
599 {
600 return (crc32(~0L, buf, len) ^ ~0L);
601 }
602
603 /*
604 * Recompute header and partition array 32bit CRC checksums.
605 * This function does not fail - if there's corruption, then it
606 * will be reported when checksuming it again (ie: probing or verify).
607 */
608 static void gpt_recompute_crc(struct gpt_header *header, struct gpt_entry *ents)
609 {
610 uint32_t crc = 0;
611 size_t entry_sz = 0;
612
613 if (!header)
614 return;
615
616 /* header CRC */
617 header->crc32 = 0;
618 crc = count_crc32((unsigned char *) header, le32_to_cpu(header->size));
619 header->crc32 = cpu_to_le32(crc);
620
621 /* partition entry array CRC */
622 header->partition_entry_array_crc32 = 0;
623 entry_sz = le32_to_cpu(header->npartition_entries) *
624 le32_to_cpu(header->sizeof_partition_entry);
625
626 crc = count_crc32((unsigned char *) ents, entry_sz);
627 header->partition_entry_array_crc32 = cpu_to_le32(crc);
628 }
629
630 /*
631 * Compute the 32bit CRC checksum of the partition table header.
632 * Returns 1 if it is valid, otherwise 0.
633 */
634 static int gpt_check_header_crc(struct gpt_header *header, struct gpt_entry *ents)
635 {
636 uint32_t crc, orgcrc = le32_to_cpu(header->crc32);
637
638 header->crc32 = 0;
639 crc = count_crc32((unsigned char *) header, le32_to_cpu(header->size));
640 header->crc32 = cpu_to_le32(orgcrc);
641
642 if (crc == le32_to_cpu(header->crc32))
643 return 1;
644
645 /*
646 * If we have checksum mismatch it may be due to stale data,
647 * like a partition being added or deleted. Recompute the CRC again
648 * and make sure this is not the case.
649 */
650 if (ents) {
651 gpt_recompute_crc(header, ents);
652 orgcrc = le32_to_cpu(header->crc32);
653 header->crc32 = 0;
654 crc = count_crc32((unsigned char *) header, le32_to_cpu(header->size));
655 header->crc32 = cpu_to_le32(orgcrc);
656
657 return crc == le32_to_cpu(header->crc32);
658 }
659
660 return 0;
661 }
662
663 /*
664 * It initializes the partition entry array.
665 * Returns 1 if the checksum is valid, otherwise 0.
666 */
667 static int gpt_check_entryarr_crc(struct gpt_header *header,
668 struct gpt_entry *ents)
669 {
670 int ret = 0;
671 ssize_t entry_sz;
672 uint32_t crc;
673
674 if (!header || !ents)
675 goto done;
676
677 entry_sz = le32_to_cpu(header->npartition_entries) *
678 le32_to_cpu(header->sizeof_partition_entry);
679
680 if (!entry_sz)
681 goto done;
682
683 crc = count_crc32((unsigned char *) ents, entry_sz);
684 ret = (crc == le32_to_cpu(header->partition_entry_array_crc32));
685 done:
686 return ret;
687 }
688
689 static int gpt_check_lba_sanity(struct fdisk_context *cxt, struct gpt_header *header)
690 {
691 int ret = 0;
692 uint64_t lu, fu, lastlba = last_lba(cxt);
693
694 fu = le64_to_cpu(header->first_usable_lba);
695 lu = le64_to_cpu(header->last_usable_lba);
696
697 /* check if first and last usable LBA make sense */
698 if (lu < fu) {
699 DBG(LABEL, dbgprint("error: header last LBA is before first LBA"));
700 goto done;
701 }
702
703 /* check if first and last usable LBAs with the disk's last LBA */
704 if (fu > lastlba || lu > lastlba) {
705 DBG(LABEL, dbgprint("error: header LBAs are after the disk's last LBA"));
706 goto done;
707 }
708
709 /* the header has to be outside usable range */
710 if (fu < GPT_PRIMARY_PARTITION_TABLE_LBA &&
711 GPT_PRIMARY_PARTITION_TABLE_LBA < lu) {
712 DBG(LABEL, dbgprint("error: header outside of usable range"));
713 goto done;
714 }
715
716 ret = 1; /* sane */
717 done:
718 return ret;
719 }
720
721 /* Check if there is a valid header signature */
722 static int gpt_check_signature(struct gpt_header *header)
723 {
724 return header->signature == cpu_to_le64(GPT_HEADER_SIGNATURE);
725 }
726
727 /*
728 * Return the specified GPT Header, or NULL upon failure/invalid.
729 * Note that all tests must pass to ensure a valid header,
730 * we do not rely on only testing the signature for a valid probe.
731 */
732 static struct gpt_header *gpt_read_header(struct fdisk_context *cxt,
733 uint64_t lba,
734 struct gpt_entry **_ents)
735 {
736 struct gpt_header *header = NULL;
737 struct gpt_entry *ents = NULL;
738 uint32_t hsz;
739
740 if (!cxt)
741 return NULL;
742
743 header = calloc(1, sizeof(*header));
744 if (!header)
745 return NULL;
746
747 /* read and verify header */
748 if (read_lba(cxt, lba, header, sizeof(struct gpt_header)) != 0)
749 goto invalid;
750
751 if (!gpt_check_signature(header))
752 goto invalid;
753
754 if (!gpt_check_header_crc(header, NULL))
755 goto invalid;
756
757 /* read and verify entries */
758 ents = gpt_read_entries(cxt, header);
759 if (!ents)
760 goto invalid;
761
762 if (!gpt_check_entryarr_crc(header, ents))
763 goto invalid;
764
765 if (!gpt_check_lba_sanity(cxt, header))
766 goto invalid;
767
768 /* valid header must be at MyLBA */
769 if (le64_to_cpu(header->my_lba) != lba)
770 goto invalid;
771
772 /* make sure header size is between 92 and sector size bytes */
773 hsz = le32_to_cpu(header->size);
774 if (hsz < GPT_HEADER_MINSZ || hsz > cxt->sector_size)
775 goto invalid;
776
777 if (_ents)
778 *_ents = ents;
779 else
780 free(ents);
781
782 return header;
783 invalid:
784 free(header);
785 free(ents);
786 return NULL;
787 }
788
789
790 static int gpt_locate_disklabel(struct fdisk_context *cxt, int n,
791 const char **name, off_t *offset, size_t *size)
792 {
793 struct fdisk_gpt_label *gpt;
794
795 assert(cxt);
796
797 *name = NULL;
798 *offset = 0;
799 *size = 0;
800
801 switch (n) {
802 case 0:
803 *name = "PMBR";
804 *offset = 0;
805 *size = 512;
806 break;
807 case 1:
808 *name = _("GPT Header");
809 *offset = GPT_PRIMARY_PARTITION_TABLE_LBA * cxt->sector_size;
810 *size = sizeof(struct gpt_header);
811 break;
812 case 2:
813 *name = _("GPT Entries");
814 gpt = self_label(cxt);
815 *offset = le64_to_cpu(gpt->pheader->partition_entry_lba) * cxt->sector_size;
816 *size = le32_to_cpu(gpt->pheader->npartition_entries) *
817 le32_to_cpu(gpt->pheader->sizeof_partition_entry);
818 break;
819 default:
820 return 1; /* no more chunks */
821 }
822
823 return 0;
824 }
825
826
827
828 /*
829 * Returns the number of partitions that are in use.
830 */
831 static unsigned partitions_in_use(struct gpt_header *header, struct gpt_entry *e)
832 {
833 uint32_t i, used = 0;
834
835 if (!header || ! e)
836 return 0;
837
838 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++)
839 if (!partition_unused(&e[i]))
840 used++;
841 return used;
842 }
843
844
845 /*
846 * Check if a partition is too big for the disk (sectors).
847 * Returns the faulting partition number, otherwise 0.
848 */
849 static uint32_t partition_check_too_big(struct gpt_header *header,
850 struct gpt_entry *e, uint64_t sectors)
851 {
852 uint32_t i;
853
854 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++) {
855 if (partition_unused(&e[i]))
856 continue;
857 if (gpt_partition_end(&e[i]) >= sectors)
858 return i + 1;
859 }
860
861 return 0;
862 }
863
864 /*
865 * Check if a partition ends before it begins
866 * Returns the faulting partition number, otherwise 0.
867 */
868 static uint32_t partition_start_after_end(struct gpt_header *header, struct gpt_entry *e)
869 {
870 uint32_t i;
871
872 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++) {
873 if (partition_unused(&e[i]))
874 continue;
875 if (gpt_partition_start(&e[i]) > gpt_partition_end(&e[i]))
876 return i + 1;
877 }
878
879 return 0;
880 }
881
882 /*
883 * Check if partition e1 overlaps with partition e2
884 */
885 static inline int partition_overlap(struct gpt_entry *e1, struct gpt_entry *e2)
886 {
887 uint64_t start1 = gpt_partition_start(e1);
888 uint64_t end1 = gpt_partition_end(e1);
889 uint64_t start2 = gpt_partition_start(e2);
890 uint64_t end2 = gpt_partition_end(e2);
891
892 return (start1 && start2 && (start1 <= end2) != (end1 < start2));
893 }
894
895 /*
896 * Find any paritions that overlap.
897 */
898 static uint32_t partition_check_overlaps(struct gpt_header *header, struct gpt_entry *e)
899 {
900 uint32_t i, j;
901
902 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++)
903 for (j = 0; j < i; j++) {
904 if (partition_unused(&e[i]) ||
905 partition_unused(&e[j]))
906 continue;
907 if (partition_overlap(&e[i], &e[j])) {
908 DBG(LABEL, dbgprint("GPT partitions overlap detected [%u vs. %u]", i, j));
909 return i + 1;
910 }
911 }
912
913 return 0;
914 }
915
916 /*
917 * Find the first available block after the starting point; returns 0 if
918 * there are no available blocks left, or error. From gdisk.
919 */
920 static uint64_t find_first_available(struct gpt_header *header,
921 struct gpt_entry *e, uint64_t start)
922 {
923 uint64_t first;
924 uint32_t i, first_moved = 0;
925
926 uint64_t fu, lu;
927
928 if (!header || !e)
929 return 0;
930
931 fu = le64_to_cpu(header->first_usable_lba);
932 lu = le64_to_cpu(header->last_usable_lba);
933
934 /*
935 * Begin from the specified starting point or from the first usable
936 * LBA, whichever is greater...
937 */
938 first = start < fu ? fu : start;
939
940 /*
941 * Now search through all partitions; if first is within an
942 * existing partition, move it to the next sector after that
943 * partition and repeat. If first was moved, set firstMoved
944 * flag; repeat until firstMoved is not set, so as to catch
945 * cases where partitions are out of sequential order....
946 */
947 do {
948 first_moved = 0;
949 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++) {
950 if (partition_unused(&e[i]))
951 continue;
952 if (first < gpt_partition_start(&e[i]))
953 continue;
954 if (first <= gpt_partition_end(&e[i])) {
955 first = gpt_partition_end(&e[i]) + 1;
956 first_moved = 1;
957 }
958 }
959 } while (first_moved == 1);
960
961 if (first > lu)
962 first = 0;
963
964 return first;
965 }
966
967
968 /* Returns last available sector in the free space pointed to by start. From gdisk. */
969 static uint64_t find_last_free(struct gpt_header *header,
970 struct gpt_entry *e, uint64_t start)
971 {
972 uint32_t i;
973 uint64_t nearest_start;
974
975 if (!header || !e)
976 return 0;
977
978 nearest_start = le64_to_cpu(header->last_usable_lba);
979
980 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++) {
981 uint64_t ps = gpt_partition_start(&e[i]);
982
983 if (nearest_start > ps && ps > start)
984 nearest_start = ps - 1;
985 }
986
987 return nearest_start;
988 }
989
990 /* Returns the last free sector on the disk. From gdisk. */
991 static uint64_t find_last_free_sector(struct gpt_header *header,
992 struct gpt_entry *e)
993 {
994 uint32_t i, last_moved;
995 uint64_t last = 0;
996
997 if (!header || !e)
998 goto done;
999
1000 /* start by assuming the last usable LBA is available */
1001 last = le64_to_cpu(header->last_usable_lba);
1002 do {
1003 last_moved = 0;
1004 for (i = 0; i < le32_to_cpu(header->npartition_entries); i++) {
1005 if ((last >= gpt_partition_start(&e[i])) &&
1006 (last <= gpt_partition_end(&e[i]))) {
1007 last = gpt_partition_start(&e[i]) - 1;
1008 last_moved = 1;
1009 }
1010 }
1011 } while (last_moved == 1);
1012 done:
1013 return last;
1014 }
1015
1016 /*
1017 * Finds the first available sector in the largest block of unallocated
1018 * space on the disk. Returns 0 if there are no available blocks left.
1019 * From gdisk.
1020 */
1021 static uint64_t find_first_in_largest(struct gpt_header *header, struct gpt_entry *e)
1022 {
1023 uint64_t start = 0, first_sect, last_sect;
1024 uint64_t segment_size, selected_size = 0, selected_segment = 0;
1025
1026 if (!header || !e)
1027 goto done;
1028
1029 do {
1030 first_sect = find_first_available(header, e, start);
1031 if (first_sect != 0) {
1032 last_sect = find_last_free(header, e, first_sect);
1033 segment_size = last_sect - first_sect + 1;
1034
1035 if (segment_size > selected_size) {
1036 selected_size = segment_size;
1037 selected_segment = first_sect;
1038 }
1039 start = last_sect + 1;
1040 }
1041 } while (first_sect != 0);
1042
1043 done:
1044 return selected_segment;
1045 }
1046
1047 /*
1048 * Find the total number of free sectors, the number of segments in which
1049 * they reside, and the size of the largest of those segments. From gdisk.
1050 */
1051 static uint64_t get_free_sectors(struct fdisk_context *cxt, struct gpt_header *header,
1052 struct gpt_entry *e, uint32_t *nsegments,
1053 uint64_t *largest_segment)
1054 {
1055 uint32_t num = 0;
1056 uint64_t first_sect, last_sect;
1057 uint64_t largest_seg = 0, segment_sz;
1058 uint64_t totfound = 0, start = 0; /* starting point for each search */
1059
1060 if (!cxt->total_sectors)
1061 goto done;
1062
1063 do {
1064 first_sect = find_first_available(header, e, start);
1065 if (first_sect) {
1066 last_sect = find_last_free(header, e, first_sect);
1067 segment_sz = last_sect - first_sect + 1;
1068
1069 if (segment_sz > largest_seg)
1070 largest_seg = segment_sz;
1071 totfound += segment_sz;
1072 num++;
1073 start = last_sect + 1;
1074 }
1075 } while (first_sect);
1076
1077 done:
1078 if (nsegments)
1079 *nsegments = num;
1080 if (largest_segment)
1081 *largest_segment = largest_seg;
1082
1083 return totfound;
1084 }
1085
1086 static int gpt_probe_label(struct fdisk_context *cxt)
1087 {
1088 int mbr_type;
1089 struct fdisk_gpt_label *gpt;
1090
1091 assert(cxt);
1092 assert(cxt->label);
1093 assert(fdisk_is_disklabel(cxt, GPT));
1094
1095 gpt = self_label(cxt);
1096
1097 mbr_type = valid_pmbr(cxt);
1098 if (!mbr_type)
1099 goto failed;
1100
1101 DBG(LABEL, dbgprint("found a %s MBR", mbr_type == GPT_MBR_PROTECTIVE ?
1102 "protective" : "hybrid"));
1103
1104 /* primary header */
1105 gpt->pheader = gpt_read_header(cxt, GPT_PRIMARY_PARTITION_TABLE_LBA,
1106 &gpt->ents);
1107
1108 /*
1109 * TODO: If the primary GPT is corrupt, we must check the last LBA of the
1110 * device to see if it has a valid GPT Header and point to a valid GPT
1111 * Partition Entry Array.
1112 * If it points to a valid GPT Partition Entry Array, then software should
1113 * restore the primary GPT if allowed by platform policy settings.
1114 *
1115 * For now we just abort GPT probing!
1116 */
1117 if (!gpt->pheader || !gpt->ents)
1118 goto failed;
1119
1120 /* OK, probing passed, now initialize backup header and fdisk variables. */
1121 gpt->bheader = gpt_read_header(cxt, last_lba(cxt), NULL);
1122
1123 cxt->label->nparts_max = le32_to_cpu(gpt->pheader->npartition_entries);
1124 cxt->label->nparts_cur = partitions_in_use(gpt->pheader, gpt->ents);
1125 return 1;
1126 failed:
1127 DBG(LABEL, dbgprint("GPT probe failed"));
1128 gpt_deinit(cxt->label);
1129 return 0;
1130 }
1131
1132 /*
1133 * Stolen from libblkid - can be removed once partition semantics
1134 * are added to the fdisk API.
1135 */
1136 static char *encode_to_utf8(unsigned char *src, size_t count)
1137 {
1138 uint16_t c;
1139 char *dest;
1140 size_t i, j, len = count;
1141
1142 dest = calloc(1, count);
1143 if (!dest)
1144 return NULL;
1145
1146 for (j = i = 0; i + 2 <= count; i += 2) {
1147 /* always little endian */
1148 c = (src[i+1] << 8) | src[i];
1149 if (c == 0) {
1150 dest[j] = '\0';
1151 break;
1152 } else if (c < 0x80) {
1153 if (j+1 >= len)
1154 break;
1155 dest[j++] = (uint8_t) c;
1156 } else if (c < 0x800) {
1157 if (j+2 >= len)
1158 break;
1159 dest[j++] = (uint8_t) (0xc0 | (c >> 6));
1160 dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
1161 } else {
1162 if (j+3 >= len)
1163 break;
1164 dest[j++] = (uint8_t) (0xe0 | (c >> 12));
1165 dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
1166 dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
1167 }
1168 }
1169 dest[j] = '\0';
1170
1171 return dest;
1172 }
1173
1174 /* convert GUID Specific attributes to string, result is a list of the enabled
1175 * bits (e.g. "60,62,63" for enabled bits 60, 62 and 63).
1176 *
1177 * Returns newly allocated string or NULL in case of error.
1178 *
1179 * see struct gpt_attr definition for more details.
1180 */
1181 static char *guid_attrs_to_string(struct gpt_attr *attr, char **res)
1182 {
1183 char *bits = (char *) attr, *end;
1184 size_t i, count = 0, len;
1185
1186 end = *res = calloc(1, 16 * 3 + 6); /* three bytes for one bit + \0 */
1187 if (!*res)
1188 return NULL;
1189
1190 for (i = 48; i < 64; i++) {
1191 if (!isset(bits, i))
1192 continue;
1193 count++;
1194 if (count > 1)
1195 len = snprintf(end, 4, ",%zu", i);
1196 else
1197 len = snprintf(end, 8, "GUID:%zu", i);
1198 end += len;
1199 }
1200
1201 return *res;
1202 }
1203
1204 /*
1205 * List label partitions.
1206 * This function must currently exist to comply with standard fdisk
1207 * requirements, but once partition semantics are added to the fdisk
1208 * API it can be removed for custom implementation (see gpt_label struct).
1209 */
1210 static int gpt_list_disklabel(struct fdisk_context *cxt)
1211 {
1212 int rc, trunc = TT_FL_TRUNC;
1213 uint32_t i;
1214 struct fdisk_gpt_label *gpt;
1215 struct gpt_header *h;
1216 uint64_t fu;
1217 uint64_t lu;
1218 struct tt *tb = NULL;
1219
1220 assert(cxt);
1221 assert(cxt->label);
1222 assert(fdisk_is_disklabel(cxt, GPT));
1223
1224 gpt = self_label(cxt);
1225 h = gpt->pheader;
1226 fu = le64_to_cpu(gpt->pheader->first_usable_lba);
1227 lu = le64_to_cpu(gpt->pheader->last_usable_lba);
1228
1229 tb = tt_new_table(TT_FL_FREEDATA);
1230 if (!tb)
1231 return -ENOMEM;
1232
1233 /* don't trunc anything in expert mode */
1234 if (fdisk_context_display_details(cxt)) {
1235 trunc = 0;
1236 fdisk_colon(cxt, _("First LBA: %ju"), h->first_usable_lba);
1237 fdisk_colon(cxt, _("Last LBA: %ju"), h->last_usable_lba);
1238 fdisk_colon(cxt, _("Alternative LBA: %ju"), h->alternative_lba);
1239 fdisk_colon(cxt, _("Partitions entries LBA: %ju"), h->partition_entry_lba);
1240 fdisk_colon(cxt, _("Allocated partition entries: %u"), h->npartition_entries);
1241 }
1242 tt_define_column(tb, _("Device"), 0.1, 0);
1243 tt_define_column(tb, _("Start"), 12, TT_FL_RIGHT);
1244 tt_define_column(tb, _("End"), 12, TT_FL_RIGHT);
1245 tt_define_column(tb, _("Size"), 6, TT_FL_RIGHT);
1246 tt_define_column(tb, _("Type"), 0.1, trunc);
1247
1248 if (fdisk_context_display_details(cxt)) {
1249 tt_define_column(tb, _("UUID"), 36, 0);
1250 tt_define_column(tb, _("Name"), 0.2, trunc);
1251 tt_define_column(tb, _("Attributes"), 0, 0);
1252 }
1253
1254 for (i = 0; i < le32_to_cpu(h->npartition_entries); i++) {
1255 struct gpt_entry *e = &gpt->ents[i];
1256 char *sizestr = NULL, *p;
1257 uint64_t start = gpt_partition_start(e);
1258 uint64_t size = gpt_partition_size(e);
1259 struct fdisk_parttype *t;
1260 struct tt_line *ln;
1261 char u_str[37];
1262
1263 if (partition_unused(&gpt->ents[i]) || start == 0)
1264 continue;
1265 /* the partition has to inside usable range */
1266 if (start < fu || start + size - 1 > lu)
1267 continue;
1268 ln = tt_add_line(tb, NULL);
1269 if (!ln)
1270 continue;
1271
1272 if (fdisk_context_display_details(cxt) &&
1273 asprintf(&p, "%ju", size * cxt->sector_size) > 0)
1274 sizestr = p;
1275 else
1276 sizestr = size_to_human_string(SIZE_SUFFIX_1LETTER,
1277 size * cxt->sector_size);
1278 t = fdisk_get_partition_type(cxt, i);
1279
1280 /* basic columns */
1281 p = fdisk_partname(cxt->dev_path, i + 1);
1282 if (p)
1283 tt_line_set_data(ln, 0, p);
1284 if (asprintf(&p, "%ju", start) > 0)
1285 tt_line_set_data(ln, 1, p);
1286 if (asprintf(&p, "%ju", gpt_partition_end(e)) > 0)
1287 tt_line_set_data(ln, 2, p);
1288 if (sizestr)
1289 tt_line_set_data(ln, 3, sizestr);
1290 if (t && t->name)
1291 tt_line_set_data(ln, 4, strdup(t->name));
1292
1293 /* expert menu column(s) */
1294 if (fdisk_context_display_details(cxt)) {
1295 char *buf = NULL;
1296 char *name = encode_to_utf8(
1297 (unsigned char *)e->name,
1298 sizeof(e->name));
1299
1300 if (guid_to_string(&e->partition_guid, u_str))
1301 tt_line_set_data(ln, 5, strdup(u_str));
1302 if (name)
1303 tt_line_set_data(ln, 6, name);
1304 if (asprintf(&p, "%s%s%s%s",
1305 e->attr.required_to_function ? "Required " : "",
1306 e->attr.legacy_bios_bootable ? "LegacyBoot " : "",
1307 e->attr.no_blockio_protocol ? "NoBlockIO " : "",
1308 guid_attrs_to_string(&e->attr, &buf)) > 0)
1309 tt_line_set_data(ln, 7, p);
1310 free(buf);
1311 }
1312
1313 fdisk_warn_alignment(cxt, start, i);
1314 fdisk_free_parttype(t);
1315 }
1316
1317 rc = fdisk_print_table(cxt, tb);
1318 tt_free_table(tb);
1319
1320 return rc;
1321 }
1322
1323 /*
1324 * Write partitions.
1325 * Returns 0 on success, or corresponding error otherwise.
1326 */
1327 static int gpt_write_partitions(struct fdisk_context *cxt,
1328 struct gpt_header *header, struct gpt_entry *ents)
1329 {
1330 off_t offset = le64_to_cpu(header->partition_entry_lba) * cxt->sector_size;
1331 uint32_t nparts = le32_to_cpu(header->npartition_entries);
1332 uint32_t totwrite = nparts * le32_to_cpu(header->sizeof_partition_entry);
1333 ssize_t rc;
1334
1335 if (offset != lseek(cxt->dev_fd, offset, SEEK_SET))
1336 goto fail;
1337
1338 rc = write(cxt->dev_fd, ents, totwrite);
1339 if (rc > 0 && totwrite == (uint32_t) rc)
1340 return 0;
1341 fail:
1342 return -errno;
1343 }
1344
1345 /*
1346 * Write a GPT header to a specified LBA
1347 * Returns 0 on success, or corresponding error otherwise.
1348 */
1349 static int gpt_write_header(struct fdisk_context *cxt,
1350 struct gpt_header *header, uint64_t lba)
1351 {
1352 off_t offset = lba * cxt->sector_size;
1353
1354 if (offset != lseek(cxt->dev_fd, offset, SEEK_SET))
1355 goto fail;
1356 if (cxt->sector_size ==
1357 (size_t) write(cxt->dev_fd, header, cxt->sector_size))
1358 return 0;
1359 fail:
1360 return -errno;
1361 }
1362
1363 /*
1364 * Write the protective MBR.
1365 * Returns 0 on success, or corresponding error otherwise.
1366 */
1367 static int gpt_write_pmbr(struct fdisk_context *cxt)
1368 {
1369 off_t offset;
1370 struct gpt_legacy_mbr *pmbr = NULL;
1371
1372 assert(cxt);
1373 assert(cxt->firstsector);
1374
1375 pmbr = (struct gpt_legacy_mbr *) cxt->firstsector;
1376
1377 /* zero out the legacy partitions */
1378 memset(pmbr->partition_record, 0, sizeof(pmbr->partition_record));
1379
1380 pmbr->signature = cpu_to_le16(MSDOS_MBR_SIGNATURE);
1381 pmbr->partition_record[0].os_type = EFI_PMBR_OSTYPE;
1382 pmbr->partition_record[0].start_sector = 1;
1383 pmbr->partition_record[0].end_head = 0xFE;
1384 pmbr->partition_record[0].end_sector = 0xFF;
1385 pmbr->partition_record[0].end_track = 0xFF;
1386 pmbr->partition_record[0].starting_lba = cpu_to_le32(1);
1387
1388 /*
1389 * Set size_in_lba to the size of the disk minus one. If the size of the disk
1390 * is too large to be represented by a 32bit LBA (2Tb), set it to 0xFFFFFFFF.
1391 */
1392 if (cxt->total_sectors - 1 > 0xFFFFFFFFULL)
1393 pmbr->partition_record[0].size_in_lba = cpu_to_le32(0xFFFFFFFF);
1394 else
1395 pmbr->partition_record[0].size_in_lba =
1396 cpu_to_le32(cxt->total_sectors - 1UL);
1397
1398 offset = GPT_PMBR_LBA * cxt->sector_size;
1399 if (offset != lseek(cxt->dev_fd, offset, SEEK_SET))
1400 goto fail;
1401
1402 /* pMBR covers the first sector (LBA) of the disk */
1403 if (write_all(cxt->dev_fd, pmbr, cxt->sector_size))
1404 goto fail;
1405 return 0;
1406 fail:
1407 return -errno;
1408 }
1409
1410 /*
1411 * Writes in-memory GPT and pMBR data to disk.
1412 * Returns 0 if successful write, otherwise, a corresponding error.
1413 * Any indication of error will abort the operation.
1414 */
1415 static int gpt_write_disklabel(struct fdisk_context *cxt)
1416 {
1417 struct fdisk_gpt_label *gpt;
1418
1419 assert(cxt);
1420 assert(cxt->label);
1421 assert(fdisk_is_disklabel(cxt, GPT));
1422
1423 gpt = self_label(cxt);
1424
1425 /* we do not want to mess up hybrid MBRs by creating a valid pmbr */
1426 if (valid_pmbr(cxt) == GPT_MBR_HYBRID)
1427 goto err0;
1428
1429 /* check that disk is big enough to handle the backup header */
1430 if (le64_to_cpu(gpt->pheader->alternative_lba) > cxt->total_sectors)
1431 goto err0;
1432
1433 /* check that the backup header is properly placed */
1434 if (le64_to_cpu(gpt->pheader->alternative_lba) < cxt->total_sectors - 1)
1435 /* TODO: correct this (with user authorization) and write */
1436 goto err0;
1437
1438 if (partition_check_overlaps(gpt->pheader, gpt->ents))
1439 goto err0;
1440
1441 /* recompute CRCs for both headers */
1442 gpt_recompute_crc(gpt->pheader, gpt->ents);
1443 gpt_recompute_crc(gpt->bheader, gpt->ents);
1444
1445 /*
1446 * UEFI requires writing in this specific order:
1447 * 1) backup partition tables
1448 * 2) backup GPT header
1449 * 3) primary partition tables
1450 * 4) primary GPT header
1451 * 5) protective MBR
1452 *
1453 * If any write fails, we abort the rest.
1454 */
1455 if (gpt_write_partitions(cxt, gpt->bheader, gpt->ents) != 0)
1456 goto err1;
1457 if (gpt_write_header(cxt, gpt->bheader,
1458 le64_to_cpu(gpt->pheader->alternative_lba)) != 0)
1459 goto err1;
1460 if (gpt_write_partitions(cxt, gpt->pheader, gpt->ents) != 0)
1461 goto err1;
1462 if (gpt_write_header(cxt, gpt->pheader, GPT_PRIMARY_PARTITION_TABLE_LBA) != 0)
1463 goto err1;
1464 if (gpt_write_pmbr(cxt) != 0)
1465 goto err1;
1466
1467 DBG(LABEL, dbgprint("GPT write success"));
1468 return 0;
1469 err0:
1470 DBG(LABEL, dbgprint("GPT write failed: incorrect input"));
1471 errno = EINVAL;
1472 return -EINVAL;
1473 err1:
1474 DBG(LABEL, dbgprint("GPT write failed: %m"));
1475 return -errno;
1476 }
1477
1478 /*
1479 * Verify data integrity and report any found problems for:
1480 * - primary and backup header validations
1481 * - paritition validations
1482 */
1483 static int gpt_verify_disklabel(struct fdisk_context *cxt)
1484 {
1485 int nerror = 0;
1486 unsigned int ptnum;
1487 struct fdisk_gpt_label *gpt;
1488
1489 assert(cxt);
1490 assert(cxt->label);
1491 assert(fdisk_is_disklabel(cxt, GPT));
1492
1493 gpt = self_label(cxt);
1494
1495 if (!gpt || !gpt->bheader) {
1496 nerror++;
1497 fdisk_warnx(cxt, _("Disk does not contain a valid backup header."));
1498 }
1499
1500 if (!gpt_check_header_crc(gpt->pheader, gpt->ents)) {
1501 nerror++;
1502 fdisk_warnx(cxt, _("Invalid primary header CRC checksum."));
1503 }
1504 if (gpt->bheader && !gpt_check_header_crc(gpt->bheader, gpt->ents)) {
1505 nerror++;
1506 fdisk_warnx(cxt, _("Invalid backup header CRC checksum."));
1507 }
1508
1509 if (!gpt_check_entryarr_crc(gpt->pheader, gpt->ents)) {
1510 nerror++;
1511 fdisk_warnx(cxt, _("Invalid partition entry checksum."));
1512 }
1513
1514 if (!gpt_check_lba_sanity(cxt, gpt->pheader)) {
1515 nerror++;
1516 fdisk_warnx(cxt, _("Invalid primary header LBA sanity checks."));
1517 }
1518 if (gpt->bheader && !gpt_check_lba_sanity(cxt, gpt->bheader)) {
1519 nerror++;
1520 fdisk_warnx(cxt, _("Invalid backup header LBA sanity checks."));
1521 }
1522
1523 if (le64_to_cpu(gpt->pheader->my_lba) != GPT_PRIMARY_PARTITION_TABLE_LBA) {
1524 nerror++;
1525 fdisk_warnx(cxt, _("MyLBA mismatch with real position at primary header."));
1526 }
1527 if (gpt->bheader && le64_to_cpu(gpt->bheader->my_lba) != last_lba(cxt)) {
1528 nerror++;
1529 fdisk_warnx(cxt, _("MyLBA mismatch with real position at backup header."));
1530
1531 }
1532 if (le64_to_cpu(gpt->pheader->alternative_lba) >= cxt->total_sectors) {
1533 nerror++;
1534 fdisk_warnx(cxt, _("Disk is too small to hold all data."));
1535 }
1536
1537 /*
1538 * if the GPT is the primary table, check the alternateLBA
1539 * to see if it is a valid GPT
1540 */
1541 if (gpt->bheader && (le64_to_cpu(gpt->pheader->my_lba) !=
1542 le64_to_cpu(gpt->bheader->alternative_lba))) {
1543 nerror++;
1544 fdisk_warnx(cxt, _("Primary and backup header mismatch."));
1545 }
1546
1547 ptnum = partition_check_overlaps(gpt->pheader, gpt->ents);
1548 if (ptnum) {
1549 nerror++;
1550 fdisk_warnx(cxt, _("Partition %u overlaps with partition %u."),
1551 ptnum, ptnum+1);
1552 }
1553
1554 ptnum = partition_check_too_big(gpt->pheader, gpt->ents, cxt->total_sectors);
1555 if (ptnum) {
1556 nerror++;
1557 fdisk_warnx(cxt, _("Partition %u is too big for the disk."),
1558 ptnum);
1559 }
1560
1561 ptnum = partition_start_after_end(gpt->pheader, gpt->ents);
1562 if (ptnum) {
1563 nerror++;
1564 fdisk_warnx(cxt, _("Partition %u ends before it starts."),
1565 ptnum);
1566 }
1567
1568 if (!nerror) { /* yay :-) */
1569 uint32_t nsegments = 0;
1570 uint64_t free_sectors = 0, largest_segment = 0;
1571
1572 fdisk_info(cxt, _("No errors detected."));
1573 fdisk_info(cxt, _("Header version: %s"), gpt_get_header_revstr(gpt->pheader));
1574 fdisk_info(cxt, _("Using %u out of %d partitions."),
1575 partitions_in_use(gpt->pheader, gpt->ents),
1576 le32_to_cpu(gpt->pheader->npartition_entries));
1577
1578 free_sectors = get_free_sectors(cxt, gpt->pheader, gpt->ents,
1579 &nsegments, &largest_segment);
1580 fdisk_info(cxt,
1581 P_("A total of %ju free sectors is available in %u segment.",
1582 "A total of %ju free sectors is available in %u segments "
1583 "(the largest is %ju).", nsegments),
1584 free_sectors, nsegments, largest_segment);
1585 } else
1586 fdisk_warnx(cxt,
1587 P_("%d error detected.", "%d errors detected.", nerror),
1588 nerror);
1589
1590 return 0;
1591 }
1592
1593 /* Delete a single GPT partition, specified by partnum. */
1594 static int gpt_delete_partition(struct fdisk_context *cxt,
1595 size_t partnum)
1596 {
1597 struct fdisk_gpt_label *gpt;
1598
1599 assert(cxt);
1600 assert(cxt->label);
1601 assert(fdisk_is_disklabel(cxt, GPT));
1602
1603 gpt = self_label(cxt);
1604
1605 if (partnum >= cxt->label->nparts_max
1606 || partition_unused(&gpt->ents[partnum]))
1607 return -EINVAL;
1608
1609 /* hasta la vista, baby! */
1610 memset(&gpt->ents[partnum], 0, sizeof(struct gpt_entry));
1611 if (!partition_unused(&gpt->ents[partnum]))
1612 return -EINVAL;
1613 else {
1614 gpt_recompute_crc(gpt->pheader, gpt->ents);
1615 gpt_recompute_crc(gpt->bheader, gpt->ents);
1616 cxt->label->nparts_cur--;
1617 fdisk_label_set_changed(cxt->label, 1);
1618 }
1619
1620 return 0;
1621 }
1622
1623 static void gpt_entry_set_type(struct gpt_entry *e, struct gpt_guid *uuid)
1624 {
1625 e->type = *uuid;
1626 DBG(LABEL, dbgprint_uuid("new type", &(e->type)));
1627 }
1628
1629 /*
1630 * Create a new GPT partition entry, specified by partnum, and with a range
1631 * of fsect to lsenct sectors, of type t.
1632 * Returns 0 on success, or negative upon failure.
1633 */
1634 static int gpt_create_new_partition(struct fdisk_context *cxt,
1635 size_t partnum, uint64_t fsect, uint64_t lsect,
1636 struct gpt_guid *type,
1637 struct gpt_entry *entries)
1638 {
1639 struct gpt_entry *e = NULL;
1640 struct fdisk_gpt_label *gpt;
1641
1642 assert(cxt);
1643 assert(cxt->label);
1644 assert(fdisk_is_disklabel(cxt, GPT));
1645
1646 gpt = self_label(cxt);
1647
1648 if (fsect > lsect || partnum >= cxt->label->nparts_max)
1649 return -EINVAL;
1650
1651 e = calloc(1, sizeof(*e));
1652 if (!e)
1653 return -ENOMEM;
1654 e->lba_end = cpu_to_le64(lsect);
1655 e->lba_start = cpu_to_le64(fsect);
1656
1657 gpt_entry_set_type(e, type);
1658
1659 /*
1660 * Any time a new partition entry is created a new GUID must be
1661 * generated for that partition, and every partition is guaranteed
1662 * to have a unique GUID.
1663 */
1664 uuid_generate_random((unsigned char *) &e->partition_guid);
1665 swap_efi_guid(&e->partition_guid);
1666
1667 memcpy(&entries[partnum], e, sizeof(*e));
1668
1669 gpt_recompute_crc(gpt->pheader, entries);
1670 gpt_recompute_crc(gpt->bheader, entries);
1671
1672 free(e);
1673 return 0;
1674 }
1675
1676 /* Performs logical checks to add a new partition entry */
1677 static int gpt_add_partition(
1678 struct fdisk_context *cxt,
1679 size_t partnum,
1680 struct fdisk_parttype *t)
1681 {
1682 uint64_t user_f, user_l; /* user input ranges for first and last sectors */
1683 uint64_t disk_f, disk_l; /* first and last available sector ranges on device*/
1684 uint64_t dflt_f, dflt_l; /* largest segment (default) */
1685 struct gpt_guid typeid;
1686 struct fdisk_gpt_label *gpt;
1687 struct gpt_header *pheader;
1688 struct gpt_entry *ents;
1689 struct fdisk_ask *ask = NULL;
1690 int rc;
1691
1692 assert(cxt);
1693 assert(cxt->label);
1694 assert(fdisk_is_disklabel(cxt, GPT));
1695
1696 gpt = self_label(cxt);
1697
1698 if (partnum >= cxt->label->nparts_max)
1699 return -EINVAL;
1700
1701 pheader = gpt->pheader;
1702 ents = gpt->ents;
1703
1704 if (!partition_unused(&ents[partnum])) {
1705 fdisk_warnx(cxt, _("Partition %zu is already defined. "
1706 "Delete it before re-adding it."), partnum +1);
1707 return -EINVAL;
1708 }
1709 if (le32_to_cpu(pheader->npartition_entries) ==
1710 partitions_in_use(pheader, ents)) {
1711 fdisk_warnx(cxt, _("All partitions are already in use."));
1712 return -EINVAL;
1713 }
1714
1715 if (!get_free_sectors(cxt, pheader, ents, NULL, NULL)) {
1716 fdisk_warnx(cxt, _("No free sectors available."));
1717 return -ENOSPC;
1718 }
1719
1720 disk_f = find_first_available(pheader, ents, 0);
1721 disk_l = find_last_free_sector(pheader, ents);
1722
1723 /* the default is the largest free space */
1724 dflt_f = find_first_in_largest(pheader, ents);
1725 dflt_l = find_last_free(pheader, ents, dflt_f);
1726
1727 /* align the default in range <dflt_f,dflt_l>*/
1728 dflt_f = fdisk_align_lba_in_range(cxt, dflt_f, dflt_f, dflt_l);
1729
1730 string_to_guid(t && t->typestr ? t->typestr : GPT_DEFAULT_ENTRY_TYPE, &typeid);
1731
1732 /* get user input for first and last sectors of the new partition */
1733 for (;;) {
1734 if (!ask)
1735 ask = fdisk_new_ask();
1736 else
1737 fdisk_reset_ask(ask);
1738
1739 /* First sector */
1740 fdisk_ask_set_query(ask, _("First sector"));
1741 fdisk_ask_set_type(ask, FDISK_ASKTYPE_NUMBER);
1742 fdisk_ask_number_set_low(ask, disk_f); /* minimal */
1743 fdisk_ask_number_set_default(ask, dflt_f); /* default */
1744 fdisk_ask_number_set_high(ask, disk_l); /* maximal */
1745
1746 rc = fdisk_do_ask(cxt, ask);
1747 if (rc)
1748 goto done;
1749
1750 user_f = fdisk_ask_number_get_result(ask);
1751 if (user_f != find_first_available(pheader, ents, user_f)) {
1752 fdisk_warnx(cxt, _("Sector %ju already used."), user_f);
1753 continue;
1754 }
1755
1756 fdisk_reset_ask(ask);
1757
1758 /* Last sector */
1759 dflt_l = find_last_free(pheader, ents, user_f);
1760
1761 fdisk_ask_set_query(ask, _("Last sector, +sectors or +size{K,M,G,T,P}"));
1762 fdisk_ask_set_type(ask, FDISK_ASKTYPE_OFFSET);
1763 fdisk_ask_number_set_low(ask, user_f); /* minimal */
1764 fdisk_ask_number_set_default(ask, dflt_l); /* default */
1765 fdisk_ask_number_set_high(ask, dflt_l); /* maximal */
1766 fdisk_ask_number_set_base(ask, user_f); /* base for relative input */
1767 fdisk_ask_number_set_unit(ask, cxt->sector_size);
1768
1769 rc = fdisk_do_ask(cxt, ask);
1770 if (rc)
1771 goto done;
1772
1773 user_l = fdisk_ask_number_get_result(ask);
1774 if (fdisk_ask_number_is_relative(ask))
1775 user_l = fdisk_align_lba_in_range(cxt, user_l, user_f, dflt_l) - 1;
1776 if (user_l > user_f && user_l <= disk_l)
1777 break;
1778 }
1779
1780 if (gpt_create_new_partition(cxt, partnum,
1781 user_f, user_l, &typeid, ents) != 0)
1782 fdisk_warnx(cxt, _("Could not create partition %ju"), partnum + 1);
1783 else {
1784 struct fdisk_parttype *t;
1785
1786 cxt->label->nparts_cur++;
1787 fdisk_label_set_changed(cxt->label, 1);
1788
1789 t = gpt_get_partition_type(cxt, partnum);
1790 fdisk_info_new_partition(cxt, partnum + 1, user_f, user_l, t);
1791 fdisk_free_parttype(t);
1792 }
1793
1794 rc = 0;
1795 done:
1796 fdisk_free_ask(ask);
1797 return rc;
1798 }
1799
1800 /*
1801 * Create a new GPT disklabel - destroys any previous data.
1802 */
1803 static int gpt_create_disklabel(struct fdisk_context *cxt)
1804 {
1805 int rc = 0;
1806 ssize_t esz = 0;
1807 char str[37];
1808 struct fdisk_gpt_label *gpt;
1809
1810 assert(cxt);
1811 assert(cxt->label);
1812 assert(fdisk_is_disklabel(cxt, GPT));
1813
1814 gpt = self_label(cxt);
1815
1816 /* label private stuff has to be empty, see gpt_deinit() */
1817 assert(gpt->pheader == NULL);
1818 assert(gpt->bheader == NULL);
1819
1820 /*
1821 * When no header, entries or pmbr is set, we're probably
1822 * dealing with a new, empty disk - so always allocate memory
1823 * to deal with the data structures whatever the case is.
1824 */
1825 rc = gpt_mknew_pmbr(cxt);
1826 if (rc < 0)
1827 goto done;
1828
1829 /* primary */
1830 gpt->pheader = calloc(1, sizeof(*gpt->pheader));
1831 if (!gpt->pheader) {
1832 rc = -ENOMEM;
1833 goto done;
1834 }
1835 rc = gpt_mknew_header(cxt, gpt->pheader, GPT_PRIMARY_PARTITION_TABLE_LBA);
1836 if (rc < 0)
1837 goto done;
1838
1839 /* backup ("copy" primary) */
1840 gpt->bheader = calloc(1, sizeof(*gpt->bheader));
1841 if (!gpt->bheader) {
1842 rc = -ENOMEM;
1843 goto done;
1844 }
1845 rc = gpt_mknew_header_from_bkp(cxt, gpt->bheader,
1846 last_lba(cxt), gpt->pheader);
1847 if (rc < 0)
1848 goto done;
1849
1850 esz = le32_to_cpu(gpt->pheader->npartition_entries) *
1851 le32_to_cpu(gpt->pheader->sizeof_partition_entry);
1852 gpt->ents = calloc(1, esz);
1853 if (!gpt->ents) {
1854 rc = -ENOMEM;
1855 goto done;
1856 }
1857 gpt_recompute_crc(gpt->pheader, gpt->ents);
1858 gpt_recompute_crc(gpt->bheader, gpt->ents);
1859
1860 cxt->label->nparts_max = le32_to_cpu(gpt->pheader->npartition_entries);
1861 cxt->label->nparts_cur = 0;
1862
1863 guid_to_string(&gpt->pheader->disk_guid, str);
1864 fdisk_label_set_changed(cxt->label, 1);
1865 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
1866 _("Created a new GPT disklabel (GUID: %s)."), str);
1867 done:
1868 return rc;
1869 }
1870
1871 static int gpt_get_disklabel_id(struct fdisk_context *cxt, char **id)
1872 {
1873 struct fdisk_gpt_label *gpt;
1874 char str[37];
1875
1876 assert(cxt);
1877 assert(id);
1878 assert(cxt->label);
1879 assert(fdisk_is_disklabel(cxt, GPT));
1880
1881 gpt = self_label(cxt);
1882 guid_to_string(&gpt->pheader->disk_guid, str);
1883
1884 *id = strdup(str);
1885 if (!*id)
1886 return -ENOMEM;
1887 return 0;
1888 }
1889
1890 static int gpt_set_disklabel_id(struct fdisk_context *cxt)
1891 {
1892 struct fdisk_gpt_label *gpt;
1893 struct gpt_guid uuid;
1894 char *str, *old, *new;
1895 int rc;
1896
1897 assert(cxt);
1898 assert(cxt->label);
1899 assert(fdisk_is_disklabel(cxt, GPT));
1900
1901 gpt = self_label(cxt);
1902 if (fdisk_ask_string(cxt,
1903 _("Enter new disk UUID (in 8-4-4-4-12 format)"), &str))
1904 return -EINVAL;
1905
1906 rc = string_to_guid(str, &uuid);
1907 free(str);
1908
1909 if (rc) {
1910 fdisk_warnx(cxt, _("Failed to parse your UUID."));
1911 return rc;
1912 }
1913
1914 gpt_get_disklabel_id(cxt, &old);
1915
1916 gpt->pheader->disk_guid = uuid;
1917 gpt->bheader->disk_guid = uuid;
1918
1919 gpt_recompute_crc(gpt->pheader, gpt->ents);
1920 gpt_recompute_crc(gpt->bheader, gpt->ents);
1921
1922 gpt_get_disklabel_id(cxt, &new);
1923
1924 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
1925 _("Disk identifier changed from %s to %s."), old, new);
1926
1927 free(old);
1928 free(new);
1929 fdisk_label_set_changed(cxt->label, 1);
1930 return 0;
1931 }
1932
1933
1934 static struct fdisk_parttype *gpt_get_partition_type(
1935 struct fdisk_context *cxt,
1936 size_t i)
1937 {
1938 struct fdisk_parttype *t;
1939 char str[37];
1940 struct fdisk_gpt_label *gpt;
1941
1942 assert(cxt);
1943 assert(cxt->label);
1944 assert(fdisk_is_disklabel(cxt, GPT));
1945
1946 gpt = self_label(cxt);
1947
1948 if ((uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries))
1949 return NULL;
1950
1951 guid_to_string(&gpt->ents[i].type, str);
1952 t = fdisk_get_parttype_from_string(cxt, str);
1953 if (!t)
1954 t = fdisk_new_unknown_parttype(0, str);
1955
1956 return t;
1957 }
1958
1959
1960 static int gpt_set_partition_type(
1961 struct fdisk_context *cxt,
1962 size_t i,
1963 struct fdisk_parttype *t)
1964 {
1965 struct gpt_guid uuid;
1966 struct fdisk_gpt_label *gpt;
1967
1968 assert(cxt);
1969 assert(cxt->label);
1970 assert(fdisk_is_disklabel(cxt, GPT));
1971
1972 gpt = self_label(cxt);
1973 if ((uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries)
1974 || !t || !t->typestr || string_to_guid(t->typestr, &uuid) != 0)
1975 return -EINVAL;
1976
1977 gpt_entry_set_type(&gpt->ents[i], &uuid);
1978 gpt_recompute_crc(gpt->pheader, gpt->ents);
1979 gpt_recompute_crc(gpt->bheader, gpt->ents);
1980
1981 fdisk_label_set_changed(cxt->label, 1);
1982 return 0;
1983 }
1984
1985 static int gpt_get_partition_status(
1986 struct fdisk_context *cxt,
1987 size_t i,
1988 int *status)
1989 {
1990 struct fdisk_gpt_label *gpt;
1991 struct gpt_entry *e;
1992
1993 assert(cxt);
1994 assert(cxt->label);
1995 assert(fdisk_is_disklabel(cxt, GPT));
1996
1997 gpt = self_label(cxt);
1998
1999 if (!status || (uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries))
2000 return -EINVAL;
2001
2002 e = &gpt->ents[i];
2003 *status = FDISK_PARTSTAT_NONE;
2004
2005 if (!partition_unused(e) || gpt_partition_start(e))
2006 *status = FDISK_PARTSTAT_USED;
2007
2008 return 0;
2009 }
2010
2011 int fdisk_gpt_partition_set_uuid(struct fdisk_context *cxt, size_t i)
2012 {
2013 struct fdisk_gpt_label *gpt;
2014 struct gpt_entry *e;
2015 struct gpt_guid uuid;
2016 char *str, new_u[37], old_u[37];
2017 int rc;
2018
2019 assert(cxt);
2020 assert(cxt->label);
2021 assert(fdisk_is_disklabel(cxt, GPT));
2022
2023 DBG(LABEL, dbgprint("UUID change requested partno=%zu", i));
2024
2025 gpt = self_label(cxt);
2026
2027 if ((uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries))
2028 return -EINVAL;
2029
2030 if (fdisk_ask_string(cxt,
2031 _("New UUID (in 8-4-4-4-12 format)"), &str))
2032 return -EINVAL;
2033
2034 rc = string_to_guid(str, &uuid);
2035 free(str);
2036
2037 if (rc) {
2038 fdisk_warnx(cxt, _("Failed to parse your UUID."));
2039 return rc;
2040 }
2041
2042 e = &gpt->ents[i];
2043
2044 guid_to_string(&e->partition_guid, old_u);
2045 guid_to_string(&uuid, new_u);
2046
2047 e->partition_guid = uuid;
2048 gpt_recompute_crc(gpt->pheader, gpt->ents);
2049 gpt_recompute_crc(gpt->bheader, gpt->ents);
2050 fdisk_label_set_changed(cxt->label, 1);
2051
2052 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2053 _("Partition UUID changed from %s to %s."),
2054 old_u, new_u);
2055 return 0;
2056 }
2057
2058 int fdisk_gpt_partition_set_name(struct fdisk_context *cxt, size_t i)
2059 {
2060 struct fdisk_gpt_label *gpt;
2061 struct gpt_entry *e;
2062 char *str, *old, name[GPT_PART_NAME_LEN] = { 0 };
2063 size_t sz;
2064
2065 assert(cxt);
2066 assert(cxt->label);
2067 assert(fdisk_is_disklabel(cxt, GPT));
2068
2069 DBG(LABEL, dbgprint("NAME change requested partno=%zu", i));
2070
2071 gpt = self_label(cxt);
2072
2073 if ((uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries))
2074 return -EINVAL;
2075
2076 if (fdisk_ask_string(cxt, _("New name"), &str))
2077 return -EINVAL;
2078
2079 e = &gpt->ents[i];
2080 old = encode_to_utf8((unsigned char *)e->name, sizeof(e->name));
2081
2082 sz = strlen(str);
2083 if (sz) {
2084 if (sz > GPT_PART_NAME_LEN)
2085 sz = GPT_PART_NAME_LEN;
2086 memcpy(name, str, sz);
2087 }
2088
2089 for (i = 0; i < GPT_PART_NAME_LEN; i++)
2090 e->name[i] = cpu_to_le16((uint16_t) name[i]);
2091
2092 gpt_recompute_crc(gpt->pheader, gpt->ents);
2093 gpt_recompute_crc(gpt->bheader, gpt->ents);
2094
2095 fdisk_label_set_changed(cxt->label, 1);
2096
2097 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2098 _("Partition name changed from '%s' to '%.*s'."),
2099 old, (int) GPT_PART_NAME_LEN, str);
2100 free(str);
2101 free(old);
2102
2103 return 0;
2104 }
2105
2106 static int gpt_toggle_partition_flag(
2107 struct fdisk_context *cxt,
2108 size_t i,
2109 unsigned long flag)
2110 {
2111 struct fdisk_gpt_label *gpt;
2112 struct gpt_entry *e;
2113
2114 assert(cxt);
2115 assert(cxt->label);
2116 assert(fdisk_is_disklabel(cxt, GPT));
2117
2118 DBG(LABEL, dbgprint("GPT entry attribute change requested partno=%zu", i));
2119
2120 gpt = self_label(cxt);
2121
2122 if ((uint32_t) i >= le32_to_cpu(gpt->pheader->npartition_entries))
2123 return -EINVAL;
2124
2125 e = &gpt->ents[i];
2126
2127 switch (flag) {
2128 case GPT_FLAG_REQUIRED:
2129 e->attr.required_to_function = !e->attr.required_to_function;
2130 fdisk_label_set_changed(cxt->label, 1);
2131 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2132 e->attr.required_to_function ?
2133 _("The RequiredPartiton flag on partition %zu is enabled now.") :
2134 _("The RequiredPartiton flag on partition %zu is disabled now."),
2135 i + 1);
2136 break;
2137 case GPT_FLAG_NOBLOCK:
2138 e->attr.no_blockio_protocol = !e->attr.no_blockio_protocol;
2139 fdisk_label_set_changed(cxt->label, 1);
2140 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2141 e->attr.no_blockio_protocol ?
2142 _("The NoBlockIOProtocol flag on partition %zu is enabled now.") :
2143 _("The NoBlockIOProtocol flag on partition %zu is disabled now."),
2144 i + 1);
2145 break;
2146 case GPT_FLAG_LEGACYBOOT:
2147 e->attr.legacy_bios_bootable = !e->attr.legacy_bios_bootable;
2148 fdisk_label_set_changed(cxt->label, 1);
2149 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2150 e->attr.legacy_bios_bootable ?
2151 _("The LegacyBIOSBootable flag on partition %zu is enabled now.") :
2152 _("The LegacyBIOSBootable flag on partition %zu is disabled now."),
2153 i + 1);
2154 break;
2155 case GPT_FLAG_GUIDSPECIFIC:
2156 {
2157 char *attrs = (char *) &e->attr;
2158 uint64_t bit = 0;
2159 int rc = fdisk_ask_number(cxt, 48, 48, 63,
2160 _("Enter GUID specific bit"),
2161 &bit);
2162 if (rc)
2163 return rc;
2164 if (!isset(attrs, bit))
2165 setbit(attrs, bit);
2166 else
2167 clrbit(attrs, bit);
2168
2169 fdisk_label_set_changed(cxt->label, 1);
2170 fdisk_sinfo(cxt, FDISK_INFO_SUCCESS,
2171 isset(attrs, bit) ?
2172 _("The GUID specific bit %ju on partition %zu is enabled now.") :
2173 _("The GUID specific bit %ju on partition %zu is disabled now."),
2174 bit, i + 1);
2175 break;
2176 }
2177 default:
2178 return 1;
2179 }
2180
2181 gpt_recompute_crc(gpt->pheader, gpt->ents);
2182 gpt_recompute_crc(gpt->bheader, gpt->ents);
2183
2184 return 0;
2185 }
2186
2187 /*
2188 * Deinitialize fdisk-specific variables
2189 */
2190 static void gpt_deinit(struct fdisk_label *lb)
2191 {
2192 struct fdisk_gpt_label *gpt = (struct fdisk_gpt_label *) lb;
2193
2194 if (!gpt)
2195 return;
2196
2197 free(gpt->ents);
2198 free(gpt->pheader);
2199 free(gpt->bheader);
2200
2201 gpt->ents = NULL;
2202 gpt->pheader = NULL;
2203 gpt->bheader = NULL;
2204 }
2205
2206 static const struct fdisk_label_operations gpt_operations =
2207 {
2208 .probe = gpt_probe_label,
2209 .write = gpt_write_disklabel,
2210 .verify = gpt_verify_disklabel,
2211 .create = gpt_create_disklabel,
2212 .list = gpt_list_disklabel,
2213 .locate = gpt_locate_disklabel,
2214 .get_id = gpt_get_disklabel_id,
2215 .set_id = gpt_set_disklabel_id,
2216
2217 .part_add = gpt_add_partition,
2218 .part_delete = gpt_delete_partition,
2219 .part_get_type = gpt_get_partition_type,
2220 .part_set_type = gpt_set_partition_type,
2221 .part_toggle_flag = gpt_toggle_partition_flag,
2222
2223 .part_get_status = gpt_get_partition_status,
2224
2225 .deinit = gpt_deinit
2226 };
2227
2228 /*
2229 * allocates GPT in-memory stuff
2230 */
2231 struct fdisk_label *fdisk_new_gpt_label(struct fdisk_context *cxt)
2232 {
2233 struct fdisk_label *lb;
2234 struct fdisk_gpt_label *gpt;
2235
2236 assert(cxt);
2237
2238 gpt = calloc(1, sizeof(*gpt));
2239 if (!gpt)
2240 return NULL;
2241
2242 /* initialize generic part of the driver */
2243 lb = (struct fdisk_label *) gpt;
2244 lb->name = "gpt";
2245 lb->id = FDISK_DISKLABEL_GPT;
2246 lb->op = &gpt_operations;
2247 lb->parttypes = gpt_parttypes;
2248 lb->nparttypes = ARRAY_SIZE(gpt_parttypes);
2249
2250 return lb;
2251 }