]> git.pld-linux.org Git - packages/util-linux.git/blame - util-linux-fdisk-gpt.patch
- uniformized configs to use system-auth where possible
[packages/util-linux.git] / util-linux-fdisk-gpt.patch
CommitLineData
5545a732
JR
1- sfdisk warning for large partitions, gpt
2
3--- util-linux-2.13-pre6/fdisk/fdisk.c.gpt 2005-11-24 15:30:36.000000000 +0100
4+++ util-linux-2.13-pre6/fdisk/fdisk.c 2005-11-24 15:30:36.000000000 +0100
5@@ -34,6 +34,8 @@
6 #include <linux/blkpg.h>
7 #endif
8
9+#include "gpt.h"
10+
11 static void delete_partition(int i);
12
13 #define hex_val(c) ({ \
14@@ -2400,6 +2402,14 @@
15 }
16
17 static void
18+gpt_warning(char *dev)
19+{
20+ if (gpt_probe_signature_devname(dev))
21+ fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
22+ "The util fdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
23+}
24+
25+static void
26 try(char *device, int user_specified) {
27 int gb;
28
29@@ -2409,6 +2419,7 @@
30 if (!user_specified)
31 if (is_ide_cdrom_or_tape(device))
32 return;
33+ gpt_warning(device);
34 if ((fd = open(disk_device, type_open)) >= 0) {
35 gb = get_boot(try_only);
36 if (gb > 0) { /* I/O error */
37@@ -2470,6 +2481,8 @@
38 printf(_("%c: unknown command\n"), c);
39 }
40
41+
42+
43 int
44 main(int argc, char **argv) {
45 int j, c;
46@@ -2574,6 +2587,7 @@
47
48 for (j = optind; j < argc; j++) {
49 disk_device = argv[j];
50+ gpt_warning(disk_device);
51 if ((fd = open(disk_device, type_open)) < 0)
52 fatal(unable_to_open);
53 if (disksize(fd, &size))
54@@ -2594,6 +2608,7 @@
55 else
56 fatal(usage2);
57
58+ gpt_warning(disk_device);
59 get_boot(fdisk);
60
61 if (osf_label) {
62--- /dev/null 2005-11-14 15:52:26.044616250 +0100
63+++ util-linux-2.13-pre6/fdisk/gpt.h 2005-11-24 15:30:36.000000000 +0100
64@@ -0,0 +1,9 @@
65+
66+#ifndef __GPT_H__
67+#define __GPT_H__
68+
69+extern int gpt_probe_signature_fd(int fd);
70+extern int gpt_probe_signature_devname(char *devname);
71+
72+#endif /* __GPT_H__ */
73+
74--- util-linux-2.13-pre6/fdisk/Makefile.am.gpt 2005-10-16 14:12:52.000000000 +0200
75+++ util-linux-2.13-pre6/fdisk/Makefile.am 2005-11-24 15:31:42.000000000 +0100
76@@ -5,13 +5,13 @@
77 sbin_PROGRAMS = fdisk
78 man_MANS = fdisk.8
79 fdisk_SOURCES = fdisk.c disksize.c fdiskbsdlabel.c fdisksgilabel.c \
80- fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c
81+ fdisksunlabel.c fdiskaixlabel.c i386_sys_types.c partname.c gpt.c
82
83 if !SPARC
84
85 sbin_PROGRAMS += sfdisk
86 man_MANS += sfdisk.8
87-sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c
88+sfdisk_SOURCES = sfdisk.c disksize.c i386_sys_types.c partname.c gpt.c
89
90 if USE_SLANG
91 sbin_PROGRAMS += cfdisk
92--- util-linux-2.13-pre6/fdisk/fdisk.8.gpt 2005-11-24 15:30:36.000000000 +0100
93+++ util-linux-2.13-pre6/fdisk/fdisk.8 2005-11-24 15:30:36.000000000 +0100
94@@ -42,6 +42,11 @@
95 partition tables.
96 It understands DOS type partition tables and BSD or SUN type disklabels.
97
98+.B fdisk
99+doesn't understand GUID Partition Table (GPT) and
100+it is not designed for large partitions. In particular case use more advanced GNU
101+.B parted(8).
102+
103 The
104 .I device
105 is usually one of the following:
106--- util-linux-2.13-pre6/fdisk/sfdisk.8.gpt 2004-12-31 17:28:30.000000000 +0100
107+++ util-linux-2.13-pre6/fdisk/sfdisk.8 2005-11-24 15:30:36.000000000 +0100
108@@ -18,6 +18,11 @@
109 on a device, check the partitions on a device, and - very dangerous -
110 repartition a device.
111
112+.B sfdisk
113+doesn't understand GUID Partition Table (GPT) and
114+it is not designed for large partitions. In particular case use more advanced GNU
115+.B parted(8).
116+
117 .SS "List Sizes"
118 .BI "sfdisk \-s " partition
119 gives the size of
120--- /dev/null 2005-11-14 15:52:26.044616250 +0100
121+++ util-linux-2.13-pre6/fdisk/gpt.c 2005-11-24 15:30:36.000000000 +0100
122@@ -0,0 +1,287 @@
123+/*
124+ GPT (GUID Partition Table) signature detection. Based on libparted and
125+ util-linux/partx.
126+
127+ Warning: this code doesn't do all GPT checks (CRC32, Protective MBR, ..). It's
128+ really GPT signature detection only.
129+
130+ -- Karel Zak <kzak@redhat.com> (Jun-2-2005)
131+
132+*/
133+
134+#include <stdio.h>
135+#include <string.h>
136+#include <stdlib.h>
137+#include <inttypes.h>
138+#include <sys/stat.h>
139+#include <sys/ioctl.h>
140+#include <sys/utsname.h>
141+#include <sys/types.h>
142+#include <fcntl.h>
143+#include <unistd.h>
144+#include <errno.h>
145+#include <linux/fs.h>
146+
147+#include "gpt.h"
148+
149+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
150+#define SECTOR_SIZE 512 /* default */
151+
152+#define _GET_BYTE(x, n) ( ((x) >> (8 * (n))) & 0xff )
153+
154+#define _PED_SWAP64(x) ( (_GET_BYTE(x, 0) << 56) \
155+ + (_GET_BYTE(x, 1) << 48) \
156+ + (_GET_BYTE(x, 2) << 40) \
157+ + (_GET_BYTE(x, 3) << 32) \
158+ + (_GET_BYTE(x, 4) << 24) \
159+ + (_GET_BYTE(x, 5) << 16) \
160+ + (_GET_BYTE(x, 6) << 8) \
161+ + (_GET_BYTE(x, 7) << 0) )
162+
163+#define PED_SWAP64(x) ((uint64_t) _PED_SWAP64( (uint64_t) (x) ))
164+
165+#if __BYTE_ORDER == __LITTLE_ENDIAN
166+# define CPU_TO_LE64(x) (x)
167+#else
168+# define CPU_TO_LE64(x) PED_SWAP64(x)
169+#endif
170+
171+#define BLKSSZGET _IO(0x12,104) /* get block device sector size */
172+#define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */
173+#define BLKGETSIZE _IO(0x12,96) /* return device size */
174+#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
175+
176+#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
177+#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
178+
179+typedef struct {
180+ uint32_t time_low;
181+ uint16_t time_mid;
182+ uint16_t time_hi_and_version;
183+ uint8_t clock_seq_hi_and_reserved;
184+ uint8_t clock_seq_low;
185+ uint8_t node[6];
186+} /* __attribute__ ((packed)) */ efi_guid_t;
187+/* commented out "__attribute__ ((packed))" to work around gcc bug (fixed
188+ * in gcc3.1): __attribute__ ((packed)) breaks addressing on initialized
189+ * data. It turns out we don't need it in this case, so it doesn't break
190+ * anything :)
191+ */
192+
193+typedef struct _GuidPartitionTableHeader_t {
194+ uint64_t Signature;
195+ uint32_t Revision;
196+ uint32_t HeaderSize;
197+ uint32_t HeaderCRC32;
198+ uint32_t Reserved1;
199+ uint64_t MyLBA;
200+ uint64_t AlternateLBA;
201+ uint64_t FirstUsableLBA;
202+ uint64_t LastUsableLBA;
203+ efi_guid_t DiskGUID;
204+ uint64_t PartitionEntryLBA;
205+ uint32_t NumberOfPartitionEntries;
206+ uint32_t SizeOfPartitionEntry;
207+ uint32_t PartitionEntryArrayCRC32;
208+ uint8_t Reserved2[512 - 92];
209+} __attribute__ ((packed)) GuidPartitionTableHeader_t;
210+
211+struct blkdev_ioctl_param {
212+ unsigned int block;
213+ size_t content_length;
214+ char * block_contents;
215+};
216+
217+static int
218+_get_linux_version (void)
219+{
220+ static int kver = -1;
221+ struct utsname uts;
222+ int major;
223+ int minor;
224+ int teeny;
225+
226+ if (kver != -1)
227+ return kver;
228+ if (uname (&uts))
229+ return kver = 0;
230+ if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) != 3)
231+ return kver = 0;
232+ return kver = KERNEL_VERSION (major, minor, teeny);
233+}
234+
235+static unsigned int
236+_get_sector_size (int fd)
237+{
238+ unsigned int sector_size;
239+
240+ if (_get_linux_version() < KERNEL_VERSION (2,3,0))
241+ return SECTOR_SIZE;
242+ if (ioctl (fd, BLKSSZGET, &sector_size))
243+ return SECTOR_SIZE;
244+ return sector_size;
245+}
246+
247+static uint64_t
248+_get_num_sectors(int fd)
249+{
250+ int version = _get_linux_version();
251+ unsigned long size;
252+ uint64_t bytes=0;
253+
254+ if (version >= KERNEL_VERSION(2,5,4) ||
255+ (version < KERNEL_VERSION(2,5,0) &&
256+ version >= KERNEL_VERSION (2,4,18)))
257+ {
258+ if (ioctl(fd, BLKGETSIZE64, &bytes) == 0)
259+ return bytes / _get_sector_size(fd);
260+ }
261+ if (ioctl (fd, BLKGETSIZE, &size))
262+ return 0;
263+ return size;
264+}
265+
266+static uint64_t
267+last_lba(int fd)
268+{
269+ int rc;
270+ uint64_t sectors = 0;
271+ struct stat s;
272+
273+ memset(&s, 0, sizeof (s));
274+ rc = fstat(fd, &s);
275+ if (rc == -1)
276+ {
277+ fprintf(stderr, "last_lba() could not stat: %s\n",
278+ strerror(errno));
279+ return 0;
280+ }
281+ if (S_ISBLK(s.st_mode))
282+ sectors = _get_num_sectors(fd);
283+ else
284+ {
285+ fprintf(stderr,
286+ "last_lba(): I don't know how to handle files with mode %x\n",
287+ s.st_mode);
288+ sectors = 1;
289+ }
290+ return sectors - 1;
291+}
292+
293+static ssize_t
294+read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
295+{
296+ int rc;
297+ struct blkdev_ioctl_param ioctl_param;
298+
299+ if (!buffer) return 0;
300+
301+ ioctl_param.block = 0; /* read the last sector */
302+ ioctl_param.content_length = count;
303+ ioctl_param.block_contents = buffer;
304+
305+ rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
306+ if (rc == -1) perror("read failed");
307+
308+ return !rc;
309+}
310+
311+static ssize_t
312+read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
313+{
314+ int sector_size = _get_sector_size(fd);
315+ off_t offset = lba * sector_size;
316+ ssize_t bytesread;
317+
318+ lseek(fd, offset, SEEK_SET);
319+ bytesread = read(fd, buffer, bytes);
320+
321+ /* Kludge. This is necessary to read/write the last
322+ block of an odd-sized disk, until Linux 2.5.x kernel fixes.
323+ This is only used by gpt.c, and only to read
324+ one sector, so we don't have to be fancy.
325+ */
326+ if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd))
327+ bytesread = read_lastoddsector(fd, lba, buffer, bytes);
328+ return bytesread;
329+}
330+
331+static GuidPartitionTableHeader_t *
332+alloc_read_gpt_header(int fd, uint64_t lba)
333+{
334+ GuidPartitionTableHeader_t *gpt =
335+ (GuidPartitionTableHeader_t *) malloc(sizeof (GuidPartitionTableHeader_t));
336+ if (!gpt)
337+ return NULL;
338+ memset(gpt, 0, sizeof (*gpt));
339+ if (!read_lba(fd, lba, gpt, sizeof (GuidPartitionTableHeader_t)))
340+ {
341+ free(gpt);
342+ return NULL;
343+ }
344+ return gpt;
345+}
346+
347+static int
348+gpt_check_signature(int fd, uint64_t lba)
349+{
350+ GuidPartitionTableHeader_t *gpt;
351+ int res=0;
352+
353+ if ((gpt = alloc_read_gpt_header(fd, lba)))
354+ {
355+ if (gpt->Signature == CPU_TO_LE64(GPT_HEADER_SIGNATURE))
356+ res = 1;
357+ free(gpt);
358+ }
359+ return res;
360+}
361+
362+/* returns:
363+ * 0 not found GPT
364+ * 1 for valid primary GPT header
365+ * 2 for valid alternative GPT header
366+ */
367+int
368+gpt_probe_signature_fd(int fd)
369+{
370+ int res = 0;
371+
372+ /* check primary GPT header */
373+ if (gpt_check_signature(fd, GPT_PRIMARY_PARTITION_TABLE_LBA))
374+ res = 1;
375+ else
376+ {
377+ /* check alternative GPT header */
378+ uint64_t lastlba = last_lba(fd);
379+ if (gpt_check_signature(fd, lastlba))
380+ res = 2;
381+ }
382+ return res;
383+}
384+
385+int
386+gpt_probe_signature_devname(char *devname)
387+{
388+ int res, fd;
389+ if ((fd = open(devname, O_RDONLY)) < 0)
390+ return 0;
391+ res = gpt_probe_signature_fd(fd);
392+ close(fd);
393+ return res;
394+}
395+
396+#ifdef GPT_TEST_MAIN
397+int
398+main(int argc, char **argv)
399+{
400+ if (argc!=2)
401+ {
402+ fprintf(stderr, "usage: %s <dev>\n", argv[0]);
403+ exit(EXIT_FAILURE);
404+ }
405+ if (gpt_probe_signature_devname(argv[1]))
406+ printf("GPT (GUID Partition Table) detected on %s\n", argv[1]);
407+ exit(EXIT_SUCCESS);
408+}
409+#endif
410--- util-linux-2.13-pre6/fdisk/sfdisk.c.gpt 2005-10-16 14:18:32.000000000 +0200
411+++ util-linux-2.13-pre6/fdisk/sfdisk.c 2005-11-24 15:30:36.000000000 +0100
412@@ -50,6 +50,8 @@
413 #include "nls.h"
414 #include "common.h"
415
416+#include "gpt.h"
417+
418 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
419
420 /*
421@@ -2457,6 +2459,23 @@
422 return NULL;
423 }
424
425+static void
426+gpt_warning(char *dev, int warn_only)
427+{
428+ if (force)
429+ warn_only = 1;
430+
431+ if (gpt_probe_signature_devname(dev)) {
432+ fflush(stdout);
433+ fprintf(stderr, _("\nWARNING: GPT (GUID Partition Table) detected on '%s'! "
434+ "The util sfdisk doesn't support GPT. Use GNU Parted.\n\n"), dev);
435+ if (!warn_only) {
436+ fprintf(stderr, _("Use the --force flag to overrule this check.\n"));
437+ exit(1);
438+ }
439+ }
440+}
441+
442 static void do_list(char *dev, int silent);
443 static void do_size(char *dev, int silent);
444 static void do_geom(char *dev, int silent);
445@@ -2602,6 +2621,7 @@
446 while ((dev = nextproc()) != NULL) {
447 if (is_ide_cdrom_or_tape(dev))
448 continue;
449+ gpt_warning(dev, 1);
450 if (opt_out_geom)
451 do_geom(dev, 1);
452 if (opt_out_pt_geom)
453@@ -2629,6 +2649,7 @@
454
455 if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
456 while (optind < argc) {
457+ gpt_warning(argv[optind], 1);
458 if (opt_out_geom)
459 do_geom(argv[optind], 0);
460 if (opt_out_pt_geom)
461@@ -2657,6 +2678,7 @@
462 fatal(_("usage: sfdisk --change-id device partition-number Id\n"));
463 else if (optind != argc-3 && optind != argc-2)
464 fatal(_("usage: sfdisk --id device partition-number [Id]\n"));
465+ gpt_warning(argv[optind], 0);
466 do_change_id(argv[optind], argv[optind+1],
467 (optind == argc-2) ? 0 : argv[optind+2]);
468 exit(exit_status);
469@@ -2666,6 +2688,8 @@
470 fatal(_("can specify only one device (except with -l or -s)\n"));
471 dev = argv[optind];
472
473+ gpt_warning(dev, 0);
474+
475 if (opt_reread)
476 do_reread(dev);
477 else if (restore_sector_file)
478@@ -2842,6 +2866,8 @@
479
480 z = &oldp;
481
482+ gpt_warning(dev, 0);
483+
484 rw = (!no_write && (arg || ac > 1));
485 fd = my_open(dev, rw, 0);
486
487@@ -2943,6 +2969,8 @@
488
489 z = &oldp;
490
491+ gpt_warning(dev, 0);
492+
493 rw = !no_write;
494 fd = my_open(dev, rw, 0);
495
This page took 0.858249 seconds and 4 git commands to generate.