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

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