- 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)
This commit is contained in:
Hans de Goede 2009-12-18 09:42:14 +00:00
parent 24837182b5
commit ce6563fae4
9 changed files with 1491 additions and 1 deletions

View File

@ -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 "

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

View File

@ -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 (&params, "%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 (&params, "%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;

View File

@ -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 <bug-gnu-gperf@gnu.org>."
+#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

View File

@ -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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>. */
+
+/* Written by David MacKenzie <djm@ai.mit.edu>
+ Modified by Akim Demaille <demaille@inf.enst.fr> */
+
+#include <config.h>
+
+/* Specification. */
+#include "argmatch.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 <djm@gnu.ai.mit.edu>
+ */
+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 <http://www.gnu.org/licenses/>. */
+
+/* Written by David MacKenzie <djm@ai.mit.edu>
+ Modified by Akim Demaille <demaille@inf.enst.fr> */
+
+#ifndef ARGMATCH_H_
+# define ARGMATCH_H_ 1
+
+# include <stddef.h>
+
+# 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 <config.h>
#include <stdbool.h>
+#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<align>] [DEVICE [COMMAND [PARAMETERS]]...]\n"),
program_name);
return 0;
}

View File

@ -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 <hdegoede@redhat.com> 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 <hdegoede@redhat.com> 1.9.0-23
- Fix parted not building on s390