1 - sfdisk warning for large partitions, gpt
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
6 #include <linux/blkpg.h>
11 static void delete_partition(int i);
13 #define hex_val(c) ({ \
14 @@ -2400,6 +2402,14 @@
18 +gpt_warning(char *dev)
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);
26 try(char *device, int user_specified) {
31 if (is_ide_cdrom_or_tape(device))
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 */
38 printf(_("%c: unknown command\n"), c);
44 main(int argc, char **argv) {
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))
58 + gpt_warning(disk_device);
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
69 +extern int gpt_probe_signature_fd(int fd);
70 +extern int gpt_probe_signature_devname(char *devname);
72 +#endif /* __GPT_H__ */
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
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
85 sbin_PROGRAMS += sfdisk
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
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
96 It understands DOS type partition tables and BSD or SUN type disklabels.
99 +doesn't understand GUID Partition Table (GPT) and
100 +it is not designed for large partitions. In particular case use more advanced GNU
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
109 on a device, check the partitions on a device, and - very dangerous -
110 repartition a device.
113 +doesn't understand GUID Partition Table (GPT) and
114 +it is not designed for large partitions. In particular case use more advanced GNU
118 .BI "sfdisk \-s " partition
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
124 + GPT (GUID Partition Table) signature detection. Based on libparted and
127 + Warning: this code doesn't do all GPT checks (CRC32, Protective MBR, ..). It's
128 + really GPT signature detection only.
130 + -- Karel Zak <kzak@redhat.com> (Jun-2-2005)
137 +#include <inttypes.h>
138 +#include <sys/stat.h>
139 +#include <sys/ioctl.h>
140 +#include <sys/utsname.h>
141 +#include <sys/types.h>
145 +#include <linux/fs.h>
149 +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
150 +#define SECTOR_SIZE 512 /* default */
152 +#define _GET_BYTE(x, n) ( ((x) >> (8 * (n))) & 0xff )
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) )
163 +#define PED_SWAP64(x) ((uint64_t) _PED_SWAP64( (uint64_t) (x) ))
165 +#if __BYTE_ORDER == __LITTLE_ENDIAN
166 +# define CPU_TO_LE64(x) (x)
168 +# define CPU_TO_LE64(x) PED_SWAP64(x)
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) */
176 +#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
177 +#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
182 + uint16_t time_hi_and_version;
183 + uint8_t clock_seq_hi_and_reserved;
184 + uint8_t clock_seq_low;
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
193 +typedef struct _GuidPartitionTableHeader_t {
194 + uint64_t Signature;
196 + uint32_t HeaderSize;
197 + uint32_t HeaderCRC32;
198 + uint32_t Reserved1;
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;
211 +struct blkdev_ioctl_param {
212 + unsigned int block;
213 + size_t content_length;
214 + char * block_contents;
218 +_get_linux_version (void)
220 + static int kver = -1;
221 + struct utsname uts;
230 + if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) != 3)
232 + return kver = KERNEL_VERSION (major, minor, teeny);
236 +_get_sector_size (int fd)
238 + unsigned int sector_size;
240 + if (_get_linux_version() < KERNEL_VERSION (2,3,0))
241 + return SECTOR_SIZE;
242 + if (ioctl (fd, BLKSSZGET, §or_size))
243 + return SECTOR_SIZE;
244 + return sector_size;
248 +_get_num_sectors(int fd)
250 + int version = _get_linux_version();
251 + unsigned long size;
254 + if (version >= KERNEL_VERSION(2,5,4) ||
255 + (version < KERNEL_VERSION(2,5,0) &&
256 + version >= KERNEL_VERSION (2,4,18)))
258 + if (ioctl(fd, BLKGETSIZE64, &bytes) == 0)
259 + return bytes / _get_sector_size(fd);
261 + if (ioctl (fd, BLKGETSIZE, &size))
270 + uint64_t sectors = 0;
273 + memset(&s, 0, sizeof (s));
274 + rc = fstat(fd, &s);
277 + fprintf(stderr, "last_lba() could not stat: %s\n",
281 + if (S_ISBLK(s.st_mode))
282 + sectors = _get_num_sectors(fd);
286 + "last_lba(): I don't know how to handle files with mode %x\n",
290 + return sectors - 1;
294 +read_lastoddsector(int fd, uint64_t lba, void *buffer, size_t count)
297 + struct blkdev_ioctl_param ioctl_param;
299 + if (!buffer) return 0;
301 + ioctl_param.block = 0; /* read the last sector */
302 + ioctl_param.content_length = count;
303 + ioctl_param.block_contents = buffer;
305 + rc = ioctl(fd, BLKGETLASTSECT, &ioctl_param);
306 + if (rc == -1) perror("read failed");
312 +read_lba(int fd, uint64_t lba, void *buffer, size_t bytes)
314 + int sector_size = _get_sector_size(fd);
315 + off_t offset = lba * sector_size;
318 + lseek(fd, offset, SEEK_SET);
319 + bytesread = read(fd, buffer, bytes);
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.
326 + if (!bytesread && !(last_lba(fd) & 1) && lba == last_lba(fd))
327 + bytesread = read_lastoddsector(fd, lba, buffer, bytes);
331 +static GuidPartitionTableHeader_t *
332 +alloc_read_gpt_header(int fd, uint64_t lba)
334 + GuidPartitionTableHeader_t *gpt =
335 + (GuidPartitionTableHeader_t *) malloc(sizeof (GuidPartitionTableHeader_t));
338 + memset(gpt, 0, sizeof (*gpt));
339 + if (!read_lba(fd, lba, gpt, sizeof (GuidPartitionTableHeader_t)))
348 +gpt_check_signature(int fd, uint64_t lba)
350 + GuidPartitionTableHeader_t *gpt;
353 + if ((gpt = alloc_read_gpt_header(fd, lba)))
355 + if (gpt->Signature == CPU_TO_LE64(GPT_HEADER_SIGNATURE))
364 + * 1 for valid primary GPT header
365 + * 2 for valid alternative GPT header
368 +gpt_probe_signature_fd(int fd)
372 + /* check primary GPT header */
373 + if (gpt_check_signature(fd, GPT_PRIMARY_PARTITION_TABLE_LBA))
377 + /* check alternative GPT header */
378 + uint64_t lastlba = last_lba(fd);
379 + if (gpt_check_signature(fd, lastlba))
386 +gpt_probe_signature_devname(char *devname)
389 + if ((fd = open(devname, O_RDONLY)) < 0)
391 + res = gpt_probe_signature_fd(fd);
396 +#ifdef GPT_TEST_MAIN
398 +main(int argc, char **argv)
402 + fprintf(stderr, "usage: %s <dev>\n", argv[0]);
403 + exit(EXIT_FAILURE);
405 + if (gpt_probe_signature_devname(argv[1]))
406 + printf("GPT (GUID Partition Table) detected on %s\n", argv[1]);
407 + exit(EXIT_SUCCESS);
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
418 #define SIZE(a) (sizeof(a)/sizeof(a[0]))
421 @@ -2457,6 +2459,23 @@
426 +gpt_warning(char *dev, int warn_only)
431 + if (gpt_probe_signature_devname(dev)) {
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);
436 + fprintf(stderr, _("Use the --force flag to overrule this check.\n"));
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))
449 + gpt_warning(dev, 1);
453 @@ -2629,6 +2649,7 @@
455 if (opt_list || opt_out_geom || opt_out_pt_geom || opt_size || verify) {
456 while (optind < argc) {
457 + gpt_warning(argv[optind], 1);
459 do_geom(argv[optind], 0);
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]);
469 @@ -2666,6 +2688,8 @@
470 fatal(_("can specify only one device (except with -l or -s)\n"));
473 + gpt_warning(dev, 0);
477 else if (restore_sector_file)
478 @@ -2842,6 +2866,8 @@
482 + gpt_warning(dev, 0);
484 rw = (!no_write && (arg || ac > 1));
485 fd = my_open(dev, rw, 0);
487 @@ -2943,6 +2969,8 @@
491 + gpt_warning(dev, 0);
494 fd = my_open(dev, rw, 0);