]> git.pld-linux.org Git - packages/util-linux.git/blob - util-linux-fdisk-gpt.patch
- uniformized configs to use system-auth where possible
[packages/util-linux.git] / util-linux-fdisk-gpt.patch
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.381798 seconds and 3 git commands to generate.