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

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