]>
Commit | Line | Data |
---|---|---|
c886eb9d AM |
1 | From a7d850a3b39b160dcc23e12491cb2cc7c056cd01 Mon Sep 17 00:00:00 2001 |
2 | From: "Brian C. Lane" <bcl@redhat.com> | |
3 | Date: Wed, 28 Oct 2015 11:57:22 -0700 | |
4 | Subject: [PATCH 35/36] parted: Display details of partition alignment failure | |
5 | (#726856) | |
6 | ||
7 | When alignment for a new partition fails it isn't always obvious why it | |
8 | failed. This adds printing the reason for the failure, in the form of: | |
9 | ||
10 | start % grain != offset | |
11 | ||
12 | This modifies align-check in interactive mode to print the alignment the | |
13 | error details if it isn't aligned. Script mode behavior is unchanged. | |
14 | ||
15 | Also cleanup pointer usage and handle asprintf failure by using a constant | |
16 | string in the error report - "unknown (malloc failure)". | |
17 | ||
18 | (cherry picked from commit 1726dbb4cd2dc4b19fe8d3c4b94e172fc0bd2c7c) | |
19 | --- | |
20 | parted/parted.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------------ | |
21 | 1 file changed, 51 insertions(+), 13 deletions(-) | |
22 | ||
23 | diff --git a/parted/parted.c b/parted/parted.c | |
24 | index 18b778c..06f9971 100644 | |
25 | --- a/parted/parted.c | |
26 | +++ b/parted/parted.c | |
27 | @@ -183,7 +183,8 @@ static TimerContext timer_context; | |
28 | static int _print_list (); | |
29 | static void _done (PedDevice* dev, PedDisk *diskp); | |
30 | static bool partition_align_check (PedDisk const *disk, | |
31 | - PedPartition const *part, enum AlignmentType a_type); | |
32 | + PedPartition const *part, enum AlignmentType a_type, | |
33 | + char **align_err); | |
34 | ||
35 | static void | |
36 | _timer_handler (PedTimer* timer, void* context) | |
37 | @@ -783,21 +784,27 @@ do_mkpart (PedDevice** dev, PedDisk** diskp) | |
38 | } | |
39 | } | |
40 | ||
41 | + char *align_err = NULL; | |
42 | if ((alignment == ALIGNMENT_OPTIMAL && | |
43 | - !partition_align_check(disk, part, PA_OPTIMUM)) || | |
44 | + !partition_align_check(disk, part, PA_OPTIMUM, &align_err)) || | |
45 | (alignment == ALIGNMENT_MINIMAL && | |
46 | - !partition_align_check(disk, part, PA_MINIMUM))) { | |
47 | + !partition_align_check(disk, part, PA_MINIMUM, &align_err))) { | |
48 | if (ped_exception_throw( | |
49 | PED_EXCEPTION_WARNING, | |
50 | (opt_script_mode | |
51 | ? PED_EXCEPTION_OK | |
52 | : PED_EXCEPTION_IGNORE_CANCEL), | |
53 | _("The resulting partition is not properly " | |
54 | - "aligned for best performance.")) == | |
55 | + "aligned for best performance: %s"), | |
56 | + align_err ? align_err : _("unknown (malloc failed)")) == | |
57 | PED_EXCEPTION_CANCEL) { | |
58 | + if (align_err) | |
59 | + free(align_err); | |
60 | /* undo partition addition */ | |
61 | goto error_remove_part; | |
62 | } | |
63 | + if (align_err) | |
64 | + free(align_err); | |
65 | } | |
66 | } else { | |
67 | ped_exception_leave_all(); | |
68 | @@ -1629,10 +1636,18 @@ do_select (PedDevice** dev, PedDisk** diskp) | |
69 | offset and alignment requirements. Also return true if there is | |
70 | insufficient kernel support to determine DISK's alignment requirements. | |
71 | Otherwise, return false. A_TYPE selects whether to check for minimal | |
72 | - or optimal alignment requirements. */ | |
73 | + or optimal alignment requirements. | |
74 | + | |
75 | + If align_err is not NULL a string describing why the check failed | |
76 | + will be allocated and returned. It is up to the caller to free this. | |
77 | + Pass NULL if no error description is needed. | |
78 | + | |
79 | + If allocating the error string fails *align_err will be set to NULL, the | |
80 | + caller should always check for this. | |
81 | +*/ | |
82 | static bool | |
83 | partition_align_check (PedDisk const *disk, PedPartition const *part, | |
84 | - enum AlignmentType a_type) | |
85 | + enum AlignmentType a_type, char **align_err) | |
86 | { | |
87 | PED_ASSERT (part->disk == disk); | |
88 | PedDevice const *dev = disk->dev; | |
89 | @@ -1641,10 +1656,20 @@ partition_align_check (PedDisk const *disk, PedPartition const *part, | |
90 | ? ped_device_get_minimum_alignment (dev) | |
91 | : ped_device_get_optimum_alignment (dev)); | |
92 | if (pa == NULL) | |
93 | - return true; | |
94 | + return true; | |
95 | ||
96 | PED_ASSERT (pa->grain_size != 0); | |
97 | bool ok = (part->geom.start % pa->grain_size == pa->offset); | |
98 | + | |
99 | + /* If it isn't aligned and the caller wants an explanation, | |
100 | + show them the math. */ | |
101 | + if (!ok && align_err) { | |
102 | + if (asprintf(align_err, | |
103 | + "%llds %% %llds != %llds", | |
104 | + part->geom.start, pa->grain_size, pa->offset) < 0) { | |
105 | + *align_err = NULL; | |
106 | + } | |
107 | + } | |
108 | free (pa); | |
109 | return ok; | |
110 | } | |
111 | @@ -1665,12 +1690,25 @@ do_align_check (PedDevice **dev, PedDisk** diskp) | |
112 | if (!command_line_get_partition (_("Partition number?"), *diskp, &part)) | |
113 | goto error; | |
114 | ||
115 | - bool aligned = partition_align_check (*diskp, part, align_type); | |
116 | - if (!opt_script_mode) | |
117 | - printf(aligned ? _("%d aligned\n") : _("%d not aligned\n"), part->num); | |
118 | - | |
119 | - if (opt_script_mode) | |
120 | - return aligned ? 1 : 0; | |
121 | + char *align_err = NULL; | |
122 | + bool aligned = partition_align_check (*diskp, part, align_type, &align_err); | |
123 | + | |
124 | + /* Don't print the error in script mode */ | |
125 | + if (opt_script_mode) { | |
126 | + if (align_err) | |
127 | + free(align_err); | |
128 | + return aligned ? 1 : 0; | |
129 | + } | |
130 | + | |
131 | + if (aligned) | |
132 | + printf(_("%d aligned\n"), part->num); | |
133 | + else | |
134 | + printf(_("%d not aligned: %s\n"), | |
135 | + part->num, | |
136 | + align_err ? align_err : _("unknown (malloc failed)")); | |
137 | + | |
138 | + if (align_err) | |
139 | + free(align_err); | |
140 | ||
141 | /* Always return 1 in interactive mode, to be consistent | |
142 | with the other modes. */ | |
143 | -- | |
144 | 2.5.5 | |
145 |