1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3 libparted - a library for manipulating disk partitions
4 Copyright (C) 2000-2001, 2007-2011 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 Contributor: Phil Knirsch <phil@redhat.de>
20 Harald Hoyer <harald@redhat.de>
34 #include <sys/ioctl.h>
35 #include <parted/parted.h>
36 #include <parted/endian.h>
37 #include <parted/debug.h>
39 #include <parted/vtoc.h>
40 #include <parted/fdasd.h>
41 #include <arch/linux.h>
45 # define _(String) dgettext (PACKAGE, String)
47 # define _(String) (String)
48 #endif /* ENABLE_NLS */
53 #define PARTITION_LINUX_SWAP 0x82
54 #define PARTITION_LINUX 0x83
55 #define PARTITION_LINUX_EXT 0x85
56 #define PARTITION_LINUX_LVM 0x8e
57 #define PARTITION_LINUX_RAID 0xfd
58 #define PARTITION_LINUX_LVM_OLD 0xfe
60 extern void ped_disk_dasd_init ();
61 extern void ped_disk_dasd_done ();
63 #define DASD_NAME "dasd"
73 unsigned int format_type;
74 volume_label_t vlabel;
77 static int dasd_probe (const PedDevice *dev);
78 static int dasd_read (PedDisk* disk);
79 static int dasd_write (const PedDisk* disk);
81 static PedPartition* dasd_partition_new (const PedDisk* disk,
82 PedPartitionType part_type,
83 const PedFileSystemType* fs_type,
86 static PedPartition* dasd_partition_duplicate (const PedPartition *part);
87 static void dasd_partition_destroy (PedPartition* part);
88 static int dasd_partition_set_flag (PedPartition* part,
89 PedPartitionFlag flag,
91 static int dasd_partition_get_flag (const PedPartition* part,
92 PedPartitionFlag flag);
93 static int dasd_partition_is_flag_available (const PedPartition* part,
94 PedPartitionFlag flag);
95 static int dasd_partition_align (PedPartition* part,
96 const PedConstraint* constraint);
97 static int dasd_partition_enumerate (PedPartition* part);
98 static int dasd_get_max_primary_partition_count (const PedDisk* disk);
99 static bool dasd_get_max_supported_partition_count (const PedDisk* disk, int *max_n);
100 static PedAlignment *dasd_get_partition_alignment(const PedDisk *disk);
102 static PedDisk* dasd_alloc (const PedDevice* dev);
103 static PedDisk* dasd_duplicate (const PedDisk* disk);
104 static void dasd_free (PedDisk* disk);
105 static int dasd_partition_set_system (PedPartition* part,
106 const PedFileSystemType* fs_type);
107 static int dasd_alloc_metadata (PedDisk* disk);
109 #include "pt-common.h"
110 PT_define_limit_functions (dasd)
112 static PedDiskOps dasd_disk_ops = {
114 write: NULL_IF_DISCOVER_ONLY (dasd_write),
116 partition_set_name: NULL,
117 partition_get_name: NULL,
119 get_partition_alignment: dasd_get_partition_alignment,
121 PT_op_function_initializers (dasd)
124 static PedDiskType dasd_disk_type = {
132 dasd_alloc (const PedDevice* dev)
135 LinuxSpecific* arch_specific;
136 DasdDiskSpecific *disk_specific;
139 PED_ASSERT (dev != NULL, return NULL);
141 arch_specific = LINUX_SPECIFIC (dev);
142 disk = _ped_disk_alloc (dev, &dasd_disk_type);
146 disk->disk_specific = disk_specific = ped_malloc(sizeof(DasdDiskSpecific));
147 if (!disk->disk_specific) {
152 /* CDL format, newer */
153 disk_specific->format_type = 2;
155 /* Setup volume label (for fresh disks) */
156 snprintf(volser, sizeof(volser), "0X%04X", arch_specific->devno);
157 vtoc_volume_label_init(&disk_specific->vlabel);
158 vtoc_volume_label_set_key(&disk_specific->vlabel, "VOL1");
159 vtoc_volume_label_set_label(&disk_specific->vlabel, "VOL1");
160 vtoc_volume_label_set_volser(&disk_specific->vlabel, volser);
161 vtoc_set_cchhb(&disk_specific->vlabel.vtoc,
162 VTOC_START_CC, VTOC_START_HH, 0x01);
168 dasd_duplicate (const PedDisk* disk)
172 new_disk = ped_disk_new_fresh(disk->dev, &dasd_disk_type);
177 memcpy(new_disk->disk_specific, disk->disk_specific,
178 sizeof(DasdDiskSpecific));
184 dasd_free (PedDisk* disk)
186 PED_ASSERT(disk != NULL, return);
187 /* Don't free disk->disk_specific first, in case _ped_disk_free
188 or one of its eventual callees ever accesses it. */
189 void *p = disk->disk_specific;
190 _ped_disk_free(disk);
196 ped_disk_dasd_init ()
198 ped_disk_type_register(&dasd_disk_type);
202 ped_disk_dasd_done ()
204 ped_disk_type_unregister(&dasd_disk_type);
208 dasd_probe (const PedDevice *dev)
210 LinuxSpecific* arch_specific;
211 struct fdasd_anchor anchor;
213 PED_ASSERT(dev != NULL, return 0);
215 if (!(dev->type == PED_DEVICE_DASD
216 || dev->type == PED_DEVICE_VIODASD
217 || dev->type == PED_DEVICE_FILE))
220 arch_specific = LINUX_SPECIFIC(dev);
222 /* add partition test here */
223 fdasd_initialize_anchor(&anchor);
225 fdasd_get_geometry(dev, &anchor, arch_specific->fd);
227 fdasd_check_api_version(&anchor, arch_specific->fd);
229 if (fdasd_check_volume(&anchor, arch_specific->fd))
232 fdasd_cleanup(&anchor);
237 fdasd_cleanup(&anchor);
238 ped_exception_throw(PED_EXCEPTION_ERROR,PED_EXCEPTION_IGNORE_CANCEL,
239 "Error while probing device %s.", dev->path);
245 dasd_read (PedDisk* disk)
251 PedFileSystemType *fs;
252 PedSector start, end;
253 PedConstraint* constraint_exact;
255 LinuxSpecific* arch_specific;
256 DasdDiskSpecific* disk_specific;
257 struct fdasd_anchor anchor;
261 PED_ASSERT (disk != NULL, return 0);
263 PED_ASSERT (disk->dev != NULL, return 0);
268 arch_specific = LINUX_SPECIFIC(dev);
269 disk_specific = disk->disk_specific;
273 fdasd_initialize_anchor(&anchor);
275 fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
277 /* check dasd for labels and vtoc */
278 if (fdasd_check_volume(&anchor, arch_specific->fd))
279 goto error_close_dev;
281 /* Save volume label (read by fdasd_check_volume) for writing */
282 memcpy(&disk_specific->vlabel, anchor.vlabel, sizeof(volume_label_t));
284 if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
287 ped_disk_delete_all (disk);
289 bool is_ldl = strncmp(anchor.vlabel->volkey,
290 vtoc_ebcdic_enc("LNX1", str, 4), 4) == 0;
291 bool is_cms = strncmp(anchor.vlabel->volkey,
292 vtoc_ebcdic_enc("CMS1", str, 4), 4) == 0;
293 if (is_ldl || is_cms) {
294 DasdPartitionData* dasd_data;
297 volume_label_t unused;
298 ldl_volume_label_t ldl;
299 cms_volume_label_t cms;
301 union vollabel *cms_ptr1 = (union vollabel *) anchor.vlabel;
302 cms_volume_label_t *cms_ptr = &cms_ptr1->cms;
303 ldl_volume_label_t *ldl_ptr = &cms_ptr1->ldl;
304 int partition_start_block;
306 disk_specific->format_type = 1;
308 if (is_cms && cms_ptr->usable_count >= cms_ptr->block_count)
309 partition_start_block = 2; /* FBA DASD */
311 partition_start_block = 3; /* CKD DASD */
314 start = (long long) arch_specific->real_sector_size
315 / (long long) disk->dev->sector_size
316 * (long long) partition_start_block;
317 else if (cms_ptr->disk_offset == 0)
318 start = (long long) cms_ptr->block_size
319 / (long long) disk->dev->sector_size
320 * (long long) partition_start_block;
322 start = (long long) cms_ptr->block_size
323 / (long long) disk->dev->sector_size
324 * (long long) cms_ptr->disk_offset;
327 if (strncmp(ldl_ptr->ldl_version,
328 vtoc_ebcdic_enc("2", str, 1), 1) >= 0)
329 end = (long long) arch_specific->real_sector_size
330 / (long long) disk->dev->sector_size
331 * (long long) ldl_ptr->formatted_blocks - 1;
333 end = disk->dev->length - 1;
335 if (cms_ptr->disk_offset == 0)
336 end = (long long) cms_ptr->block_size
337 / (long long) disk->dev->sector_size
338 * (long long) cms_ptr->block_count - 1;
341 Frankly, I do not understand why the last block
342 of the CMS reserved file is not included in the
343 partition; but this is the algorithm used by the
344 Linux kernel. See fs/partitions/ibm.c in the
345 Linux kernel source code.
347 end = (long long) cms_ptr->block_size
348 / (long long) disk->dev->sector_size
349 * (long long) (cms_ptr->block_count - 1) - 1;
351 part = ped_partition_new (disk, PED_PARTITION_PROTECTED, NULL, start, end);
353 goto error_close_dev;
356 part->fs_type = ped_file_system_probe (&part->geom);
357 dasd_data = part->disk_specific;
362 if (!ped_disk_add_partition (disk, part, NULL))
363 goto error_close_dev;
365 fdasd_cleanup(&anchor);
370 /* CDL format, newer */
371 disk_specific->format_type = 2;
376 for (i = 1 ; i <= USABLE_PARTITIONS; i++) {
377 char *ch = p->f1->DS1DSNAM;
378 DasdPartitionData* dasd_data;
386 start = (long long)(long long) p->start_trk
387 * (long long) disk->dev->hw_geom.sectors
388 * (long long) arch_specific->real_sector_size
389 / (long long) disk->dev->sector_size;
390 end = (long long)((long long) p->end_trk + 1)
391 * (long long) disk->dev->hw_geom.sectors
392 * (long long) arch_specific->real_sector_size
393 / (long long) disk->dev->sector_size - 1;
394 part = ped_partition_new(disk, PED_PARTITION_NORMAL, NULL,
399 goto error_close_dev;
404 part->fs_type = ped_file_system_probe(&part->geom);
406 vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
407 ch = strstr(p->f1->DS1DSNAM, "PART");
410 strncpy(str, ch+9, 6);
414 dasd_data = part->disk_specific;
416 if ((strncmp(PART_TYPE_RAID, str, 6) == 0) &&
417 (ped_file_system_probe(&part->geom) == NULL))
418 ped_partition_set_flag(part, PED_PARTITION_RAID, 1);
420 ped_partition_set_flag(part, PED_PARTITION_RAID, 0);
422 if ((strncmp(PART_TYPE_LVM, str, 6) == 0) &&
423 (ped_file_system_probe(&part->geom) == NULL))
424 ped_partition_set_flag(part, PED_PARTITION_LVM, 1);
426 ped_partition_set_flag(part, PED_PARTITION_LVM, 0);
428 if (strncmp(PART_TYPE_SWAP, str, 6) == 0) {
429 fs = ped_file_system_probe(&part->geom);
430 if (fs && is_linux_swap(fs->name)) {
431 dasd_data->system = PARTITION_LINUX_SWAP;
436 vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
440 constraint_exact = ped_constraint_exact (&part->geom);
441 if (!constraint_exact)
442 goto error_close_dev;
443 if (!ped_disk_add_partition(disk, part, constraint_exact)) {
444 ped_constraint_destroy(constraint_exact);
445 goto error_close_dev;
447 ped_constraint_destroy(constraint_exact);
449 if (p->fspace_trk > 0) {
450 start = (long long)((long long) p->end_trk + 1)
451 * (long long) disk->dev->hw_geom.sectors
452 * (long long) arch_specific->real_sector_size
453 / (long long) disk->dev->sector_size;
454 end = (long long)((long long) p->end_trk + 1 + p->fspace_trk)
455 * (long long) disk->dev->hw_geom.sectors
456 * (long long) arch_specific->real_sector_size
457 / (long long) disk->dev->sector_size - 1;
458 part = ped_partition_new (disk, PED_PARTITION_NORMAL,
462 goto error_close_dev;
464 part->type = PED_PARTITION_FREESPACE;
465 constraint_exact = ped_constraint_exact(&part->geom);
467 if (!constraint_exact)
468 goto error_close_dev;
469 if (!ped_disk_add_partition(disk, part, constraint_exact)) {
470 ped_constraint_destroy(constraint_exact);
471 goto error_close_dev;
474 ped_constraint_destroy (constraint_exact);
481 fdasd_cleanup(&anchor);
486 fdasd_cleanup(&anchor);
491 dasd_update_type (const PedDisk* disk, struct fdasd_anchor *anchor,
492 partition_info_t *part_info[USABLE_PARTITIONS])
495 LinuxSpecific* arch_specific;
496 DasdDiskSpecific* disk_specific;
498 arch_specific = LINUX_SPECIFIC(disk->dev);
499 disk_specific = disk->disk_specific;
504 for (i = 1; i <= USABLE_PARTITIONS; i++) {
507 DasdPartitionData* dasd_data;
511 part = ped_disk_get_partition(disk, i);
517 dasd_data = part->disk_specific;
518 p = part_info[i - 1];
525 vtoc_ebcdic_dec(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
526 ch = strstr(p->f1->DS1DSNAM, "PART");
530 vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
537 switch (dasd_data->system) {
538 case PARTITION_LINUX_LVM:
540 strncpy(ch, PART_TYPE_LVM, 6);
542 case PARTITION_LINUX_RAID:
544 strncpy(ch, PART_TYPE_RAID, 6);
546 case PARTITION_LINUX:
548 strncpy(ch, PART_TYPE_NATIVE, 6);
550 case PARTITION_LINUX_SWAP:
552 strncpy(ch, PART_TYPE_SWAP, 6);
556 strncpy(ch, PART_TYPE_NATIVE, 6);
560 anchor->vtoc_changed++;
561 vtoc_ebcdic_enc(p->f1->DS1DSNAM, p->f1->DS1DSNAM, 44);
568 dasd_write (const PedDisk* disk)
570 DasdPartitionData* dasd_data;
574 LinuxSpecific* arch_specific;
575 DasdDiskSpecific* disk_specific;
576 struct fdasd_anchor anchor;
577 partition_info_t *part_info[USABLE_PARTITIONS];
579 PED_ASSERT(disk != NULL, return 0);
580 PED_ASSERT(disk->dev != NULL, return 0);
582 arch_specific = LINUX_SPECIFIC (disk->dev);
583 disk_specific = disk->disk_specific;
587 /* If not formated in CDL, don't write anything. */
588 if (disk_specific->format_type == 1)
591 /* initialize the anchor */
592 fdasd_initialize_anchor(&anchor);
593 fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
594 memcpy(anchor.vlabel, &disk_specific->vlabel, sizeof(volume_label_t));
595 anchor.vlabel_changed++;
597 if ((anchor.geo.cylinders * anchor.geo.heads) > BIG_DISK_SIZE)
600 fdasd_recreate_vtoc(&anchor);
602 for (i = 1; i <= USABLE_PARTITIONS; i++) {
603 unsigned int start, stop;
606 part = ped_disk_get_partition(disk, i);
612 start = part->geom.start * disk->dev->sector_size
613 / arch_specific->real_sector_size / disk->dev->hw_geom.sectors;
614 stop = (part->geom.end + 1)
615 * disk->dev->sector_size / arch_specific->real_sector_size
616 / disk->dev->hw_geom.sectors - 1;
619 dasd_data = part->disk_specific;
621 p = fdasd_add_partition(&anchor, start, stop);
626 part_info[i - 1] = p;
627 p->type = dasd_data->system;
632 if (!fdasd_prepare_labels(&anchor, arch_specific->fd))
635 dasd_update_type(disk, &anchor, part_info);
638 if (!fdasd_write_labels(&anchor, arch_specific->fd))
641 fdasd_cleanup(&anchor);
646 fdasd_cleanup(&anchor);
651 dasd_partition_new (const PedDisk* disk, PedPartitionType part_type,
652 const PedFileSystemType* fs_type,
653 PedSector start, PedSector end)
657 part = _ped_partition_alloc(disk, part_type, fs_type, start, end);
661 part->disk_specific = ped_malloc (sizeof (DasdPartitionData));
669 dasd_partition_duplicate (const PedPartition *part)
671 PedPartition *new_part;
673 new_part = ped_partition_new (part->disk, part->type, part->fs_type,
674 part->geom.start, part->geom.end);
677 new_part->num = part->num;
679 memcpy(new_part->disk_specific, part->disk_specific,
680 sizeof(DasdPartitionData));
686 dasd_partition_destroy (PedPartition* part)
688 PED_ASSERT(part != NULL, return);
690 if (ped_partition_is_active(part))
691 free(part->disk_specific);
696 dasd_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
698 DasdPartitionData* dasd_data;
700 PED_ASSERT(part != NULL, return 0);
701 PED_ASSERT(part->disk_specific != NULL, return 0);
702 dasd_data = part->disk_specific;
705 case PED_PARTITION_RAID:
708 dasd_data->raid = state;
709 return ped_partition_set_system(part, part->fs_type);
710 case PED_PARTITION_LVM:
713 dasd_data->lvm = state;
714 return ped_partition_set_system(part, part->fs_type);
721 dasd_partition_get_flag (const PedPartition* part, PedPartitionFlag flag)
723 DasdPartitionData* dasd_data;
725 PED_ASSERT (part != NULL, return 0);
726 PED_ASSERT (part->disk_specific != NULL, return 0);
727 dasd_data = part->disk_specific;
730 case PED_PARTITION_RAID:
731 return dasd_data->raid;
732 case PED_PARTITION_LVM:
733 return dasd_data->lvm;
740 dasd_partition_is_flag_available (const PedPartition* part,
741 PedPartitionFlag flag)
744 case PED_PARTITION_RAID:
746 case PED_PARTITION_LVM:
755 dasd_get_max_primary_partition_count (const PedDisk* disk)
757 DasdDiskSpecific* disk_specific;
759 disk_specific = disk->disk_specific;
760 /* If formated in LDL, maximum partition number is 1 */
761 if (disk_specific->format_type == 1)
764 return USABLE_PARTITIONS;
768 dasd_get_max_supported_partition_count (const PedDisk* disk, int *max_n)
770 *max_n = dasd_get_max_primary_partition_count(disk);
775 dasd_get_partition_alignment(const PedDisk *disk)
777 LinuxSpecific *arch_specific = LINUX_SPECIFIC(disk->dev);
778 PedSector sector_size =
779 arch_specific->real_sector_size / disk->dev->sector_size;
781 return ped_alignment_new(0, disk->dev->hw_geom.sectors * sector_size);
784 static PedConstraint*
785 _primary_constraint (PedDisk* disk)
787 PedAlignment start_align;
788 PedAlignment end_align;
789 PedGeometry max_geom;
790 PedSector sector_size;
791 LinuxSpecific* arch_specific;
792 DasdDiskSpecific* disk_specific;
796 arch_specific = LINUX_SPECIFIC (disk->dev);
797 disk_specific = disk->disk_specific;
798 sector_size = arch_specific->real_sector_size / disk->dev->sector_size;
800 if (!ped_alignment_init (&start_align, 0,
801 disk->dev->hw_geom.sectors * sector_size))
803 if (!ped_alignment_init (&end_align, -1,
804 disk->dev->hw_geom.sectors * sector_size))
806 if (!ped_geometry_init (&max_geom, disk->dev, 0, disk->dev->length))
809 return ped_constraint_new(&start_align, &end_align, &max_geom,
810 &max_geom, 1, disk->dev->length);
814 dasd_partition_align (PedPartition* part, const PedConstraint* constraint)
816 DasdDiskSpecific* disk_specific;
818 PED_ASSERT (part != NULL, return 0);
820 disk_specific = part->disk->disk_specific;
821 /* If formated in LDL, ignore metadata partition */
822 if (disk_specific->format_type == 1)
825 if (_ped_partition_attempt_align(part, constraint,
826 _primary_constraint(part->disk)))
829 #ifndef DISCOVER_ONLY
830 ped_exception_throw (
832 PED_EXCEPTION_CANCEL,
833 _("Unable to satisfy all constraints on the partition."));
840 dasd_partition_enumerate (PedPartition* part)
845 /* never change the partition numbers */
849 for (i = 1; i <= USABLE_PARTITIONS; i++) {
850 p = ped_disk_get_partition (part->disk, i);
857 /* failed to allocate a number */
858 ped_exception_throw(PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
859 _("Unable to allocate a dasd disklabel slot"));
864 dasd_partition_set_system (PedPartition* part,
865 const PedFileSystemType* fs_type)
867 DasdPartitionData* dasd_data = part->disk_specific;
870 cyl_size=part->disk->dev->hw_geom.sectors * part->disk->dev->hw_geom.heads;
873 part->fs_type = fs_type;
875 if (dasd_data->lvm) {
876 dasd_data->system = PARTITION_LINUX_LVM;
881 if (dasd_data->raid) {
882 dasd_data->system = PARTITION_LINUX_RAID;
888 dasd_data->system = PARTITION_LINUX;
890 } else if (is_linux_swap (fs_type->name)) {
891 dasd_data->system = PARTITION_LINUX_SWAP;
894 dasd_data->system = PARTITION_LINUX;
902 dasd_alloc_metadata (PedDisk* disk)
904 PedPartition* new_part;
905 PedConstraint* constraint_any = NULL;
907 LinuxSpecific* arch_specific;
908 DasdDiskSpecific* disk_specific;
909 PedPartition* part = NULL; /* initialize solely to placate gcc */
910 PedPartition* new_part2;
911 PedSector trailing_meta_start, trailing_meta_end;
912 struct fdasd_anchor anchor;
914 PED_ASSERT (disk != NULL, goto error);
915 PED_ASSERT (disk->dev != NULL, goto error);
917 arch_specific = LINUX_SPECIFIC (disk->dev);
918 disk_specific = disk->disk_specific;
920 constraint_any = ped_constraint_any (disk->dev);
922 /* For LDL or CMS, the leading metadata ends at the sector before
923 the start of the first partition */
924 if (disk_specific->format_type == 1) {
925 part = ped_disk_get_partition(disk, 1);
926 vtoc_end = part->geom.start - 1;
929 if (disk->dev->type == PED_DEVICE_FILE)
930 arch_specific->real_sector_size = disk->dev->sector_size;
931 /* Mark the start of the disk as metadata. */
932 vtoc_end = (FIRST_USABLE_TRK * (long long) disk->dev->hw_geom.sectors
933 * (long long) arch_specific->real_sector_size
934 / (long long) disk->dev->sector_size) - 1;
937 new_part = ped_partition_new (disk,PED_PARTITION_METADATA,NULL,0,vtoc_end);
941 if (!ped_disk_add_partition (disk, new_part, constraint_any)) {
942 ped_partition_destroy (new_part);
946 if (disk_specific->format_type == 1) {
948 For LDL or CMS there may be trailing metadata as well.
949 For example: the last block of a CMS reserved file,
950 the "recomp" area of a CMS minidisk that has been
951 formatted and then formatted again with the RECOMP
952 option specifying fewer than the maximum number of
953 cylinders, a disk that was formatted at one size,
954 backed up, then restored to a larger size disk, etc.
956 trailing_meta_start = part->geom.end + 1;
957 fdasd_initialize_anchor(&anchor);
958 fdasd_get_geometry(disk->dev, &anchor, arch_specific->fd);
959 trailing_meta_end = (long long) disk->dev->length - 1;
960 fdasd_cleanup(&anchor);
961 if (trailing_meta_end >= trailing_meta_start) {
962 new_part2 = ped_partition_new (disk,PED_PARTITION_METADATA,
963 NULL, trailing_meta_start, trailing_meta_end);
965 ped_partition_destroy (new_part);
968 if (!ped_disk_add_partition (disk, new_part2,
970 ped_partition_destroy (new_part2);
971 ped_partition_destroy (new_part);
977 ped_constraint_destroy (constraint_any);
981 ped_constraint_destroy (constraint_any);