146 lines
5.6 KiB
Diff
146 lines
5.6 KiB
Diff
|
From a7d850a3b39b160dcc23e12491cb2cc7c056cd01 Mon Sep 17 00:00:00 2001
|
||
|
From: "Brian C. Lane" <bcl@redhat.com>
|
||
|
Date: Wed, 28 Oct 2015 11:57:22 -0700
|
||
|
Subject: [PATCH 35/36] parted: Display details of partition alignment failure
|
||
|
(#726856)
|
||
|
|
||
|
When alignment for a new partition fails it isn't always obvious why it
|
||
|
failed. This adds printing the reason for the failure, in the form of:
|
||
|
|
||
|
start % grain != offset
|
||
|
|
||
|
This modifies align-check in interactive mode to print the alignment the
|
||
|
error details if it isn't aligned. Script mode behavior is unchanged.
|
||
|
|
||
|
Also cleanup pointer usage and handle asprintf failure by using a constant
|
||
|
string in the error report - "unknown (malloc failure)".
|
||
|
|
||
|
(cherry picked from commit 1726dbb4cd2dc4b19fe8d3c4b94e172fc0bd2c7c)
|
||
|
---
|
||
|
parted/parted.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------------
|
||
|
1 file changed, 51 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/parted/parted.c b/parted/parted.c
|
||
|
index 18b778c..06f9971 100644
|
||
|
--- a/parted/parted.c
|
||
|
+++ b/parted/parted.c
|
||
|
@@ -183,7 +183,8 @@ static TimerContext timer_context;
|
||
|
static int _print_list ();
|
||
|
static void _done (PedDevice* dev, PedDisk *diskp);
|
||
|
static bool partition_align_check (PedDisk const *disk,
|
||
|
- PedPartition const *part, enum AlignmentType a_type);
|
||
|
+ PedPartition const *part, enum AlignmentType a_type,
|
||
|
+ char **align_err);
|
||
|
|
||
|
static void
|
||
|
_timer_handler (PedTimer* timer, void* context)
|
||
|
@@ -783,21 +784,27 @@ do_mkpart (PedDevice** dev, PedDisk** diskp)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+ char *align_err = NULL;
|
||
|
if ((alignment == ALIGNMENT_OPTIMAL &&
|
||
|
- !partition_align_check(disk, part, PA_OPTIMUM)) ||
|
||
|
+ !partition_align_check(disk, part, PA_OPTIMUM, &align_err)) ||
|
||
|
(alignment == ALIGNMENT_MINIMAL &&
|
||
|
- !partition_align_check(disk, part, PA_MINIMUM))) {
|
||
|
+ !partition_align_check(disk, part, PA_MINIMUM, &align_err))) {
|
||
|
if (ped_exception_throw(
|
||
|
PED_EXCEPTION_WARNING,
|
||
|
(opt_script_mode
|
||
|
? PED_EXCEPTION_OK
|
||
|
: PED_EXCEPTION_IGNORE_CANCEL),
|
||
|
_("The resulting partition is not properly "
|
||
|
- "aligned for best performance.")) ==
|
||
|
+ "aligned for best performance: %s"),
|
||
|
+ align_err ? align_err : _("unknown (malloc failed)")) ==
|
||
|
PED_EXCEPTION_CANCEL) {
|
||
|
+ if (align_err)
|
||
|
+ free(align_err);
|
||
|
/* undo partition addition */
|
||
|
goto error_remove_part;
|
||
|
}
|
||
|
+ if (align_err)
|
||
|
+ free(align_err);
|
||
|
}
|
||
|
} else {
|
||
|
ped_exception_leave_all();
|
||
|
@@ -1629,10 +1636,18 @@ do_select (PedDevice** dev, PedDisk** diskp)
|
||
|
offset and alignment requirements. Also return true if there is
|
||
|
insufficient kernel support to determine DISK's alignment requirements.
|
||
|
Otherwise, return false. A_TYPE selects whether to check for minimal
|
||
|
- or optimal alignment requirements. */
|
||
|
+ or optimal alignment requirements.
|
||
|
+
|
||
|
+ If align_err is not NULL a string describing why the check failed
|
||
|
+ will be allocated and returned. It is up to the caller to free this.
|
||
|
+ Pass NULL if no error description is needed.
|
||
|
+
|
||
|
+ If allocating the error string fails *align_err will be set to NULL, the
|
||
|
+ caller should always check for this.
|
||
|
+*/
|
||
|
static bool
|
||
|
partition_align_check (PedDisk const *disk, PedPartition const *part,
|
||
|
- enum AlignmentType a_type)
|
||
|
+ enum AlignmentType a_type, char **align_err)
|
||
|
{
|
||
|
PED_ASSERT (part->disk == disk);
|
||
|
PedDevice const *dev = disk->dev;
|
||
|
@@ -1641,10 +1656,20 @@ partition_align_check (PedDisk const *disk, PedPartition const *part,
|
||
|
? ped_device_get_minimum_alignment (dev)
|
||
|
: ped_device_get_optimum_alignment (dev));
|
||
|
if (pa == NULL)
|
||
|
- return true;
|
||
|
+ return true;
|
||
|
|
||
|
PED_ASSERT (pa->grain_size != 0);
|
||
|
bool ok = (part->geom.start % pa->grain_size == pa->offset);
|
||
|
+
|
||
|
+ /* If it isn't aligned and the caller wants an explanation,
|
||
|
+ show them the math. */
|
||
|
+ if (!ok && align_err) {
|
||
|
+ if (asprintf(align_err,
|
||
|
+ "%llds %% %llds != %llds",
|
||
|
+ part->geom.start, pa->grain_size, pa->offset) < 0) {
|
||
|
+ *align_err = NULL;
|
||
|
+ }
|
||
|
+ }
|
||
|
free (pa);
|
||
|
return ok;
|
||
|
}
|
||
|
@@ -1665,12 +1690,25 @@ do_align_check (PedDevice **dev, PedDisk** diskp)
|
||
|
if (!command_line_get_partition (_("Partition number?"), *diskp, &part))
|
||
|
goto error;
|
||
|
|
||
|
- bool aligned = partition_align_check (*diskp, part, align_type);
|
||
|
- if (!opt_script_mode)
|
||
|
- printf(aligned ? _("%d aligned\n") : _("%d not aligned\n"), part->num);
|
||
|
-
|
||
|
- if (opt_script_mode)
|
||
|
- return aligned ? 1 : 0;
|
||
|
+ char *align_err = NULL;
|
||
|
+ bool aligned = partition_align_check (*diskp, part, align_type, &align_err);
|
||
|
+
|
||
|
+ /* Don't print the error in script mode */
|
||
|
+ if (opt_script_mode) {
|
||
|
+ if (align_err)
|
||
|
+ free(align_err);
|
||
|
+ return aligned ? 1 : 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (aligned)
|
||
|
+ printf(_("%d aligned\n"), part->num);
|
||
|
+ else
|
||
|
+ printf(_("%d not aligned: %s\n"),
|
||
|
+ part->num,
|
||
|
+ align_err ? align_err : _("unknown (malloc failed)"));
|
||
|
+
|
||
|
+ if (align_err)
|
||
|
+ free(align_err);
|
||
|
|
||
|
/* Always return 1 in interactive mode, to be consistent
|
||
|
with the other modes. */
|
||
|
--
|
||
|
2.5.5
|
||
|
|