From ce6563fae4f88f08768d9bee99f7728950224b06 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 18 Dec 2009 09:42:14 +0000 Subject: [PATCH] - Allow partitioning of loopback devices (#546622) - Add libparted function to query maximum partition length and start addresses for a given disk (#533417) - Add per disk flags functions from upstream, this is the way upstream has implemented the disable cylinder alignment functionality - Add --align cmdline option to specify how to align new partitions see the parted man page for details (#361951) - Make the default alignment for new partitions optimal (#361951) - When cylinder alignment is disabled, allow use of the last (incomplete) cylinder of the disk (#533328) - Don't crash when printing partition tables in Russian (#543029) - Make parted work correctly with new lvm (#525095) --- parted-1.9.0-align-default-rh361951.patch | 11 + parted-1.9.0-diskflags.patch | 406 +++++++++++++ parted-1.9.0-entiredisk-rh533328.patch | 52 ++ parted-1.9.0-lo-as-file-rh546622.patch | 20 + parted-1.9.0-new-lvm-rh525095.patch | 122 ++++ parted-1.9.0-partition-limits-rh533417.patch | 251 ++++++++ parted-1.9.0-ru-rh543029.patch | 12 + parted-1.9.0-ui-align-rh361951.patch | 586 +++++++++++++++++++ parted.spec | 32 +- 9 files changed, 1491 insertions(+), 1 deletion(-) create mode 100644 parted-1.9.0-align-default-rh361951.patch create mode 100644 parted-1.9.0-diskflags.patch create mode 100644 parted-1.9.0-entiredisk-rh533328.patch create mode 100644 parted-1.9.0-lo-as-file-rh546622.patch create mode 100644 parted-1.9.0-new-lvm-rh525095.patch create mode 100644 parted-1.9.0-partition-limits-rh533417.patch create mode 100644 parted-1.9.0-ru-rh543029.patch create mode 100644 parted-1.9.0-ui-align-rh361951.patch diff --git a/parted-1.9.0-align-default-rh361951.patch b/parted-1.9.0-align-default-rh361951.patch new file mode 100644 index 0000000..53430f1 --- /dev/null +++ b/parted-1.9.0-align-default-rh361951.patch @@ -0,0 +1,11 @@ +--- parted-1.9.0/parted/parted.c~ 2009-12-15 18:44:00.000000000 +0100 ++++ parted-1.9.0/parted/parted.c 2009-12-15 19:20:14.000000000 +0100 +@@ -133,7 +133,7 @@ int pretend_input_tty = 0; + int opt_machine_mode = 0; + int disk_is_modified = 0; + int is_toggle_mode = 0; +-int alignment = ALIGNMENT_CYLINDER; ++int alignment = ALIGNMENT_OPTIMAL; + + static const char* number_msg = N_( + "NUMBER is the partition number used by Linux. On MS-DOS disk labels, the " diff --git a/parted-1.9.0-diskflags.patch b/parted-1.9.0-diskflags.patch new file mode 100644 index 0000000..2c66dec --- /dev/null +++ b/parted-1.9.0-diskflags.patch @@ -0,0 +1,406 @@ +diff -up parted-1.9.0/include/parted/disk.h.diskflags parted-1.9.0/include/parted/disk.h +--- parted-1.9.0/include/parted/disk.h.diskflags 2009-12-15 11:07:11.000000000 +0100 ++++ parted-1.9.0/include/parted/disk.h 2009-12-15 11:08:29.000000000 +0100 +@@ -27,6 +27,20 @@ + #define PED_DISK_H_INCLUDED + + /** ++ * Disk flags ++ */ ++enum _PedDiskFlag { ++ /* This flag (which defaults to true) controls if disk types for ++ which cylinder alignment is optional do cylinder alignment when a ++ new partition gets added. ++ This flag is available for msdos and sun disklabels (for sun labels ++ it only controls the aligning of the end of the partition) */ ++ PED_DISK_CYLINDER_ALIGNMENT=1, ++}; ++#define PED_DISK_FIRST_FLAG PED_DISK_CYLINDER_ALIGNMENT ++#define PED_DISK_LAST_FLAG PED_DISK_CYLINDER_ALIGNMENT ++ ++/** + * Partition types + */ + enum _PedPartitionType { +@@ -72,6 +86,7 @@ struct _PedDiskOps; + struct _PedDiskType; + struct _PedDiskArchOps; + ++typedef enum _PedDiskFlag PedDiskFlag; + typedef enum _PedPartitionType PedPartitionType; + typedef enum _PedPartitionFlag PedPartitionFlag; + typedef enum _PedDiskTypeFeature PedDiskTypeFeature; +@@ -180,6 +195,16 @@ struct _PedDiskOps { + void (*free) (PedDisk* disk); + int (*read) (PedDisk* disk); + int (*write) (const PedDisk* disk); ++ int (*disk_set_flag) ( ++ PedDisk *disk, ++ PedDiskFlag flag, ++ int state); ++ int (*disk_get_flag) ( ++ const PedDisk *disk, ++ PedDiskFlag flag); ++ int (*disk_is_flag_available) ( ++ const PedDisk *disk, ++ PedDiskFlag flag); + /** \todo add label guessing op here */ + + /* partition operations */ +@@ -304,6 +329,14 @@ extern const char* ped_partition_flag_ge + extern PedPartitionFlag ped_partition_flag_get_by_name (const char* name); + extern PedPartitionFlag ped_partition_flag_next (PedPartitionFlag flag); + ++extern int ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state); ++extern int ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag); ++extern int ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag); ++ ++extern const char *ped_disk_flag_get_name(PedDiskFlag flag); ++extern PedDiskFlag ped_disk_flag_get_by_name(const char *name); ++extern PedDiskFlag ped_disk_flag_next(PedDiskFlag flag); ++ + /** @} */ + + /** +diff -up parted-1.9.0/libparted/disk.c.diskflags parted-1.9.0/libparted/disk.c +--- parted-1.9.0/libparted/disk.c.diskflags 2009-12-15 11:07:11.000000000 +0100 ++++ parted-1.9.0/libparted/disk.c 2009-12-15 11:08:29.000000000 +0100 +@@ -773,6 +773,130 @@ ped_disk_max_partition_start_sector (con + } + + /** ++ * Set the state (\c 1 or \c 0) of a flag on a disk. ++ * ++ * \note It is an error to call this on an unavailable flag -- use ++ * ped_disk_is_flag_available() to determine which flags are available ++ * for a given disk label. ++ * ++ * \throws PED_EXCEPTION_ERROR if the requested flag is not available for this ++ * label. ++ */ ++int ++ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state) ++{ ++ PED_ASSERT (disk != NULL, return 0); ++ ++ PedDiskOps *ops = disk->type->ops; ++ ++ if (!ped_disk_is_flag_available(disk, flag)) { ++ ped_exception_throw ( ++ PED_EXCEPTION_ERROR, ++ PED_EXCEPTION_CANCEL, ++ "The flag '%s' is not available for %s disk labels.", ++ ped_disk_flag_get_name(flag), ++ disk->type->name); ++ return 0; ++ } ++ ++ return ops->disk_set_flag(disk, flag, state); ++} ++ ++/** ++ * Get the state (\c 1 or \c 0) of a flag on a disk. ++ */ ++int ++ped_disk_get_flag(const PedDisk *disk, PedDiskFlag flag) ++{ ++ PED_ASSERT (disk != NULL, return 0); ++ ++ PedDiskOps *ops = disk->type->ops; ++ ++ if (!ped_disk_is_flag_available(disk, flag)) ++ return 0; ++ ++ return ops->disk_get_flag(disk, flag); ++} ++ ++/** ++ * Check whether a given flag is available on a disk. ++ * ++ * \return \c 1 if the flag is available. ++ */ ++int ++ped_disk_is_flag_available(const PedDisk *disk, PedDiskFlag flag) ++{ ++ PED_ASSERT (disk != NULL, return 0); ++ ++ PedDiskOps *ops = disk->type->ops; ++ ++ if (!ops->disk_is_flag_available) ++ return 0; ++ ++ return ops->disk_is_flag_available(disk, flag); ++} ++ ++/** ++ * Returns a name for a \p flag, e.g. PED_DISK_CYLINDER_ALIGNMENT will return ++ * "cylinder_alignment". ++ * ++ * \note The returned string will be in English. However, ++ * translations are provided, so the caller can call ++ * dgettext("parted", RESULT) on the result. ++ */ ++const char * ++ped_disk_flag_get_name(PedDiskFlag flag) ++{ ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ return N_("cylinder_alignment"); ++ ++ default: ++ ped_exception_throw ( ++ PED_EXCEPTION_BUG, ++ PED_EXCEPTION_CANCEL, ++ _("Unknown disk flag, %d."), ++ flag); ++ return NULL; ++ } ++} ++ ++/** ++ * Returns the flag associated with \p name. ++ * ++ * \p name can be the English ++ * string, or the translation for the native language. ++ */ ++PedDiskFlag ++ped_disk_flag_get_by_name(const char *name) ++{ ++ PedDiskFlag flag; ++ ++ for (flag = ped_disk_flag_next(0); flag; ++ flag = ped_disk_flag_next(flag)) { ++ const char *flag_name = ped_disk_flag_get_name(flag); ++ if (strcasecmp(name, flag_name) == 0 ++ || strcasecmp(name, _(flag_name)) == 0) ++ return flag; ++ } ++ ++ return 0; ++} ++ ++/** ++ * Iterates through all disk flags. ++ * ++ * ped_disk_flag_next(0) returns the first flag ++ * ++ * \return the next flag, or 0 if there are no more flags ++ */ ++PedDiskFlag ++ped_disk_flag_next(PedDiskFlag flag) ++{ ++ return (flag + 1) % (PED_DISK_LAST_FLAG + 1); ++} ++ ++/** + * \internal We turned a really nasty bureaucracy problem into an elegant maths + * problem :-) Basically, there are some constraints to a partition's + * geometry: +diff -up parted-1.9.0/libparted/labels/dos.c.diskflags parted-1.9.0/libparted/labels/dos.c +--- parted-1.9.0/libparted/labels/dos.c.diskflags 2009-12-15 11:07:11.000000000 +0100 ++++ parted-1.9.0/libparted/labels/dos.c 2009-12-15 11:12:46.000000000 +0100 +@@ -140,6 +140,10 @@ typedef struct { + } OrigState; + + typedef struct { ++ int cylinder_alignment; ++} DosDiskData; ++ ++typedef struct { + unsigned char system; + int boot; + int hidden; +@@ -243,8 +247,16 @@ msdos_alloc (const PedDevice* dev) + PED_ASSERT (dev != NULL, return NULL); + + disk = _ped_disk_alloc ((PedDevice*)dev, &msdos_disk_type); +- if (disk) +- disk->disk_specific = NULL; ++ if (disk) { ++ DosDiskData *disk_specific = ped_malloc(sizeof *disk_specific); ++ if (!disk_specific) { ++ free (disk); ++ return NULL; ++ } ++ disk_specific->cylinder_alignment = 1; ++ disk->disk_specific = disk_specific; ++ } ++ + return disk; + } + +@@ -256,7 +268,10 @@ msdos_duplicate (const PedDisk* disk) + new_disk = ped_disk_new_fresh (disk->dev, &msdos_disk_type); + if (!new_disk) + return NULL; +- new_disk->disk_specific = NULL; ++ ++ memcpy(new_disk->disk_specific, disk->disk_specific, ++ sizeof(DosDiskData)); ++ + return new_disk; + } + +@@ -265,7 +280,45 @@ msdos_free (PedDisk* disk) + { + PED_ASSERT (disk != NULL, return); + ++ DosDiskData *disk_specific = disk->disk_specific; + _ped_disk_free (disk); ++ free(disk_specific); ++} ++ ++static int ++msdos_disk_set_flag (PedDisk *disk, PedDiskFlag flag, int state) ++{ ++ DosDiskData *disk_specific = disk->disk_specific; ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ disk_specific->cylinder_alignment = !!state; ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++static int ++msdos_disk_get_flag (const PedDisk *disk, PedDiskFlag flag) ++{ ++ DosDiskData *disk_specific = disk->disk_specific; ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ return disk_specific->cylinder_alignment; ++ default: ++ return 0; ++ } ++} ++ ++static int ++msdos_disk_is_flag_available (const PedDisk *disk, PedDiskFlag flag) ++{ ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ return 1; ++ default: ++ return 0; ++ } + } + + #ifndef DISCOVER_ONLY +@@ -2029,7 +2083,9 @@ msdos_partition_align (PedPartition* par + + partition_probe_bios_geometry (part, &bios_geom); + +- if (ped_disk_align_to_cylinders_on()) ++ DosDiskData *disk_specific = part->disk->disk_specific; ++ if (ped_disk_align_to_cylinders_on() && ++ disk_specific->cylinder_alignment) + if (_align (part, &bios_geom, constraint)) + return 1; + if (_align_no_geom (part, constraint)) +@@ -2324,6 +2380,10 @@ static PedDiskOps msdos_disk_ops = { + write: NULL, + #endif + ++ disk_set_flag: msdos_disk_set_flag, ++ disk_get_flag: msdos_disk_get_flag, ++ disk_is_flag_available: msdos_disk_is_flag_available, ++ + partition_new: msdos_partition_new, + partition_duplicate: msdos_partition_duplicate, + partition_destroy: msdos_partition_destroy, +diff -up parted-1.9.0/libparted/labels/sun.c.diskflags parted-1.9.0/libparted/labels/sun.c +--- parted-1.9.0/libparted/labels/sun.c.diskflags 2009-12-15 11:07:11.000000000 +0100 ++++ parted-1.9.0/libparted/labels/sun.c 2009-12-15 11:13:44.000000000 +0100 +@@ -94,6 +94,7 @@ struct _SunPartitionData { + struct _SunDiskData { + PedSector length; /* This is based on cyl - alt-cyl */ + SunRawLabel raw_label; ++ int cylinder_alignment; + }; + + static PedDiskType sun_disk_type; +@@ -190,6 +191,7 @@ sun_alloc (const PedDevice* dev) + + bios_geom->cylinders = dev->length / cyl_size; + sun_specific->length = bios_geom->cylinders * cyl_size; ++ sun_specific->cylinder_alignment = 1; + + label = &sun_specific->raw_label; + memset(label, 0, sizeof(SunRawLabel)); +@@ -252,6 +254,42 @@ sun_free (PedDisk *disk) + } + + static int ++sun_disk_set_flag (PedDisk *disk, PedDiskFlag flag, int state) ++{ ++ SunDiskData *disk_specific = disk->disk_specific; ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ disk_specific->cylinder_alignment = !!state; ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++static int ++sun_disk_get_flag (const PedDisk *disk, PedDiskFlag flag) ++{ ++ SunDiskData *disk_specific = disk->disk_specific; ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ return disk_specific->cylinder_alignment; ++ default: ++ return 0; ++ } ++} ++ ++static int ++sun_disk_is_flag_available (const PedDisk *disk, PedDiskFlag flag) ++{ ++ switch (flag) { ++ case PED_DISK_CYLINDER_ALIGNMENT: ++ return 1; ++ default: ++ return 0; ++ } ++} ++ ++static int + _check_geometry_sanity (PedDisk* disk, SunRawLabel* label) + { + PedDevice* dev = disk->dev; +@@ -738,12 +776,15 @@ sun_partition_align (PedPartition* part, + { + PED_ASSERT (part != NULL, return 0); + +- if (_ped_partition_attempt_align (part, constraint, +- _get_strict_constraint (part->disk))) +- return 1; +- if (_ped_partition_attempt_align (part, constraint, +- _get_lax_constraint (part->disk))) +- return 1; ++ SunDiskData *disk_specific = part->disk->disk_specific; ++ ++ if (disk_specific->cylinder_alignment && ++ _ped_partition_attempt_align (part, constraint, ++ _get_strict_constraint (part->disk))) ++ return 1; ++ if (_ped_partition_attempt_align (part, constraint, ++ _get_lax_constraint (part->disk))) ++ return 1; + + #ifndef DISCOVER_ONLY + ped_exception_throw ( +@@ -862,6 +903,10 @@ static PedDiskOps sun_disk_ops = { + write: NULL, + #endif + ++ disk_set_flag: sun_disk_set_flag, ++ disk_get_flag: sun_disk_get_flag, ++ disk_is_flag_available: sun_disk_is_flag_available, ++ + partition_new: sun_partition_new, + partition_duplicate: sun_partition_duplicate, + partition_destroy: sun_partition_destroy, diff --git a/parted-1.9.0-entiredisk-rh533328.patch b/parted-1.9.0-entiredisk-rh533328.patch new file mode 100644 index 0000000..0a99ace --- /dev/null +++ b/parted-1.9.0-entiredisk-rh533328.patch @@ -0,0 +1,52 @@ +diff -up parted-1.9.0/libparted/disk.c.entiredisk parted-1.9.0/libparted/disk.c +--- parted-1.9.0/libparted/disk.c.entiredisk 2009-12-15 19:22:01.000000000 +0100 ++++ parted-1.9.0/libparted/disk.c 2009-12-15 20:19:30.000000000 +0100 +@@ -785,10 +785,15 @@ ped_disk_max_partition_start_sector (con + int + ped_disk_set_flag(PedDisk *disk, PedDiskFlag flag, int state) + { ++ int ret; ++ + PED_ASSERT (disk != NULL, return 0); + + PedDiskOps *ops = disk->type->ops; + ++ if (!_disk_push_update_mode(disk)) ++ return 0; ++ + if (!ped_disk_is_flag_available(disk, flag)) { + ped_exception_throw ( + PED_EXCEPTION_ERROR, +@@ -796,10 +801,16 @@ ped_disk_set_flag(PedDisk *disk, PedDisk + "The flag '%s' is not available for %s disk labels.", + ped_disk_flag_get_name(flag), + disk->type->name); ++ _disk_pop_update_mode(disk); + return 0; + } + +- return ops->disk_set_flag(disk, flag, state); ++ ret = ops->disk_set_flag(disk, flag, state); ++ ++ if (!_disk_pop_update_mode (disk)) ++ return 0; ++ ++ return ret; + } + + /** +diff -up parted-1.9.0/libparted/labels/dos.c.entiredisk parted-1.9.0/libparted/labels/dos.c +--- parted-1.9.0/libparted/labels/dos.c.entiredisk 2009-12-15 19:22:01.000000000 +0100 ++++ parted-1.9.0/libparted/labels/dos.c 2009-12-15 20:19:38.000000000 +0100 +@@ -2242,7 +2242,10 @@ add_startend_metadata (PedDisk* disk) + else + init_end = PED_MIN (dev->bios_geom.sectors - 1, init_end - 1); + +- if (!get_end_last_nonfree_part(disk, &final_start)) ++ DosDiskData *disk_specific = disk->disk_specific; ++ if (!disk_specific->cylinder_alignment) ++ final_start = dev->length - 1; ++ else if (!get_end_last_nonfree_part(disk, &final_start)) + final_start = ped_round_down_to (dev->length, cyl_size); + else + final_start = PED_MAX (final_start + 1, diff --git a/parted-1.9.0-lo-as-file-rh546622.patch b/parted-1.9.0-lo-as-file-rh546622.patch new file mode 100644 index 0000000..a3bf65a --- /dev/null +++ b/parted-1.9.0-lo-as-file-rh546622.patch @@ -0,0 +1,20 @@ +diff -up parted-1.9.0/libparted/arch/linux.c.orig parted-1.9.0/libparted/arch/linux.c +--- parted-1.9.0/libparted/arch/linux.c.orig 2009-12-14 22:44:18.000000000 +0100 ++++ parted-1.9.0/libparted/arch/linux.c 2009-12-15 10:25:38.000000000 +0100 +@@ -259,6 +259,7 @@ struct blkdev_ioctl_param { + #define SX8_MAJOR2 161 + #define XVD_MAJOR 202 + #define SDMMC_MAJOR 179 ++#define LOOP_MAJOR 7 + + #define SCSI_BLK_MAJOR(M) ( \ + (M) == SCSI_DISK0_MAJOR \ +@@ -561,6 +562,8 @@ _device_probe_type (PedDevice* dev) + dev->type = PED_DEVICE_SDMMC; + } else if (_is_virtblk_major(dev_major)) { + dev->type = PED_DEVICE_VIRTBLK; ++ } else if (dev_major == LOOP_MAJOR) { ++ dev->type = PED_DEVICE_FILE; + } else { + dev->type = PED_DEVICE_UNKNOWN; + } diff --git a/parted-1.9.0-new-lvm-rh525095.patch b/parted-1.9.0-new-lvm-rh525095.patch new file mode 100644 index 0000000..9ab9b32 --- /dev/null +++ b/parted-1.9.0-new-lvm-rh525095.patch @@ -0,0 +1,122 @@ +--- parted-1.9.0.orig/libparted/arch/linux.c 2009-12-18 09:35:22.000000000 +0100 ++++ parted-1.9.0/libparted/arch/linux.c 2009-12-18 09:57:37.000000000 +0100 +@@ -430,7 +430,8 @@ + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + return r; + +- if (!dm_task_set_name(dmt, dev->path)) ++ if (!dm_task_set_major_minor(dmt, arch_specific->major, ++ arch_specific->minor, 0)) + goto bad; + + dm_task_no_open_count(dmt); +@@ -513,6 +514,7 @@ + struct stat dev_stat; + int dev_major; + int dev_minor; ++ LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); + + if (!_device_stat (dev, &dev_stat)) + return 0; +@@ -522,8 +524,8 @@ + return 1; + } + +- dev_major = major (dev_stat.st_rdev); +- dev_minor = minor (dev_stat.st_rdev); ++ arch_specific->major = dev_major = major (dev_stat.st_rdev); ++ arch_specific->minor = dev_minor = minor (dev_stat.st_rdev); + + if (SCSI_BLK_MAJOR (dev_major) && (dev_minor % 0x10 == 0)) { + dev->type = PED_DEVICE_SCSI; +@@ -2305,22 +2307,20 @@ + static int + _dm_remove_parts (PedDevice* dev) + { +- struct stat dev_stat; + struct dm_task* task = NULL; + struct dm_info* info = alloca(sizeof *info); + struct dm_names* names = NULL; + unsigned int next = 0; + int rc; +- +- if (!_device_stat (dev, &dev_stat)) +- goto err; ++ LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); + + task = dm_task_create(DM_DEVICE_LIST); + if (!task) + goto err; + +- dm_task_set_major (task, major (dev_stat.st_rdev)); +- dm_task_set_minor (task, minor (dev_stat.st_rdev)); ++ if (!dm_task_set_major_minor (task, arch_specific->major, ++ arch_specific->minor, 0)) ++ goto err; + + rc = dm_task_run(task); + if (rc < 0) +@@ -2365,33 +2365,36 @@ + static int + _dm_add_partition (PedDisk* disk, PedPartition* part) + { +- struct stat dev_stat; + struct dm_task* task = NULL; + int rc; + char* vol_name = NULL; +- char* dev_name = NULL; ++ const char *dev_name = NULL; + char* params = NULL; ++ LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev); + +- dev_name = _device_get_part_path (disk->dev, part->num); +- if (!dev_name) +- return 0; ++ /* Get map name from devicemapper */ ++ task = dm_task_create (DM_DEVICE_INFO); ++ if (!task) ++ goto err; + +- vol_name = strrchr (dev_name, '/'); +- if (vol_name && *vol_name && *(++vol_name)) +- vol_name = strdup (vol_name); +- else +- vol_name = strdup (dev_name); +- if (!vol_name) +- return 0; ++ if (!dm_task_set_major_minor (task, arch_specific->major, ++ arch_specific->minor, 0)) ++ goto err; + +- if (!_device_stat (disk->dev, &dev_stat)) ++ rc = dm_task_run(task); ++ if (rc < 0) + goto err; + +- if (asprintf (¶ms, "%d:%d %lld", major (dev_stat.st_rdev), +- minor (dev_stat.st_rdev), part->geom.start) == -1) ++ dev_name = dm_task_get_name (task); ++ ++ if (asprintf (&vol_name, "%sp%d", dev_name, part->num) == -1) + goto err; + +- if (!params) ++ dm_task_destroy (task); ++ task = NULL; ++ ++ if (asprintf (¶ms, "%d:%d %lld", arch_specific->major, ++ arch_specific->minor, part->geom.start) == -1) + goto err; + + task = dm_task_create (DM_DEVICE_CREATE); +--- parted-1.9.0.orig/libparted/arch/linux.h 2009-12-18 09:35:22.000000000 +0100 ++++ parted-1.9.0/libparted/arch/linux.h 2009-12-18 09:44:26.000000000 +0100 +@@ -28,6 +28,8 @@ + + struct _LinuxSpecific { + int fd; ++ int major; ++ int minor; + char* dmtype; /**< device map target type */ + #if defined(__s390__) || defined(__s390x__) + unsigned int real_sector_size; diff --git a/parted-1.9.0-partition-limits-rh533417.patch b/parted-1.9.0-partition-limits-rh533417.patch new file mode 100644 index 0000000..3535bf3 --- /dev/null +++ b/parted-1.9.0-partition-limits-rh533417.patch @@ -0,0 +1,251 @@ +--- parted-1.9.0.orig/include/parted/disk.h 2009-12-15 10:32:24.000000000 +0100 ++++ parted-1.9.0/include/parted/disk.h 2009-12-15 10:59:26.000000000 +0100 +@@ -266,6 +266,9 @@ + int* supported); + extern PedAlignment *ped_disk_get_partition_alignment(const PedDisk *disk); + ++extern PedSector ped_disk_max_partition_length (const PedDisk *disk); ++extern PedSector ped_disk_max_partition_start_sector (const PedDisk *disk); ++ + extern int ped_disk_align_to_cylinders_on(); + extern int ped_disk_align_to_cylinders_toggle(); + /** @} */ +--- parted-1.9.0.orig/libparted/disk.c 2009-12-15 10:32:24.000000000 +0100 ++++ parted-1.9.0/libparted/disk.c 2009-12-15 10:55:16.000000000 +0100 +@@ -738,6 +738,40 @@ + return disk->type->ops->get_max_primary_partition_count (disk); + } + ++#include "labels/pt-limit.c" ++ ++/** ++ * Return the maximum representable length (in sectors) of a ++ * partition on disk \disk. ++ */ ++PedSector ++ped_disk_max_partition_length (const PedDisk* disk) ++{ ++ const char *pt_type = disk->type->name; ++ struct partition_limit const *pt_lim ++ = pt_limit_lookup (pt_type, strlen (pt_type)); ++ if (pt_lim == NULL) ++ return 0; ++ ++ return pt_lim->max_length; ++} ++ ++/** ++ * Return the maximum representable start sector of a ++ * partition on disk \disk. ++ */ ++PedSector ++ped_disk_max_partition_start_sector (const PedDisk* disk) ++{ ++ const char *pt_type = disk->type->name; ++ struct partition_limit const *pt_lim ++ = pt_limit_lookup (pt_type, strlen (pt_type)); ++ if (pt_lim == NULL) ++ return 0; ++ ++ return pt_lim->max_start_sector; ++} ++ + /** + * \internal We turned a really nasty bureaucracy problem into an elegant maths + * problem :-) Basically, there are some constraints to a partition's +--- parted-1.9.0.orig/libparted/labels/pt-limit.c 1970-01-01 01:00:00.000000000 +0100 ++++ parted-1.9.0/libparted/labels/pt-limit.c 2009-12-15 10:40:46.000000000 +0100 +@@ -0,0 +1,164 @@ ++/* ANSI-C code produced by gperf version 3.0.3 */ ++/* Command-line: gperf -C -N pt_limit_lookup -n -t -s 6 -k '*' --language=ANSI-C pt-limit.gperf */ ++ ++#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ ++ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ ++ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ ++ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ ++ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ ++ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ ++ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ ++ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ ++ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ ++ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ ++ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ ++ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ ++ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ ++ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ ++ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ ++ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ ++ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ ++ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ ++ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ ++ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ ++ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ ++ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ ++ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) ++/* The character set is not based on ISO-646. */ ++#error "gperf generated tables don't work with this execution character set. Please report a bug to ." ++#endif ++ ++#line 1 "pt-limit.gperf" ++struct partition_limit ++{ ++ char const *name; ++ uint64_t max_start_sector; ++ uint64_t max_length; ++}; ++ ++#define TOTAL_KEYWORDS 10 ++#define MIN_WORD_LENGTH 3 ++#define MAX_WORD_LENGTH 5 ++#define MIN_HASH_VALUE 0 ++#define MAX_HASH_VALUE 45 ++/* maximum key range = 46, duplicates = 0 */ ++ ++#ifdef __GNUC__ ++__inline ++#else ++#ifdef __cplusplus ++inline ++#endif ++#endif ++static unsigned int ++hash (register const char *str, register unsigned int len) ++{ ++ static const unsigned char asso_values[] = ++ { ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 10, 5, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 0, 30, 30, ++ 10, 46, 46, 5, 10, 15, 46, 46, 5, 5, ++ 0, 0, 0, 46, 46, 0, 5, 0, 10, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, ++ 46, 46, 46, 46, 46, 46 ++ }; ++ register int hval = 0; ++ ++ switch (len) ++ { ++ default: ++ hval += asso_values[(unsigned char)str[4]]; ++ /*FALLTHROUGH*/ ++ case 4: ++ hval += asso_values[(unsigned char)str[3]]; ++ /*FALLTHROUGH*/ ++ case 3: ++ hval += asso_values[(unsigned char)str[2]]; ++ /*FALLTHROUGH*/ ++ case 2: ++ hval += asso_values[(unsigned char)str[1]]; ++ /*FALLTHROUGH*/ ++ case 1: ++ hval += asso_values[(unsigned char)str[0]]; ++ break; ++ } ++ return hval; ++} ++ ++#ifdef __GNUC__ ++__inline ++static ++#ifdef __GNUC_STDC_INLINE__ ++__attribute__ ((__gnu_inline__)) ++#endif ++#endif ++const struct partition_limit * ++pt_limit_lookup (register const char *str, register unsigned int len) ++{ ++ static const struct partition_limit wordlist[] = ++ { ++#line 18 "pt-limit.gperf" ++ {"sun",128ULL*UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 22 "pt-limit.gperf" ++ {"loop",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 10 "pt-limit.gperf" ++ {"gpt",UINT64_MAX,UINT64_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 12 "pt-limit.gperf" ++ {"msdos",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 8 "pt-limit.gperf" ++ {"dasd",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 26 "pt-limit.gperf" ++ {"amiga",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 9 "pt-limit.gperf" ++ {"dvh",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 11 "pt-limit.gperf" ++ {"mac",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 20 "pt-limit.gperf" ++ {"bsd",UINT32_MAX,UINT32_MAX}, ++ {""}, {""}, {""}, {""}, ++#line 23 "pt-limit.gperf" ++ {"pc98",UINT32_MAX,UINT32_MAX} ++ }; ++ ++ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) ++ { ++ register int key = hash (str, len); ++ ++ if (key <= MAX_HASH_VALUE && key >= 0) ++ { ++ register const char *s = wordlist[key].name; ++ ++ if (*str == *s && !strcmp (str + 1, s + 1)) ++ return &wordlist[key]; ++ } ++ } ++ return 0; ++} +--- parted-1.9.0.orig/libparted/labels/pt-limit.gperf 1970-01-01 01:00:00.000000000 +0100 ++++ parted-1.9.0/libparted/labels/pt-limit.gperf 2009-12-15 10:57:05.000000000 +0100 +@@ -0,0 +1,26 @@ ++struct partition_limit ++{ ++ char const *name; ++ uint64_t max_start_sector; ++ uint64_t max_length; ++}; ++%% ++dasd,UINT32_MAX,UINT32_MAX ++dvh,UINT32_MAX,UINT32_MAX ++gpt,UINT64_MAX,UINT64_MAX ++mac,UINT32_MAX,UINT32_MAX ++msdos,UINT32_MAX,UINT32_MAX ++# ++# Sun partitions are cylinder-aligned, and it looks like there are 128 sectors ++# in a cylinder. FIXME verify. Possibly compute sectors-per-cylinder, given ++# u_int16_t ntrks; /* Tracks per cylinder */ ++# u_int16_t nsect; /* Sectors per track */ ++sun,128ULL*UINT32_MAX,UINT32_MAX ++# ++bsd,UINT32_MAX,UINT32_MAX ++# aix,UINT32_MAX,UINT32_MAX ++loop,UINT32_MAX,UINT32_MAX ++pc98,UINT32_MAX,UINT32_MAX ++# ++# FIXME: not verified. looks like these are cylinder aligned, too ++amiga,UINT32_MAX,UINT32_MAX diff --git a/parted-1.9.0-ru-rh543029.patch b/parted-1.9.0-ru-rh543029.patch new file mode 100644 index 0000000..478259c --- /dev/null +++ b/parted-1.9.0-ru-rh543029.patch @@ -0,0 +1,12 @@ +diff -up parted-1.9.0/parted/parted.c.ru parted-1.9.0/parted/parted.c +--- parted-1.9.0/parted/parted.c.ru 2009-12-17 10:32:41.000000000 +0100 ++++ parted-1.9.0/parted/parted.c 2009-12-17 10:32:01.000000000 +0100 +@@ -1227,7 +1227,7 @@ partition_print_flags (PedPartition* par + ped_realloc (&_res, strlen (res) + 1 + + strlen (name)); + res = _res; +- strncat (res, name, 21); ++ strcat (res, name); + } + } + diff --git a/parted-1.9.0-ui-align-rh361951.patch b/parted-1.9.0-ui-align-rh361951.patch new file mode 100644 index 0000000..a0a73da --- /dev/null +++ b/parted-1.9.0-ui-align-rh361951.patch @@ -0,0 +1,586 @@ +diff -up parted-1.9.0/doc/C/parted.8.align parted-1.9.0/doc/C/parted.8 +--- parted-1.9.0/doc/C/parted.8.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/doc/C/parted.8 2009-12-15 18:42:29.000000000 +0100 +@@ -30,6 +30,26 @@ never prompts for user intervention + .TP + .B -v, --version + displays the version ++.TP ++.B -a \fIalignment-type\fP, --align \fIalignment-type\fP ++Set alignment for newly created partitions, valid alignment types are: ++.RS ++.IP none ++Use the minimum alignment allowed by the disk type. ++.IP cylinder ++Align partitions to cylinders. ++.IP minimal ++Use minimum alignment as given by the disk topology information. This and ++the opt value will use layout information provided by the disk to align the ++logical partition table addresses to actual physical blocks on the disks. ++The min value is the minimum aligment needed to align the partition properly to ++physical blocks, which avoids performance degradation. ++.IP optimal ++Use optimum alignment as given by the disk topology information. This ++aligns to a multiple of the physical block size in a way that guarantees ++optimal performance. ++.RE ++ + .SH COMMANDS + .TP + .B [device] +diff -up parted-1.9.0/doc/parted.texi.align parted-1.9.0/doc/parted.texi +--- parted-1.9.0/doc/parted.texi.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/doc/parted.texi 2009-12-15 18:42:29.000000000 +0100 +@@ -496,6 +496,11 @@ display a help message + @itemx --script + never prompt the user + ++@item -a alignment-type ++@itemx --align alignment-type ++Set alignment for newly created partitions, valid alignment types are: ++none, cylinder, minimal and optimal. ++ + @item -v + @itemx --version + display the version +diff -up parted-1.9.0/lib/argmatch.c.align parted-1.9.0/lib/argmatch.c +--- parted-1.9.0/lib/argmatch.c.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/lib/argmatch.c 2009-12-15 18:43:16.000000000 +0100 +@@ -0,0 +1,274 @@ ++/* argmatch.c -- find a match for a string in an array ++ ++ Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007 ++ Free Software Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Written by David MacKenzie ++ Modified by Akim Demaille */ ++ ++#include ++ ++/* Specification. */ ++#include "argmatch.h" ++ ++#include ++#include ++#include ++#include ++ ++#include "gettext.h" ++#define _(msgid) gettext (msgid) ++ ++#include "error.h" ++ ++#if USE_UNLOCKED_IO ++# include "unlocked-io.h" ++#endif ++ ++/* When reporting an invalid argument, show nonprinting characters ++ by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use ++ literal_quoting_style. */ ++#ifndef ARGMATCH_QUOTING_STYLE ++# define ARGMATCH_QUOTING_STYLE locale_quoting_style ++#endif ++ ++/* Non failing version of argmatch call this function after failing. */ ++#ifndef ARGMATCH_DIE ++# include "exitfail.h" ++# define ARGMATCH_DIE exit (exit_failure) ++#endif ++ ++#ifdef ARGMATCH_DIE_DECL ++ARGMATCH_DIE_DECL; ++#endif ++ ++static void ++__argmatch_die (void) ++{ ++ ARGMATCH_DIE; ++} ++ ++/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. ++ Default to __argmatch_die, but allow caller to change this at run-time. */ ++argmatch_exit_fn argmatch_die = __argmatch_die; ++ ++ ++/* If ARG is an unambiguous match for an element of the ++ NULL-terminated array ARGLIST, return the index in ARGLIST ++ of the matched element, else -1 if it does not match any element ++ or -2 if it is ambiguous (is a prefix of more than one element). ++ ++ If VALLIST is none null, use it to resolve ambiguities limited to ++ synonyms, i.e., for ++ "yes", "yop" -> 0 ++ "no", "nope" -> 1 ++ "y" is a valid argument, for `0', and "n" for `1'. */ ++ ++ptrdiff_t ++argmatch (const char *arg, const char *const *arglist, ++ const char *vallist, size_t valsize) ++{ ++ size_t i; /* Temporary index in ARGLIST. */ ++ size_t arglen; /* Length of ARG. */ ++ ptrdiff_t matchind = -1; /* Index of first nonexact match. */ ++ bool ambiguous = false; /* If true, multiple nonexact match(es). */ ++ ++ arglen = strlen (arg); ++ ++ /* Test all elements for either exact match or abbreviated matches. */ ++ for (i = 0; arglist[i]; i++) ++ { ++ if (!strncmp (arglist[i], arg, arglen)) ++ { ++ if (strlen (arglist[i]) == arglen) ++ /* Exact match found. */ ++ return i; ++ else if (matchind == -1) ++ /* First nonexact match found. */ ++ matchind = i; ++ else ++ { ++ /* Second nonexact match found. */ ++ if (vallist == NULL ++ || memcmp (vallist + valsize * matchind, ++ vallist + valsize * i, valsize)) ++ { ++ /* There is a real ambiguity, or we could not ++ disambiguate. */ ++ ambiguous = true; ++ } ++ } ++ } ++ } ++ if (ambiguous) ++ return -2; ++ else ++ return matchind; ++} ++ ++/* Error reporting for argmatch. ++ CONTEXT is a description of the type of entity that was being matched. ++ VALUE is the invalid value that was given. ++ PROBLEM is the return value from argmatch. */ ++ ++void ++argmatch_invalid (const char *context, const char *value, ptrdiff_t problem) ++{ ++ char const *format = (problem == -1 ++ ? _("invalid argument %s for %s") ++ : _("ambiguous argument %s for %s")); ++ ++ error (0, 0, format, value, context); ++} ++ ++/* List the valid arguments for argmatch. ++ ARGLIST is the same as in argmatch. ++ VALLIST is a pointer to an array of values. ++ VALSIZE is the size of the elements of VALLIST */ ++void ++argmatch_valid (const char *const *arglist, ++ const char *vallist, size_t valsize) ++{ ++ size_t i; ++ const char *last_val = NULL; ++ ++ /* We try to put synonyms on the same line. The assumption is that ++ synonyms follow each other */ ++ fprintf (stderr, _("Valid arguments are:")); ++ for (i = 0; arglist[i]; i++) ++ if ((i == 0) ++ || memcmp (last_val, vallist + valsize * i, valsize)) ++ { ++ fprintf (stderr, "\n - `%s'", arglist[i]); ++ last_val = vallist + valsize * i; ++ } ++ else ++ { ++ fprintf (stderr, ", `%s'", arglist[i]); ++ } ++ putc ('\n', stderr); ++} ++ ++/* Never failing versions of the previous functions. ++ ++ CONTEXT is the context for which argmatch is called (e.g., ++ "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, ++ calls the (supposed never to return) function EXIT_FN. */ ++ ++ptrdiff_t ++__xargmatch_internal (const char *context, ++ const char *arg, const char *const *arglist, ++ const char *vallist, size_t valsize, ++ argmatch_exit_fn exit_fn) ++{ ++ ptrdiff_t res = argmatch (arg, arglist, vallist, valsize); ++ if (res >= 0) ++ /* Success. */ ++ return res; ++ ++ /* We failed. Explain why. */ ++ argmatch_invalid (context, arg, res); ++ argmatch_valid (arglist, vallist, valsize); ++ (*exit_fn) (); ++ ++ return -1; /* To please the compilers. */ ++} ++ ++/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and ++ return the first corresponding argument in ARGLIST */ ++const char * ++argmatch_to_argument (const char *value, ++ const char *const *arglist, ++ const char *vallist, size_t valsize) ++{ ++ size_t i; ++ ++ for (i = 0; arglist[i]; i++) ++ if (!memcmp (value, vallist + valsize * i, valsize)) ++ return arglist[i]; ++ return NULL; ++} ++ ++#ifdef TEST ++/* ++ * Based on "getversion.c" by David MacKenzie ++ */ ++char *program_name; ++ ++/* When to make backup files. */ ++enum backup_type ++{ ++ /* Never make backups. */ ++ no_backups, ++ ++ /* Make simple backups of every file. */ ++ simple_backups, ++ ++ /* Make numbered backups of files that already have numbered backups, ++ and simple backups of the others. */ ++ numbered_existing_backups, ++ ++ /* Make numbered backups of every file. */ ++ numbered_backups ++}; ++ ++/* Two tables describing arguments (keys) and their corresponding ++ values */ ++static const char *const backup_args[] = ++{ ++ "no", "none", "off", ++ "simple", "never", ++ "existing", "nil", ++ "numbered", "t", ++ 0 ++}; ++ ++static const enum backup_type backup_vals[] = ++{ ++ no_backups, no_backups, no_backups, ++ simple_backups, simple_backups, ++ numbered_existing_backups, numbered_existing_backups, ++ numbered_backups, numbered_backups ++}; ++ ++int ++main (int argc, const char *const *argv) ++{ ++ const char *cp; ++ enum backup_type backup_type = no_backups; ++ ++ program_name = (char *) argv[0]; ++ ++ if (argc > 2) ++ { ++ fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); ++ exit (1); ++ } ++ ++ if ((cp = getenv ("VERSION_CONTROL"))) ++ backup_type = XARGMATCH ("$VERSION_CONTROL", cp, ++ backup_args, backup_vals); ++ ++ if (argc == 2) ++ backup_type = XARGMATCH (program_name, argv[1], ++ backup_args, backup_vals); ++ ++ printf ("The version control is `%s'\n", ++ ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); ++ ++ return 0; ++} ++#endif +diff -up parted-1.9.0/lib/argmatch.h.align parted-1.9.0/lib/argmatch.h +--- parted-1.9.0/lib/argmatch.h.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/lib/argmatch.h 2009-12-15 18:42:29.000000000 +0100 +@@ -0,0 +1,102 @@ ++/* argmatch.h -- definitions and prototypes for argmatch.c ++ ++ Copyright (C) 1990, 1998, 1999, 2001, 2002, 2004, 2005 Free Software ++ Foundation, Inc. ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Written by David MacKenzie ++ Modified by Akim Demaille */ ++ ++#ifndef ARGMATCH_H_ ++# define ARGMATCH_H_ 1 ++ ++# include ++ ++# include "verify.h" ++ ++# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) ++ ++/* Assert there are as many real arguments as there are values ++ (argument list ends with a NULL guard). */ ++ ++# define ARGMATCH_VERIFY(Arglist, Vallist) \ ++ verify (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1) ++ ++/* Return the index of the element of ARGLIST (NULL terminated) that ++ matches with ARG. If VALLIST is not NULL, then use it to resolve ++ false ambiguities (i.e., different matches of ARG but corresponding ++ to the same values in VALLIST). */ ++ ++ptrdiff_t argmatch (char const *arg, char const *const *arglist, ++ char const *vallist, size_t valsize); ++ ++# define ARGMATCH(Arg, Arglist, Vallist) \ ++ argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist)) ++ ++/* xargmatch calls this function when it fails. This function should not ++ return. By default, this is a function that calls ARGMATCH_DIE which ++ in turn defaults to `exit (exit_failure)'. */ ++typedef void (*argmatch_exit_fn) (void); ++extern argmatch_exit_fn argmatch_die; ++ ++/* Report on stderr why argmatch failed. Report correct values. */ ++ ++void argmatch_invalid (char const *context, char const *value, ++ ptrdiff_t problem); ++ ++/* Left for compatibility with the old name invalid_arg */ ++ ++# define invalid_arg(Context, Value, Problem) \ ++ argmatch_invalid (Context, Value, Problem) ++ ++ ++ ++/* Report on stderr the list of possible arguments. */ ++ ++void argmatch_valid (char const *const *arglist, ++ char const *vallist, size_t valsize); ++ ++# define ARGMATCH_VALID(Arglist, Vallist) \ ++ argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist)) ++ ++ ++ ++/* Same as argmatch, but upon failure, reports a explanation on the ++ failure, and exits using the function EXIT_FN. */ ++ ++ptrdiff_t __xargmatch_internal (char const *context, ++ char const *arg, char const *const *arglist, ++ char const *vallist, size_t valsize, ++ argmatch_exit_fn exit_fn); ++ ++/* Programmer friendly interface to __xargmatch_internal. */ ++ ++# define XARGMATCH(Context, Arg, Arglist, Vallist) \ ++ ((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \ ++ (char const *) (Vallist), \ ++ sizeof *(Vallist), \ ++ argmatch_die)]) ++ ++/* Convert a value into a corresponding argument. */ ++ ++char const *argmatch_to_argument (char const *value, ++ char const *const *arglist, ++ char const *vallist, size_t valsize); ++ ++# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \ ++ argmatch_to_argument (Value, Arglist, \ ++ (char const *) (Vallist), sizeof *(Vallist)) ++ ++#endif /* ARGMATCH_H_ */ +diff -up parted-1.9.0/lib/gnulib.mk.align parted-1.9.0/lib/gnulib.mk +--- parted-1.9.0/lib/gnulib.mk.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/lib/gnulib.mk 2009-12-15 18:42:29.000000000 +0100 +@@ -72,6 +72,15 @@ EXTRA_DIST += $(top_srcdir)/build-aux/an + + ## end gnulib module announce-gen + ++## begin gnulib module argmatch ++ ++ ++EXTRA_DIST += argmatch.c argmatch.h ++ ++libgnulib_la_SOURCES += argmatch.c ++ ++## end gnulib module argmatch ++ + ## begin gnulib module btowc + + +diff -up parted-1.9.0/parted/parted.c.align parted-1.9.0/parted/parted.c +--- parted-1.9.0/parted/parted.c.align 2009-12-15 18:42:25.000000000 +0100 ++++ parted-1.9.0/parted/parted.c 2009-12-15 18:42:29.000000000 +0100 +@@ -19,6 +19,7 @@ + #include + #include + ++#include "argmatch.h" + #include "closeout.h" + #include "configmake.h" + #include "version-etc.h" +@@ -74,6 +75,31 @@ enum + PRETEND_INPUT_TTY = CHAR_MAX + 1, + }; + ++enum ++{ ++ ALIGNMENT_NONE = 2, ++ ALIGNMENT_CYLINDER, ++ ALIGNMENT_MINIMAL, ++ ALIGNMENT_OPTIMAL ++}; ++ ++static char const *const align_args[] = ++{ ++ "none", ++ "cylinder", ++ "minimal", ++ "optimal", ++ NULL ++}; ++ ++static int const align_types[] = ++{ ++ ALIGNMENT_NONE, ++ ALIGNMENT_CYLINDER, ++ ALIGNMENT_MINIMAL, ++ ALIGNMENT_OPTIMAL ++}; ++ARGMATCH_VERIFY (align_args, align_types); + + typedef struct { + time_t last_update; +@@ -87,6 +113,7 @@ static struct option const options[] = { + {"machine", 0, NULL, 'm'}, + {"script", 0, NULL, 's'}, + {"version", 0, NULL, 'v'}, ++ {"align", required_argument, NULL, 'a'}, + {"-pretend-input-tty", 0, NULL, PRETEND_INPUT_TTY}, + {NULL, 0, NULL, 0} + }; +@@ -97,6 +124,7 @@ static const char *const options_help [] + {"machine", N_("displays machine parseable output")}, + {"script", N_("never prompts for user intervention")}, + {"version", N_("displays the version")}, ++ {"align=[none|cyl|min|opt]", N_("alignment for new partitions")}, + {NULL, NULL} + }; + +@@ -105,6 +133,7 @@ int pretend_input_tty = 0; + int opt_machine_mode = 0; + int disk_is_modified = 0; + int is_toggle_mode = 0; ++int alignment = ALIGNMENT_CYLINDER; + + static const char* number_msg = N_( + "NUMBER is the partition number used by Linux. On MS-DOS disk labels, the " +@@ -569,7 +598,7 @@ print_options_help () + int i; + + for (i=0; options_help [i][0]; i++) { +- printf (" -%c, --%-23.23s %s\n", ++ printf (" -%c, --%-25.25s %s\n", + options_help [i][0][0], + options_help [i][0], + _(options_help [i][1])); +@@ -700,6 +729,11 @@ do_mkpart (PedDevice** dev) + if (!disk) + goto error; + ++ if (ped_disk_is_flag_available(disk, PED_DISK_CYLINDER_ALIGNMENT)) ++ if (!ped_disk_set_flag(disk, PED_DISK_CYLINDER_ALIGNMENT, ++ alignment == ALIGNMENT_CYLINDER)) ++ goto error_destroy_disk; ++ + if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED)) { + part_type = PED_PARTITION_NORMAL; + } else { +@@ -752,7 +786,14 @@ do_mkpart (PedDevice** dev) + range_end); + PED_ASSERT (user_constraint != NULL, return 0); + +- dev_constraint = ped_device_get_constraint (*dev); ++ if (alignment == ALIGNMENT_OPTIMAL) ++ dev_constraint = ++ ped_device_get_optimal_aligned_constraint(*dev); ++ else if (alignment == ALIGNMENT_MINIMAL) ++ dev_constraint = ++ ped_device_get_minimal_aligned_constraint(*dev); ++ else ++ dev_constraint = ped_device_get_constraint(*dev); + PED_ASSERT (dev_constraint != NULL, return 0); + + final_constraint = ped_constraint_intersect (user_constraint, +@@ -2364,7 +2405,7 @@ int opt, help = 0, list = 0, version + + while (1) + { +- opt = getopt_long (*argc_ptr, *argv_ptr, "hlmsv", ++ opt = getopt_long (*argc_ptr, *argv_ptr, "hlmsva:", + options, NULL); + if (opt == -1) + break; +@@ -2375,16 +2416,22 @@ while (1) + case 'm': opt_machine_mode = 1; break; + case 's': opt_script_mode = 1; break; + case 'v': version = 1; break; ++ case 'a': ++ alignment = XARGMATCH ("--align", optarg, ++ align_args, align_types); ++ break; + case PRETEND_INPUT_TTY: + pretend_input_tty = 1; + break; +- default: wrong = 1; break; ++ default: ++ wrong = 1; ++ break; + } + } + + if (wrong == 1) { + fprintf (stderr, +- _("Usage: %s [-hlmsv] [DEVICE [COMMAND [PARAMETERS]]...]\n"), ++ _("Usage: %s [-hlmsv] [-a] [DEVICE [COMMAND [PARAMETERS]]...]\n"), + program_name); + return 0; + } diff --git a/parted.spec b/parted.spec index cb1a0f9..f4b7cc9 100644 --- a/parted.spec +++ b/parted.spec @@ -4,7 +4,7 @@ Summary: The GNU disk partition manipulation program Name: parted Version: 1.9.0 -Release: 23%{?dist} +Release: 24%{?dist} License: GPLv3+ Group: Applications/System URL: http://www.gnu.org/software/parted @@ -28,6 +28,14 @@ Patch17: %{name}-1.9.0-gpt-big-endian.patch Patch18: %{name}-1.9.0-export-alignment-info.patch Patch19: %{name}-1.9.0-dasd-fixes.patch Patch20: %{name}-1.9.0-dasd-533808.patch +Patch21: %{name}-1.9.0-lo-as-file-rh546622.patch +Patch22: %{name}-1.9.0-partition-limits-rh533417.patch +Patch23: %{name}-1.9.0-diskflags.patch +Patch24: %{name}-1.9.0-ui-align-rh361951.patch +Patch25: %{name}-1.9.0-align-default-rh361951.patch +Patch26: %{name}-1.9.0-entiredisk-rh533328.patch +Patch27: %{name}-1.9.0-ru-rh543029.patch +Patch28: %{name}-1.9.0-new-lvm-rh525095.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: e2fsprogs-devel @@ -84,6 +92,14 @@ Parted library, you need to install this package. %patch18 -p1 -b .export-align %patch19 -p1 -b .dasd %patch20 -p1 -b .dasd2 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 aclocal --force -I m4 autoconf --force autoheader --force @@ -149,6 +165,20 @@ fi %{_exec_prefix}/%{_lib}/pkgconfig/libparted.pc %changelog +* Fri Dec 18 2009 Hans de Goede 1.9.0-24 +- Allow partitioning of loopback devices (#546622) +- Add libparted function to query maximum partition length and start + addresses for a given disk (#533417) +- Add per disk flags functions from upstream, this is the way upstream + has implemented the disable cylinder alignment functionality +- Add --align cmdline option to specify how to align new partitions + see the parted man page for details (#361951) +- Make the default alignment for new partitions optimal (#361951) +- When cylinder alignment is disabled, allow use of the last (incomplete) + cylinder of the disk (#533328) +- Don't crash when printing partition tables in Russian (#543029) +- Make parted work correctly with new lvm (#525095) + * Wed Nov 11 2009 Hans de Goede 1.9.0-23 - Fix parted not building on s390