Blame SOURCES/0035-parted-Display-details-of-partition-alignment-failur.patch

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