Merge lp:~trapnine/maas/fix-1513085 into lp:~maas-committers/maas/trunk
- fix-1513085
- Merge into trunk
Proposed by
Jeffrey C Jones
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Jeffrey C Jones | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 4504 | ||||
Proposed branch: | lp:~trapnine/maas/fix-1513085 | ||||
Merge into: | lp:~maas-committers/maas/trunk | ||||
Diff against target: |
1347 lines (+256/-192) 21 files modified
src/maasserver/api/tests/test_raid.py (+6/-12) src/maasserver/api/tests/test_volume_groups.py (+13/-4) src/maasserver/forms.py (+2/-1) src/maasserver/models/blockdevice.py (+1/-1) src/maasserver/models/partition.py (+7/-7) src/maasserver/models/partitiontable.py (+21/-17) src/maasserver/models/tests/test_blockdevice.py (+4/-2) src/maasserver/models/tests/test_filesystemgroup.py (+27/-33) src/maasserver/models/tests/test_partition.py (+9/-8) src/maasserver/models/tests/test_partitiontable.py (+27/-18) src/maasserver/models/virtualblockdevice.py (+21/-11) src/maasserver/testing/factory.py (+1/-3) src/maasserver/tests/test_forms_blockdevice.py (+5/-1) src/maasserver/tests/test_forms_partition.py (+5/-5) src/maasserver/tests/test_forms_raid.py (+5/-9) src/maasserver/tests/test_forms_volume_group.py (+7/-2) src/maasserver/tests/test_preseed_storage.py (+14/-14) src/maasserver/tests/test_storage_layouts.py (+43/-32) src/maasserver/utils/converters.py (+5/-3) src/maasserver/utils/tests/test_converters.py (+22/-6) src/maasserver/websockets/handlers/tests/test_node.py (+11/-3) |
||||
To merge this branch: | bzr merge lp:~trapnine/maas/fix-1513085 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Blake Rouse (community) | Approve | ||
Review via email: mp+277409@code.launchpad.net |
Commit message
Align partitions and logical volumes to 4MiB.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/maasserver/api/tests/test_raid.py' |
2 | --- src/maasserver/api/tests/test_raid.py 2015-10-28 17:32:43 +0000 |
3 | +++ src/maasserver/api/tests/test_raid.py 2015-11-16 07:08:21 +0000 |
4 | @@ -403,10 +403,8 @@ |
5 | (parsed_block_devices, parsed_partitions, |
6 | parsed_block_device_spares, parsed_partition_spares) = ( |
7 | get_devices_from_raid(parsed_device)) |
8 | - # Size is equivalent to 7 devices of 9 TB each. |
9 | - self.assertEqual( |
10 | - 7 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE), |
11 | - parsed_device['size']) |
12 | + # Size is equivalent to 7 of the smallest device (the partitions). |
13 | + self.assertEqual(7 * large_partitions[0].size, parsed_device['size']) |
14 | self.assertItemsEqual(block_devices, parsed_block_devices) |
15 | self.assertItemsEqual(partitions, parsed_partitions) |
16 | self.assertItemsEqual(spare_devices, parsed_block_device_spares) |
17 | @@ -450,10 +448,8 @@ |
18 | (parsed_block_devices, parsed_partitions, |
19 | parsed_block_device_spares, parsed_partition_spares) = ( |
20 | get_devices_from_raid(parsed_device)) |
21 | - # Size is equivalent to 6 devices of 9 TB each. |
22 | - self.assertEqual( |
23 | - 6 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE), |
24 | - parsed_device['size']) |
25 | + # Size is equivalent to 6 of the smallest device (the partitions). |
26 | + self.assertEqual(6 * large_partitions[0].size, parsed_device['size']) |
27 | self.assertItemsEqual(block_devices, parsed_block_devices) |
28 | self.assertItemsEqual(partitions, parsed_partitions) |
29 | self.assertItemsEqual(spare_devices, parsed_block_device_spares) |
30 | @@ -497,10 +493,8 @@ |
31 | (parsed_block_devices, parsed_partitions, |
32 | parsed_block_device_spares, parsed_partition_spares) = ( |
33 | get_devices_from_raid(parsed_device)) |
34 | - # Size is equivalent to 4 devices of 9 TB each. |
35 | - self.assertEqual( |
36 | - 4 * ((9 * 1000 ** 4) - PARTITION_TABLE_EXTRA_SPACE), |
37 | - parsed_device['size']) |
38 | + # Size is equivalent to 4 of the smallest device (the partitions). |
39 | + self.assertEqual(4 * large_partitions[0].size, parsed_device['size']) |
40 | self.assertItemsEqual(block_devices, parsed_block_devices) |
41 | self.assertItemsEqual(partitions, parsed_partitions) |
42 | self.assertItemsEqual(spare_devices, parsed_block_device_spares) |
43 | |
44 | === modified file 'src/maasserver/api/tests/test_volume_groups.py' |
45 | --- src/maasserver/api/tests/test_volume_groups.py 2015-09-24 16:22:12 +0000 |
46 | +++ src/maasserver/api/tests/test_volume_groups.py 2015-11-16 07:08:21 +0000 |
47 | @@ -26,11 +26,18 @@ |
48 | NODE_STATUS, |
49 | ) |
50 | from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
51 | +from maasserver.models.partition import ( |
52 | + MIN_PARTITION_SIZE, |
53 | + PARTITION_ALIGNMENT_SIZE, |
54 | +) |
55 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
56 | from maasserver.testing.api import APITestCase |
57 | from maasserver.testing.factory import factory |
58 | from maasserver.testing.orm import reload_object |
59 | -from maasserver.utils.converters import human_readable_bytes |
60 | +from maasserver.utils.converters import ( |
61 | + human_readable_bytes, |
62 | + round_size_to_nearest_block, |
63 | +) |
64 | from testtools.matchers import ( |
65 | ContainsDict, |
66 | Equals, |
67 | @@ -132,11 +139,11 @@ |
68 | ] |
69 | block_device = factory.make_PhysicalBlockDevice( |
70 | node=node, |
71 | - size=(MIN_BLOCK_DEVICE_SIZE * 3) + PARTITION_TABLE_EXTRA_SPACE) |
72 | + size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE) |
73 | partition_table = factory.make_PartitionTable( |
74 | block_device=block_device) |
75 | partitions = [ |
76 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
77 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
78 | for _ in range(2) |
79 | ] |
80 | partition_ids = [ |
81 | @@ -411,10 +418,12 @@ |
82 | }) |
83 | self.assertEqual(httplib.OK, response.status_code, response.content) |
84 | logical_volume = json.loads(response.content) |
85 | + expected_size = round_size_to_nearest_block( |
86 | + size, PARTITION_ALIGNMENT_SIZE, False) |
87 | self.assertThat(logical_volume, ContainsDict({ |
88 | "name": Equals("%s-%s" % (volume_group.name, name)), |
89 | "uuid": Equals(vguuid), |
90 | - "size": Equals(size), |
91 | + "size": Equals(expected_size), |
92 | })) |
93 | |
94 | def test_delete_logical_volume_204_when_invalid_id(self): |
95 | |
96 | === modified file 'src/maasserver/forms.py' |
97 | --- src/maasserver/forms.py 2015-11-02 16:32:29 +0000 |
98 | +++ src/maasserver/forms.py 2015-11-16 07:08:21 +0000 |
99 | @@ -154,6 +154,7 @@ |
100 | nodegroup_fqdn, |
101 | ) |
102 | from maasserver.models.nodegroup import NODEGROUP_CLUSTER_NAME_TEMPLATE |
103 | +from maasserver.models.partition import MIN_PARTITION_SIZE |
104 | from maasserver.models.subnet import ( |
105 | create_cidr, |
106 | Subnet, |
107 | @@ -3253,7 +3254,7 @@ |
108 | This needs to be done on the fly so that we can pass the maximum size. |
109 | """ |
110 | self.fields['size'] = BytesField( |
111 | - min_value=MIN_BLOCK_DEVICE_SIZE, |
112 | + min_value=MIN_PARTITION_SIZE, |
113 | max_value=self.block_device.size, |
114 | required=True) |
115 | |
116 | |
117 | === modified file 'src/maasserver/models/blockdevice.py' |
118 | --- src/maasserver/models/blockdevice.py 2015-10-28 01:59:30 +0000 |
119 | +++ src/maasserver/models/blockdevice.py 2015-11-16 07:08:21 +0000 |
120 | @@ -51,7 +51,7 @@ |
121 | ) |
122 | |
123 | |
124 | -MIN_BLOCK_DEVICE_SIZE = 2 * 1024 * 1024 # 2MiB |
125 | +MIN_BLOCK_DEVICE_SIZE = 4 * 1024 * 1024 # 4MiB |
126 | MIN_BLOCK_DEVICE_BLOCK_SIZE = 512 # A ProDOS block |
127 | |
128 | |
129 | |
130 | === modified file 'src/maasserver/models/partition.py' |
131 | --- src/maasserver/models/partition.py 2015-10-20 15:02:19 +0000 |
132 | +++ src/maasserver/models/partition.py 2015-11-16 07:08:21 +0000 |
133 | @@ -32,7 +32,6 @@ |
134 | from django.dispatch import receiver |
135 | from maasserver import DefaultMeta |
136 | from maasserver.enum import PARTITION_TABLE_TYPE |
137 | -from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
138 | from maasserver.models.cleansave import CleanSave |
139 | from maasserver.models.timestampedmodel import TimestampedModel |
140 | from maasserver.utils.converters import ( |
141 | @@ -45,8 +44,10 @@ |
142 | ) |
143 | |
144 | |
145 | -MIN_PARTITION_SIZE = MIN_BLOCK_DEVICE_SIZE |
146 | MAX_PARTITION_SIZE_FOR_MBR = (((2 ** 32) - 1) * 512) - (1024 ** 2) # 2 TiB |
147 | +# All partitions are aligned down to 4MiB blocks for performance (lp:1513085) |
148 | +PARTITION_ALIGNMENT_SIZE = 4 * 1024 * 1024 |
149 | +MIN_PARTITION_SIZE = PARTITION_ALIGNMENT_SIZE |
150 | |
151 | |
152 | class PartitionManager(Manager): |
153 | @@ -216,17 +217,16 @@ |
154 | bd=self.partition_table.block_device.__unicode__()) |
155 | |
156 | def _round_size(self): |
157 | - """Round the size of this partition to the nearest block.""" |
158 | + """Round the size of this partition down for alignment.""" |
159 | if self.size is not None and self.partition_table is not None: |
160 | self.size = round_size_to_nearest_block( |
161 | - self.size, self.partition_table.get_block_size()) |
162 | + self.size, PARTITION_ALIGNMENT_SIZE, False) |
163 | |
164 | @classmethod |
165 | def _get_mbr_max_for_block_device(self, block_device): |
166 | """Get the maximum partition size for MBR for this block device.""" |
167 | - block_size = block_device.block_size |
168 | - number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / block_size |
169 | - return block_size * (number_of_blocks - 1) |
170 | + return round_size_to_nearest_block( |
171 | + MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False) |
172 | |
173 | def _get_mbr_max_for_partition(self): |
174 | """Get the maximum partition size for MBR for this partition.""" |
175 | |
176 | === modified file 'src/maasserver/models/partitiontable.py' |
177 | --- src/maasserver/models/partitiontable.py 2015-11-04 04:27:46 +0000 |
178 | +++ src/maasserver/models/partitiontable.py 2015-11-16 07:08:21 +0000 |
179 | @@ -29,13 +29,17 @@ |
180 | ) |
181 | from maasserver.models.blockdevice import BlockDevice |
182 | from maasserver.models.cleansave import CleanSave |
183 | -from maasserver.models.partition import Partition |
184 | +from maasserver.models.partition import ( |
185 | + Partition, |
186 | + PARTITION_ALIGNMENT_SIZE, |
187 | +) |
188 | from maasserver.models.timestampedmodel import TimestampedModel |
189 | from maasserver.utils.converters import round_size_to_nearest_block |
190 | |
191 | -# The first partition on the disk must start at 2MiB, as all previous bytes |
192 | -# will be used by the partition table and grub. |
193 | -INITIAL_PARTITION_OFFSET = 2 * 1024 * 1024 |
194 | +# The first 2MiB of the device are used by the partition table and grub. We'll |
195 | +# reserve the first 4MiB to make sure all partitions stay aligned to 4MB across |
196 | +# the device. |
197 | +INITIAL_PARTITION_OFFSET = 4 * 1024 * 1024 |
198 | |
199 | # An additional 1MiB of space is left open at the end of the disk to allow for |
200 | # the extra MBR table. |
201 | @@ -67,11 +71,11 @@ |
202 | return self.block_device.node |
203 | |
204 | def get_size(self): |
205 | - """Size of partition table.""" |
206 | - return ( |
207 | - self.block_device.size - |
208 | - round_size_to_nearest_block( |
209 | - PARTITION_TABLE_EXTRA_SPACE, self.get_block_size())) |
210 | + """Total usable size of partition table.""" |
211 | + return round_size_to_nearest_block( |
212 | + self.block_device.size - PARTITION_TABLE_EXTRA_SPACE, |
213 | + PARTITION_ALIGNMENT_SIZE, |
214 | + False) |
215 | |
216 | def get_block_size(self): |
217 | """Block size of partition table.""" |
218 | @@ -89,15 +93,15 @@ |
219 | if used_size is None: |
220 | used_size = 0 |
221 | # The extra space taken by the partition table header is used space. |
222 | - used_size += round_size_to_nearest_block( |
223 | - PARTITION_TABLE_EXTRA_SPACE, self.get_block_size()) |
224 | - return round_size_to_nearest_block( |
225 | - used_size, self.get_block_size()) |
226 | + return used_size + PARTITION_TABLE_EXTRA_SPACE |
227 | |
228 | def get_available_size(self, ignore_partitions=[]): |
229 | """Return the remaining size available for partitions.""" |
230 | used_size = self.get_used_size(ignore_partitions=ignore_partitions) |
231 | - return self.block_device.size - used_size |
232 | + # Only report 'alignable' space as available for new partitions |
233 | + return round_size_to_nearest_block( |
234 | + self.block_device.size - used_size, |
235 | + PARTITION_ALIGNMENT_SIZE, False) |
236 | |
237 | def add_partition(self, size=None, bootable=False, uuid=None): |
238 | """Adds a partition to this partition table, returns the added |
239 | @@ -105,15 +109,15 @@ |
240 | |
241 | If size is omitted, the partition will extend to the end of the device. |
242 | |
243 | - If size is not a multiple of the device's block size, the size will be |
244 | - rounded up to the next multiple. |
245 | + All partition sizes will be aligned down to PARTITION_ALIGNMENT_SIZE. |
246 | """ |
247 | if size is None: |
248 | size = self.get_available_size() |
249 | if self.table_type == PARTITION_TABLE_TYPE.MBR: |
250 | size = min(size, Partition._get_mbr_max_for_block_device( |
251 | self.block_device)) |
252 | - size = round_size_to_nearest_block(size, self.get_block_size()) |
253 | + size = round_size_to_nearest_block( |
254 | + size, PARTITION_ALIGNMENT_SIZE, False) |
255 | return Partition.objects.create( |
256 | partition_table=self, size=size, uuid=uuid, bootable=bootable) |
257 | |
258 | |
259 | === modified file 'src/maasserver/models/tests/test_blockdevice.py' |
260 | --- src/maasserver/models/tests/test_blockdevice.py 2015-10-28 01:59:30 +0000 |
261 | +++ src/maasserver/models/tests/test_blockdevice.py 2015-11-16 07:08:21 +0000 |
262 | @@ -34,6 +34,7 @@ |
263 | VirtualBlockDevice, |
264 | VolumeGroup, |
265 | ) |
266 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
267 | from maasserver.testing.factory import factory |
268 | from maasserver.testing.orm import reload_object |
269 | from maasserver.testing.testcase import MAASServerTestCase |
270 | @@ -428,8 +429,9 @@ |
271 | boot_disk = factory.make_PhysicalBlockDevice(node=node) |
272 | partition = boot_disk.create_partition_if_boot_disk() |
273 | self.assertIsNotNone(partition) |
274 | - self.assertEquals( |
275 | - boot_disk.get_available_size(), 0, |
276 | + available_size = boot_disk.get_available_size() |
277 | + self.assertTrue( |
278 | + available_size >= 0 and available_size < PARTITION_ALIGNMENT_SIZE, |
279 | "Should create a partition for the entire disk.") |
280 | |
281 | |
282 | |
283 | === modified file 'src/maasserver/models/tests/test_filesystemgroup.py' |
284 | --- src/maasserver/models/tests/test_filesystemgroup.py 2015-11-10 16:55:24 +0000 |
285 | +++ src/maasserver/models/tests/test_filesystemgroup.py 2015-11-16 07:08:21 +0000 |
286 | @@ -43,6 +43,7 @@ |
287 | VolumeGroup, |
288 | VolumeGroupManager, |
289 | ) |
290 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
291 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
292 | from maasserver.models.physicalblockdevice import PhysicalBlockDevice |
293 | from maasserver.models.virtualblockdevice import VirtualBlockDevice |
294 | @@ -52,7 +53,10 @@ |
295 | reload_objects, |
296 | ) |
297 | from maasserver.testing.testcase import MAASServerTestCase |
298 | -from maasserver.utils.converters import machine_readable_bytes |
299 | +from maasserver.utils.converters import ( |
300 | + machine_readable_bytes, |
301 | + round_size_to_nearest_block, |
302 | +) |
303 | from maastesting.matchers import ( |
304 | MockCalledOnceWith, |
305 | MockNotCalled, |
306 | @@ -327,13 +331,16 @@ |
307 | [filesystem_group.id], result_filesystem_group_ids) |
308 | |
309 | def test__bcache_on_partitions(self): |
310 | - block_device = factory.make_PhysicalBlockDevice() |
311 | + device_size = random.randint( |
312 | + MIN_BLOCK_DEVICE_SIZE * 4, MIN_BLOCK_DEVICE_SIZE * 1024) |
313 | + block_device = factory.make_PhysicalBlockDevice( |
314 | + size=device_size + PARTITION_TABLE_EXTRA_SPACE) |
315 | partition_table = factory.make_PartitionTable( |
316 | block_device=block_device) |
317 | partition_one = factory.make_Partition( |
318 | - partition_table=partition_table) |
319 | + partition_table=partition_table, size=device_size / 2) |
320 | partition_two = factory.make_Partition( |
321 | - partition_table=partition_table) |
322 | + partition_table=partition_table, size=device_size / 2) |
323 | cache_set = factory.make_CacheSet(partition=partition_one) |
324 | filesystem_backing = factory.make_Filesystem( |
325 | fstype=FILESYSTEM_TYPE.BCACHE_BACKING, partition=partition_two) |
326 | @@ -1324,9 +1331,11 @@ |
327 | factory.make_VirtualBlockDevice( |
328 | filesystem_group=fsgroup, size=5 * 1000 ** 3) |
329 | |
330 | - self.assertEqual(40 * 1000 ** 3, fsgroup.get_lvm_allocated_size()) |
331 | + expected_size = round_size_to_nearest_block( |
332 | + 40 * 1000 ** 3, PARTITION_ALIGNMENT_SIZE, False) |
333 | + self.assertEqual(expected_size, fsgroup.get_lvm_allocated_size()) |
334 | self.assertEqual( |
335 | - usable_size - (40 * 1000 ** 3), fsgroup.get_lvm_free_space()) |
336 | + usable_size - expected_size, fsgroup.get_lvm_free_space()) |
337 | |
338 | def test_get_virtual_block_device_block_size_returns_backing_for_bc(self): |
339 | # This test is not included in the scenario below |
340 | @@ -1567,10 +1576,12 @@ |
341 | logical_volume = volume_group.create_logical_volume( |
342 | name=name, uuid=vguuid, size=size) |
343 | logical_volume = reload_object(logical_volume) |
344 | + expected_size = round_size_to_nearest_block( |
345 | + size, PARTITION_ALIGNMENT_SIZE, False) |
346 | self.assertThat(logical_volume, MatchesStructure.byEquality( |
347 | name=name, |
348 | uuid=vguuid, |
349 | - size=size, |
350 | + size=expected_size, |
351 | block_size=volume_group.get_virtual_block_device_block_size(), |
352 | )) |
353 | |
354 | @@ -1597,8 +1608,6 @@ |
355 | bd.get_partitiontable().add_partition() |
356 | for bd in block_devices[5:] |
357 | ] |
358 | - # Partition size will be smaller than the disk, because of overhead. |
359 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
360 | spare_block_device = block_devices[0] |
361 | spare_partition = partitions[0] |
362 | uuid = unicode(uuid4()) |
363 | @@ -1611,7 +1620,7 @@ |
364 | spare_devices=[spare_block_device], |
365 | spare_partitions=[spare_partition]) |
366 | self.assertEqual('md0', raid.name) |
367 | - self.assertEqual(6 * partition_size, raid.get_size()) |
368 | + self.assertEqual(6 * partitions[1].size, raid.get_size()) |
369 | self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type) |
370 | self.assertEqual(uuid, raid.uuid) |
371 | self.assertEqual(10, raid.filesystems.count()) |
372 | @@ -1689,7 +1698,6 @@ |
373 | for bd in block_devices[5:] |
374 | ] |
375 | # Partition size will be smaller than the disk, because of overhead. |
376 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
377 | spare_block_device = block_devices[0] |
378 | spare_partition = partitions[0] |
379 | uuid = unicode(uuid4()) |
380 | @@ -1702,7 +1710,7 @@ |
381 | spare_devices=[spare_block_device], |
382 | spare_partitions=[spare_partition]) |
383 | self.assertEqual('md0', raid.name) |
384 | - self.assertEqual(partition_size, raid.get_size()) |
385 | + self.assertEqual(partitions[1].size, raid.get_size()) |
386 | self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_1, raid.group_type) |
387 | self.assertEqual(uuid, raid.uuid) |
388 | self.assertEqual(10, raid.filesystems.count()) |
389 | @@ -1742,8 +1750,6 @@ |
390 | bd.get_partitiontable().add_partition() |
391 | for bd in block_devices[5:] |
392 | ] |
393 | - # Partition size will be smaller than the disk, because of overhead. |
394 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
395 | spare_block_device = block_devices[0] |
396 | spare_partition = partitions[0] |
397 | uuid = unicode(uuid4()) |
398 | @@ -1756,7 +1762,7 @@ |
399 | spare_devices=[spare_block_device], |
400 | spare_partitions=[spare_partition]) |
401 | self.assertEqual('md0', raid.name) |
402 | - self.assertEqual(7 * partition_size, raid.get_size()) |
403 | + self.assertEqual(7 * partitions[1].size, raid.get_size()) |
404 | self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_5, raid.group_type) |
405 | self.assertEqual(uuid, raid.uuid) |
406 | self.assertEqual(10, raid.filesystems.count()) |
407 | @@ -1906,11 +1912,9 @@ |
408 | partition = factory.make_PartitionTable( |
409 | block_device=factory.make_PhysicalBlockDevice( |
410 | node=node, size=device_size)).add_partition() |
411 | - # Partition size will be smaller than the disk, because of overhead. |
412 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
413 | raid.add_partition(partition, FILESYSTEM_TYPE.RAID) |
414 | self.assertEqual(11, raid.filesystems.count()) |
415 | - self.assertEqual(10 * partition_size, raid.get_size()) |
416 | + self.assertEqual(10 * partition.size, raid.get_size()) |
417 | |
418 | def test_add_spare_partition_to_array(self): |
419 | node = factory.make_Node() |
420 | @@ -1928,11 +1932,9 @@ |
421 | partition = factory.make_PartitionTable( |
422 | block_device=factory.make_PhysicalBlockDevice( |
423 | node=node, size=device_size)).add_partition() |
424 | - # Partition size will be smaller than the disk, because of overhead. |
425 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
426 | raid.add_partition(partition, FILESYSTEM_TYPE.RAID_SPARE) |
427 | self.assertEqual(11, raid.filesystems.count()) |
428 | - self.assertEqual(9 * partition_size, raid.get_size()) |
429 | + self.assertEqual(9 * partition.size, raid.get_size()) |
430 | |
431 | def test_add_device_from_another_node_to_array_fails(self): |
432 | node = factory.make_Node() |
433 | @@ -2054,8 +2056,6 @@ |
434 | node=node, size=device_size)).add_partition() |
435 | for _ in range(4) |
436 | ] |
437 | - # Partition size will be smaller than the disk, because of overhead. |
438 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
439 | uuid = unicode(uuid4()) |
440 | raid = RAID.objects.create_raid( |
441 | name='md0', |
442 | @@ -2070,7 +2070,7 @@ |
443 | "devices and any number of spares.']}")): |
444 | raid.remove_partition(partitions[0]) |
445 | self.assertEqual(4, raid.filesystems.count()) |
446 | - self.assertEqual(2 * partition_size, raid.get_size()) |
447 | + self.assertEqual(2 * partitions[0].size, raid.get_size()) |
448 | # Ensure the filesystems are the exact same before and after. |
449 | self.assertItemsEqual( |
450 | fsids_before, [fs.id for fs in raid.filesystems.all()]) |
451 | @@ -2102,8 +2102,6 @@ |
452 | node=node, size=device_size)).add_partition() |
453 | for _ in range(10) |
454 | ] |
455 | - # Partition size will be smaller than the disk, because of overhead. |
456 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
457 | uuid = unicode(uuid4()) |
458 | raid = RAID.objects.create_raid( |
459 | name='md0', |
460 | @@ -2113,7 +2111,7 @@ |
461 | spare_partitions=partitions[-2:]) |
462 | raid.remove_partition(partitions[0]) |
463 | self.assertEqual(9, raid.filesystems.count()) |
464 | - self.assertEqual(6 * partition_size, raid.get_size()) |
465 | + self.assertEqual(6 * partitions[0].size, raid.get_size()) |
466 | |
467 | def test_remove_invalid_partition_from_array_fails(self): |
468 | node = factory.make_Node(bios_boot_method="uefi") |
469 | @@ -2125,8 +2123,6 @@ |
470 | node=node, size=device_size)).add_partition() |
471 | for _ in range(10) |
472 | ] |
473 | - # Partition size will be smaller than the disk, because of overhead. |
474 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
475 | uuid = unicode(uuid4()) |
476 | raid = RAID.objects.create_raid( |
477 | name='md0', |
478 | @@ -2142,7 +2138,7 @@ |
479 | block_device=factory.make_PhysicalBlockDevice( |
480 | node=node, size=device_size)).add_partition()) |
481 | self.assertEqual(10, raid.filesystems.count()) |
482 | - self.assertEqual(9 * partition_size, raid.get_size()) |
483 | + self.assertEqual(9 * partitions[0].size, raid.get_size()) |
484 | |
485 | def test_remove_device_from_array_fails(self): |
486 | node = factory.make_Node() |
487 | @@ -2251,8 +2247,6 @@ |
488 | backing_partition = factory.make_PartitionTable( |
489 | block_device=factory.make_PhysicalBlockDevice( |
490 | node=node, size=backing_size)).add_partition() |
491 | - # Partition size will be smaller than the disk, because of overhead. |
492 | - partition_size = backing_size - PARTITION_TABLE_EXTRA_SPACE |
493 | uuid = unicode(uuid4()) |
494 | bcache = Bcache.objects.create_bcache( |
495 | name='bcache0', |
496 | @@ -2262,7 +2256,7 @@ |
497 | cache_mode=CACHE_MODE_TYPE.WRITEBACK) |
498 | |
499 | # Verify the filesystems were properly created on the target devices |
500 | - self.assertEqual(partition_size, bcache.get_size()) |
501 | + self.assertEqual(backing_partition.size, bcache.get_size()) |
502 | self.assertEqual( |
503 | FILESYSTEM_TYPE.BCACHE_CACHE, |
504 | cache_partition.get_effective_filesystem().fstype) |
505 | |
506 | === modified file 'src/maasserver/models/tests/test_partition.py' |
507 | --- src/maasserver/models/tests/test_partition.py 2015-11-04 19:39:51 +0000 |
508 | +++ src/maasserver/models/tests/test_partition.py 2015-11-16 07:08:21 +0000 |
509 | @@ -29,6 +29,7 @@ |
510 | from maasserver.models.partition import ( |
511 | MIN_PARTITION_SIZE, |
512 | Partition, |
513 | + PARTITION_ALIGNMENT_SIZE, |
514 | ) |
515 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
516 | from maasserver.testing.factory import factory |
517 | @@ -45,18 +46,18 @@ |
518 | node = factory.make_Node() |
519 | block_device = factory.make_PhysicalBlockDevice( |
520 | node=node, |
521 | - size=(MIN_BLOCK_DEVICE_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE) |
522 | + size=(MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE) |
523 | partition_table = factory.make_PartitionTable( |
524 | block_device=block_device) |
525 | free_partitions = [ |
526 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
527 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
528 | for _ in range(2) |
529 | ] |
530 | # Make used partitions. |
531 | for _ in range(2): |
532 | factory.make_Filesystem( |
533 | partition=partition_table.add_partition( |
534 | - size=MIN_BLOCK_DEVICE_SIZE)) |
535 | + size=MIN_PARTITION_SIZE)) |
536 | self.assertItemsEqual( |
537 | free_partitions, |
538 | Partition.objects.get_free_partitions_for_node(node)) |
539 | @@ -213,12 +214,12 @@ |
540 | partition.save() |
541 | self.assertEquals('%s' % uuid, partition.uuid) |
542 | |
543 | - def test_size_is_rounded_to_next_block(self): |
544 | + def test_size_is_rounded_to_current_block(self): |
545 | partition = factory.make_Partition() |
546 | - partition.size = partition.get_block_size() * 4096 |
547 | + partition.size = PARTITION_ALIGNMENT_SIZE * 4 |
548 | partition.size += 1 |
549 | partition.save() |
550 | - self.assertEquals(4097, partition.size / partition.get_block_size()) |
551 | + self.assertEquals(PARTITION_ALIGNMENT_SIZE * 4, partition.size) |
552 | |
553 | def test_validate_enough_space_for_new_partition(self): |
554 | partition_table = factory.make_PartitionTable() |
555 | @@ -235,7 +236,7 @@ |
556 | def test_validate_enough_space_for_resize_partition(self): |
557 | partition_table = factory.make_PartitionTable() |
558 | partition = partition_table.add_partition() |
559 | - partition.size += partition_table.get_block_size() * 2 |
560 | + partition.size += PARTITION_ALIGNMENT_SIZE * 2 |
561 | error = self.assertRaises(ValidationError, partition.save) |
562 | self.assertEquals({ |
563 | "size": [ |
564 | @@ -298,7 +299,7 @@ |
565 | node = factory.make_Node(bios_boot_method="uefi") |
566 | block_device = factory.make_PhysicalBlockDevice( |
567 | node=node, |
568 | - size=(MIN_BLOCK_DEVICE_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE) |
569 | + size=(MIN_PARTITION_SIZE * 4) + PARTITION_TABLE_EXTRA_SPACE) |
570 | partition_table = factory.make_PartitionTable( |
571 | block_device=block_device, table_type=PARTITION_TABLE_TYPE.GPT) |
572 | partitions = [ |
573 | |
574 | === modified file 'src/maasserver/models/tests/test_partitiontable.py' |
575 | --- src/maasserver/models/tests/test_partitiontable.py 2015-11-04 04:27:46 +0000 |
576 | +++ src/maasserver/models/tests/test_partitiontable.py 2015-11-16 07:08:21 +0000 |
577 | @@ -23,7 +23,11 @@ |
578 | BlockDevice, |
579 | MIN_BLOCK_DEVICE_SIZE, |
580 | ) |
581 | -from maasserver.models.partition import MAX_PARTITION_SIZE_FOR_MBR |
582 | +from maasserver.models.partition import ( |
583 | + MAX_PARTITION_SIZE_FOR_MBR, |
584 | + MIN_PARTITION_SIZE, |
585 | + PARTITION_ALIGNMENT_SIZE, |
586 | +) |
587 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
588 | from maasserver.testing.factory import factory |
589 | from maasserver.testing.testcase import MAASServerTestCase |
590 | @@ -41,7 +45,11 @@ |
591 | def test_get_size_returns_block_device_size_minus_initial_offset(self): |
592 | partition_table = factory.make_PartitionTable() |
593 | self.assertEquals( |
594 | - partition_table.block_device.size - PARTITION_TABLE_EXTRA_SPACE, |
595 | + round_size_to_nearest_block( |
596 | + partition_table.block_device.size - |
597 | + PARTITION_TABLE_EXTRA_SPACE, |
598 | + PARTITION_ALIGNMENT_SIZE, |
599 | + False), |
600 | partition_table.get_size()) |
601 | |
602 | def test_get_block_size_returns_block_device_block_size(self): |
603 | @@ -52,17 +60,17 @@ |
604 | |
605 | def test_add_misaligned_partition(self): |
606 | """Tests whether a partition size are adjusted according to |
607 | - device block size.""" |
608 | + partition alignment size (4MiB).""" |
609 | block_size = 4096 |
610 | device = factory.make_BlockDevice( |
611 | - size=MIN_BLOCK_DEVICE_SIZE * 2 + PARTITION_TABLE_EXTRA_SPACE, |
612 | + size=MIN_PARTITION_SIZE * 2 + PARTITION_TABLE_EXTRA_SPACE, |
613 | block_size=block_size) |
614 | partition_table = factory.make_PartitionTable(block_device=device) |
615 | partition = partition_table.add_partition( |
616 | - size=MIN_BLOCK_DEVICE_SIZE + 54) |
617 | + size=MIN_PARTITION_SIZE + 54) |
618 | self.assertEqual( |
619 | round_size_to_nearest_block( |
620 | - MIN_BLOCK_DEVICE_SIZE + 54, block_size), |
621 | + MIN_PARTITION_SIZE + 54, PARTITION_ALIGNMENT_SIZE, False), |
622 | partition.size) |
623 | |
624 | def test_add_partition_no_size(self): |
625 | @@ -85,9 +93,10 @@ |
626 | partition_table = factory.make_PartitionTable( |
627 | table_type=PARTITION_TABLE_TYPE.MBR, block_device=device) |
628 | partition = partition_table.add_partition() |
629 | - number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / block_size |
630 | self.assertEqual( |
631 | - partition.size, block_size * (number_of_blocks - 1)) |
632 | + round_size_to_nearest_block( |
633 | + MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False), |
634 | + partition.size) |
635 | |
636 | def test_add_second_partition_no_size(self): |
637 | """Tests whether a second partition with no specified size starts from |
638 | @@ -95,12 +104,12 @@ |
639 | device.""" |
640 | block_size = 4096 |
641 | device = factory.make_BlockDevice( |
642 | - size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
643 | + size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
644 | block_size=block_size) |
645 | partition_table = factory.make_PartitionTable(block_device=device) |
646 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
647 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
648 | partition = partition_table.add_partition() |
649 | - self.assertEqual(MIN_BLOCK_DEVICE_SIZE * 2, partition.size) |
650 | + self.assertEqual(MIN_PARTITION_SIZE * 2, partition.size) |
651 | |
652 | def test_add_partition_to_full_device(self): |
653 | """Tests whether we fail to add a partition to an already full device. |
654 | @@ -117,26 +126,26 @@ |
655 | def test_get_available_size(self): |
656 | block_size = 4096 |
657 | device = factory.make_BlockDevice( |
658 | - size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
659 | + size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
660 | block_size=block_size) |
661 | partition_table = factory.make_PartitionTable(block_device=device) |
662 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
663 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
664 | self.assertEquals( |
665 | - MIN_BLOCK_DEVICE_SIZE * 2, partition_table.get_available_size()) |
666 | + MIN_PARTITION_SIZE * 2, partition_table.get_available_size()) |
667 | |
668 | def test_get_available_size_skips_partitions(self): |
669 | block_size = 4096 |
670 | device = factory.make_BlockDevice( |
671 | - size=MIN_BLOCK_DEVICE_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
672 | + size=MIN_PARTITION_SIZE * 3 + PARTITION_TABLE_EXTRA_SPACE, |
673 | block_size=block_size) |
674 | partition_table = factory.make_PartitionTable(block_device=device) |
675 | ignore_partitions = [ |
676 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
677 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
678 | for _ in range(2) |
679 | ] |
680 | - partition_table.add_partition(size=MIN_BLOCK_DEVICE_SIZE) |
681 | + partition_table.add_partition(size=MIN_PARTITION_SIZE) |
682 | self.assertEquals( |
683 | - MIN_BLOCK_DEVICE_SIZE * 2, |
684 | + MIN_PARTITION_SIZE * 2, |
685 | partition_table.get_available_size( |
686 | ignore_partitions=ignore_partitions)) |
687 | |
688 | |
689 | === modified file 'src/maasserver/models/virtualblockdevice.py' |
690 | --- src/maasserver/models/virtualblockdevice.py 2015-08-14 13:48:59 +0000 |
691 | +++ src/maasserver/models/virtualblockdevice.py 2015-11-16 07:08:21 +0000 |
692 | @@ -30,7 +30,11 @@ |
693 | ) |
694 | from maasserver.models.filesystemgroup import FilesystemGroup |
695 | from maasserver.models.node import Node |
696 | -from maasserver.utils.converters import human_readable_bytes |
697 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
698 | +from maasserver.utils.converters import ( |
699 | + human_readable_bytes, |
700 | + round_size_to_nearest_block, |
701 | +) |
702 | from maasserver.utils.orm import get_one |
703 | |
704 | |
705 | @@ -109,16 +113,22 @@ |
706 | |
707 | # Check if the size of this is not larger than the free size of |
708 | # its filesystem group if its lvm. |
709 | - if (self.filesystem_group.is_lvm() and |
710 | - self.size > self.filesystem_group.get_lvm_free_space( |
711 | - skip_volumes=[self])): |
712 | - raise ValidationError( |
713 | - "There is not enough free space (%s) " |
714 | - "on volume group %s." % ( |
715 | - human_readable_bytes(self.size), |
716 | - self.filesystem_group.name, |
717 | - )) |
718 | - elif not self.filesystem_group.is_lvm(): |
719 | + if self.filesystem_group.is_lvm(): |
720 | + |
721 | + # align virtual partition to partition alignment size |
722 | + # otherwise on creation it may be rounded up, overfilling group |
723 | + self.size = round_size_to_nearest_block( |
724 | + self.size, PARTITION_ALIGNMENT_SIZE, False) |
725 | + |
726 | + if self.size > self.filesystem_group.get_lvm_free_space( |
727 | + skip_volumes=[self]): |
728 | + raise ValidationError( |
729 | + "There is not enough free space (%s) " |
730 | + "on volume group %s." % ( |
731 | + human_readable_bytes(self.size), |
732 | + self.filesystem_group.name, |
733 | + )) |
734 | + else: |
735 | # If not a volume group the size of the virtual block device |
736 | # must equal the size of the filesystem group. |
737 | assert self.size == self.filesystem_group.get_size() |
738 | |
739 | === modified file 'src/maasserver/testing/factory.py' |
740 | --- src/maasserver/testing/factory.py 2015-11-02 22:17:02 +0000 |
741 | +++ src/maasserver/testing/factory.py 2015-11-16 07:08:21 +0000 |
742 | @@ -1287,9 +1287,7 @@ |
743 | raise ValueError( |
744 | "Cannot make another partition on partition_table not " |
745 | "enough free space.") |
746 | - size = round_size_to_nearest_block( |
747 | - random.randint(MIN_PARTITION_SIZE, available_size), |
748 | - partition_table.get_block_size()) |
749 | + size = random.randint(MIN_PARTITION_SIZE, available_size) |
750 | if bootable is None: |
751 | bootable = random.choice([True, False]) |
752 | return Partition.objects.create( |
753 | |
754 | === modified file 'src/maasserver/tests/test_forms_blockdevice.py' |
755 | --- src/maasserver/tests/test_forms_blockdevice.py 2015-09-24 19:54:30 +0000 |
756 | +++ src/maasserver/tests/test_forms_blockdevice.py 2015-11-16 07:08:21 +0000 |
757 | @@ -31,9 +31,11 @@ |
758 | ) |
759 | from maasserver.models import Filesystem |
760 | from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
761 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
762 | from maasserver.testing.factory import factory |
763 | from maasserver.testing.orm import reload_object |
764 | from maasserver.testing.testcase import MAASServerTestCase |
765 | +from maasserver.utils.converters import round_size_to_nearest_block |
766 | from maasserver.utils.orm import get_one |
767 | from testtools.matchers import MatchesStructure |
768 | |
769 | @@ -379,8 +381,10 @@ |
770 | }) |
771 | self.assertTrue(form.is_valid(), form.errors) |
772 | block_device = form.save() |
773 | + expected_size = round_size_to_nearest_block( |
774 | + size, PARTITION_ALIGNMENT_SIZE, False) |
775 | self.assertThat(block_device, MatchesStructure.byEquality( |
776 | name=name, |
777 | uuid=vguuid, |
778 | - size=size, |
779 | + size=expected_size, |
780 | )) |
781 | |
782 | === modified file 'src/maasserver/tests/test_forms_partition.py' |
783 | --- src/maasserver/tests/test_forms_partition.py 2015-09-24 19:54:30 +0000 |
784 | +++ src/maasserver/tests/test_forms_partition.py 2015-11-16 07:08:21 +0000 |
785 | @@ -26,9 +26,11 @@ |
786 | ) |
787 | from maasserver.models import Filesystem |
788 | from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
789 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
790 | from maasserver.testing.factory import factory |
791 | from maasserver.testing.orm import reload_object |
792 | from maasserver.testing.testcase import MAASServerTestCase |
793 | +from maasserver.utils.converters import round_size_to_nearest_block |
794 | from maasserver.utils.orm import get_one |
795 | |
796 | |
797 | @@ -84,15 +86,13 @@ |
798 | form.is_valid(), |
799 | "Should be valid because size is large enough and a string.") |
800 | |
801 | - def test_size_rounded_up_and_placed_on_block_boundry(self): |
802 | + def test_size_rounded_down_and_placed_on_alignment_boundry(self): |
803 | block_size = 4096 |
804 | block_device = factory.make_PhysicalBlockDevice(block_size=block_size) |
805 | k_size = (MIN_BLOCK_DEVICE_SIZE / 1000) + 1 |
806 | size = "%sk" % k_size |
807 | - block_count = (k_size * 1000) / block_size |
808 | - if (k_size * 1000) % block_size > 0: |
809 | - block_count += 1 |
810 | - rounded_size = block_count * block_size |
811 | + rounded_size = round_size_to_nearest_block( |
812 | + k_size * 1000, PARTITION_ALIGNMENT_SIZE, False) |
813 | data = { |
814 | 'size': size, |
815 | } |
816 | |
817 | === modified file 'src/maasserver/tests/test_forms_raid.py' |
818 | --- src/maasserver/tests/test_forms_raid.py 2015-10-29 16:39:49 +0000 |
819 | +++ src/maasserver/tests/test_forms_raid.py 2015-11-16 07:08:21 +0000 |
820 | @@ -26,7 +26,6 @@ |
821 | UpdateRaidForm, |
822 | ) |
823 | from maasserver.models.filesystemgroup import RAID |
824 | -from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
825 | from maasserver.testing.factory import factory |
826 | from maasserver.testing.testcase import MAASServerTestCase |
827 | |
828 | @@ -126,12 +125,11 @@ |
829 | for bd in bds |
830 | if bd.get_partitiontable() is None |
831 | ] |
832 | - partitions = [ |
833 | - bd.get_partitiontable().add_partition().id |
834 | + partition_objs = [ |
835 | + bd.get_partitiontable().add_partition() |
836 | for bd in bds[5:] |
837 | ] |
838 | - # Partition size will be smaller than the disk, because of overhead. |
839 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
840 | + partitions = [partition.id for partition in partition_objs] |
841 | form = CreateRaidForm(node=node, data={ |
842 | 'name': 'md1', |
843 | 'level': FILESYSTEM_GROUP_TYPE.RAID_6, |
844 | @@ -141,7 +139,7 @@ |
845 | self.assertTrue(form.is_valid(), form.errors) |
846 | raid = form.save() |
847 | self.assertEqual('md1', raid.name) |
848 | - self.assertEqual(8 * partition_size, raid.get_size()) |
849 | + self.assertEqual(8 * partition_objs[0].size, raid.get_size()) |
850 | self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type) |
851 | self.assertItemsEqual( |
852 | block_devices, |
853 | @@ -183,8 +181,6 @@ |
854 | part.name |
855 | for part in partitions |
856 | ] |
857 | - # Partition size will be smaller than the disk, because of overhead. |
858 | - partition_size = device_size - PARTITION_TABLE_EXTRA_SPACE |
859 | form = CreateRaidForm(node=node, data={ |
860 | 'name': 'md1', |
861 | 'level': FILESYSTEM_GROUP_TYPE.RAID_6, |
862 | @@ -194,7 +190,7 @@ |
863 | self.assertTrue(form.is_valid(), form.errors) |
864 | raid = form.save() |
865 | self.assertEqual('md1', raid.name) |
866 | - self.assertEqual(8 * partition_size, raid.get_size()) |
867 | + self.assertEqual(8 * partitions[0].size, raid.get_size()) |
868 | self.assertEqual(FILESYSTEM_GROUP_TYPE.RAID_6, raid.group_type) |
869 | self.assertItemsEqual( |
870 | block_devices_ids, |
871 | |
872 | === modified file 'src/maasserver/tests/test_forms_volume_group.py' |
873 | --- src/maasserver/tests/test_forms_volume_group.py 2015-10-28 01:59:30 +0000 |
874 | +++ src/maasserver/tests/test_forms_volume_group.py 2015-11-16 07:08:21 +0000 |
875 | @@ -24,9 +24,11 @@ |
876 | UpdateVolumeGroupForm, |
877 | ) |
878 | from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
879 | +from maasserver.models.partition import PARTITION_ALIGNMENT_SIZE |
880 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
881 | from maasserver.testing.factory import factory |
882 | from maasserver.testing.testcase import MAASServerTestCase |
883 | +from maasserver.utils.converters import round_size_to_nearest_block |
884 | from testtools.matchers import MatchesStructure |
885 | |
886 | |
887 | @@ -512,9 +514,10 @@ |
888 | factory.make_name("lv"), |
889 | size=volume_group.get_size() - MIN_BLOCK_DEVICE_SIZE - 1) |
890 | name = factory.make_name("lv") |
891 | + free_space = volume_group.get_lvm_free_space() |
892 | data = { |
893 | 'name': name, |
894 | - 'size': MIN_BLOCK_DEVICE_SIZE + 2, |
895 | + 'size': free_space + 2, |
896 | } |
897 | form = CreateLogicalVolumeForm(volume_group, data=data) |
898 | self.assertFalse( |
899 | @@ -560,9 +563,11 @@ |
900 | form = CreateLogicalVolumeForm(volume_group, data=data) |
901 | self.assertTrue(form.is_valid(), form._errors) |
902 | logical_volume = form.save() |
903 | + expected_size = round_size_to_nearest_block( |
904 | + size, PARTITION_ALIGNMENT_SIZE, False) |
905 | self.assertThat( |
906 | logical_volume, MatchesStructure.byEquality( |
907 | name=name, |
908 | uuid=vguuid, |
909 | - size=size, |
910 | + size=expected_size, |
911 | )) |
912 | |
913 | === modified file 'src/maasserver/tests/test_preseed_storage.py' |
914 | --- src/maasserver/tests/test_preseed_storage.py 2015-11-04 04:27:46 +0000 |
915 | +++ src/maasserver/tests/test_preseed_storage.py 2015-11-16 07:08:21 +0000 |
916 | @@ -83,7 +83,7 @@ |
917 | size: 536870912B |
918 | device: sda |
919 | wipe: superblock |
920 | - offset: 2097152B |
921 | + offset: 4194304B |
922 | flag: boot |
923 | - id: sda-part2 |
924 | name: sda-part2 |
925 | @@ -99,7 +99,7 @@ |
926 | type: partition |
927 | number: 3 |
928 | uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf |
929 | - size: 6976176128B |
930 | + size: 6970933248B |
931 | wipe: superblock |
932 | device: sda |
933 | - id: sda-part1_format |
934 | @@ -195,7 +195,7 @@ |
935 | size: 536870912B |
936 | device: sda |
937 | wipe: superblock |
938 | - offset: 2097152B |
939 | + offset: 4194304B |
940 | flag: boot |
941 | - id: sda-part2 |
942 | name: sda-part2 |
943 | @@ -233,7 +233,7 @@ |
944 | type: partition |
945 | number: 6 |
946 | uuid: 8c365c80-900b-40a1-a8c7-1e445878d19a |
947 | - size: 2144337920B |
948 | + size: 2139095040B |
949 | device: sda |
950 | wipe: superblock |
951 | flag: logical |
952 | @@ -370,10 +370,10 @@ |
953 | type: partition |
954 | number: 1 |
955 | uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398 |
956 | - size: 8586788864B |
957 | + size: 8581545984B |
958 | device: sda |
959 | wipe: superblock |
960 | - offset: 2097152B |
961 | + offset: 4194304B |
962 | - id: sda-part1_format |
963 | type: format |
964 | fstype: ext4 |
965 | @@ -435,10 +435,10 @@ |
966 | type: partition |
967 | number: 1 |
968 | uuid: 6efc2c3d-bc9d-4ee5-a7ed-c6e1574d5398 |
969 | - size: 8586788864B |
970 | + size: 8581545984B |
971 | device: sda |
972 | wipe: superblock |
973 | - offset: 2097152B |
974 | + offset: 4194304B |
975 | - id: sda-part1_format |
976 | type: format |
977 | fstype: ext4 |
978 | @@ -548,7 +548,7 @@ |
979 | size: 536870912B |
980 | device: sda |
981 | wipe: superblock |
982 | - offset: 2097152B |
983 | + offset: 4194304B |
984 | flag: boot |
985 | - id: sda-part2 |
986 | name: sda-part2 |
987 | @@ -564,16 +564,16 @@ |
988 | type: partition |
989 | number: 3 |
990 | uuid: f74ff260-2a5b-4a36-b1b8-37f746b946bf |
991 | - size: 6976176128B |
992 | + size: 6970933248B |
993 | device: sda |
994 | wipe: superblock |
995 | - id: sdb-part1 |
996 | name: sdb-part1 |
997 | type: partition |
998 | number: 1 |
999 | - offset: 2097152B |
1000 | + offset: 4194304B |
1001 | uuid: f3281144-a0b6-46f1-90af-8541f97f7b1f |
1002 | - size: 2144337920B |
1003 | + size: 2139095040B |
1004 | wipe: superblock |
1005 | device: sdb |
1006 | - id: bcache0 |
1007 | @@ -610,9 +610,9 @@ |
1008 | name: md0-part1 |
1009 | type: partition |
1010 | number: 1 |
1011 | - offset: 2097152B |
1012 | + offset: 4194304B |
1013 | uuid: 18a6e885-3e6d-4505-8a0d-cf34df11a8b0 |
1014 | - size: 2199020109824B |
1015 | + size: 2199014866944B |
1016 | wipe: superblock |
1017 | device: md0 |
1018 | - id: sda-part1_format |
1019 | |
1020 | === modified file 'src/maasserver/tests/test_storage_layouts.py' |
1021 | --- src/maasserver/tests/test_storage_layouts.py 2015-10-27 20:53:16 +0000 |
1022 | +++ src/maasserver/tests/test_storage_layouts.py 2015-11-16 07:08:21 +0000 |
1023 | @@ -25,7 +25,10 @@ |
1024 | ) |
1025 | from maasserver.models.blockdevice import MIN_BLOCK_DEVICE_SIZE |
1026 | from maasserver.models.filesystemgroup import VolumeGroup |
1027 | -from maasserver.models.partition import MAX_PARTITION_SIZE_FOR_MBR |
1028 | +from maasserver.models.partition import ( |
1029 | + MAX_PARTITION_SIZE_FOR_MBR, |
1030 | + PARTITION_ALIGNMENT_SIZE, |
1031 | +) |
1032 | from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE |
1033 | from maasserver.storage_layouts import ( |
1034 | BcacheStorageLayout, |
1035 | @@ -46,6 +49,7 @@ |
1036 | ) |
1037 | from maasserver.testing.factory import factory |
1038 | from maasserver.testing.testcase import MAASServerTestCase |
1039 | +from maasserver.utils.converters import round_size_to_nearest_block |
1040 | from maastesting.matchers import MockCalledOnceWith |
1041 | from testtools.matchers import MatchesStructure |
1042 | |
1043 | @@ -53,13 +57,6 @@ |
1044 | LARGE_BLOCK_DEVICE = 10 * 1024 * 1024 * 1024 # 10 GiB |
1045 | |
1046 | |
1047 | -def round_size_by_blocks(size, block_size): |
1048 | - number_of_blocks = size / block_size |
1049 | - if size % block_size > 0: |
1050 | - number_of_blocks += 1 |
1051 | - return number_of_blocks * block_size |
1052 | - |
1053 | - |
1054 | def make_Node_with_uefi_boot_method(*args, **kwargs): |
1055 | kwargs['bios_boot_method'] = "uefi" |
1056 | kwargs['with_boot_disk'] = False |
1057 | @@ -435,7 +432,8 @@ |
1058 | def assertEFIPartition(self, partition, boot_disk): |
1059 | self.assertIsNotNone(partition) |
1060 | self.assertEquals( |
1061 | - round_size_by_blocks(EFI_PARTITION_SIZE, boot_disk.block_size), |
1062 | + round_size_to_nearest_block( |
1063 | + EFI_PARTITION_SIZE, boot_disk.block_size), |
1064 | partition.size) |
1065 | self.assertThat( |
1066 | partition.get_effective_filesystem(), MatchesStructure.byEquality( |
1067 | @@ -474,9 +472,10 @@ |
1068 | root_partition = partitions[0] |
1069 | self.assertIsNotNone(root_partition) |
1070 | self.assertEquals( |
1071 | - round_size_by_blocks( |
1072 | + round_size_to_nearest_block( |
1073 | boot_disk.size - PARTITION_TABLE_EXTRA_SPACE, |
1074 | - boot_disk.block_size), |
1075 | + PARTITION_ALIGNMENT_SIZE, |
1076 | + False), |
1077 | root_partition.size) |
1078 | self.assertThat( |
1079 | root_partition.get_effective_filesystem(), |
1080 | @@ -500,10 +499,12 @@ |
1081 | # Validate root partition. |
1082 | partitions = partition_table.partitions.order_by('id').all() |
1083 | root_partition = partitions[0] |
1084 | - number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / boot_disk.block_size |
1085 | self.assertIsNotNone(root_partition) |
1086 | self.assertEquals( |
1087 | - (boot_disk.block_size * (number_of_blocks - 1)), |
1088 | + round_size_to_nearest_block( |
1089 | + MAX_PARTITION_SIZE_FOR_MBR, |
1090 | + PARTITION_ALIGNMENT_SIZE, |
1091 | + False), |
1092 | root_partition.size) |
1093 | self.assertThat( |
1094 | root_partition.get_effective_filesystem(), |
1095 | @@ -533,10 +534,11 @@ |
1096 | root_partition = partitions[1] |
1097 | self.assertIsNotNone(root_partition) |
1098 | self.assertEquals( |
1099 | - round_size_by_blocks( |
1100 | + round_size_to_nearest_block( |
1101 | boot_disk.size - EFI_PARTITION_SIZE - |
1102 | PARTITION_TABLE_EXTRA_SPACE, |
1103 | - boot_disk.block_size), |
1104 | + PARTITION_ALIGNMENT_SIZE, |
1105 | + False), |
1106 | root_partition.size) |
1107 | self.assertThat( |
1108 | root_partition.get_effective_filesystem(), |
1109 | @@ -570,8 +572,8 @@ |
1110 | boot_partition = partitions[1] |
1111 | self.assertIsNotNone(boot_partition) |
1112 | self.assertEquals( |
1113 | - round_size_by_blocks( |
1114 | - boot_size, boot_disk.block_size), |
1115 | + round_size_to_nearest_block( |
1116 | + boot_size, PARTITION_ALIGNMENT_SIZE, False), |
1117 | boot_partition.size) |
1118 | self.assertThat( |
1119 | boot_partition.get_effective_filesystem(), |
1120 | @@ -585,10 +587,11 @@ |
1121 | root_partition = partitions[2] |
1122 | self.assertIsNotNone(root_partition) |
1123 | self.assertEquals( |
1124 | - round_size_by_blocks( |
1125 | + round_size_to_nearest_block( |
1126 | boot_disk.size - boot_partition.size - |
1127 | EFI_PARTITION_SIZE - PARTITION_TABLE_EXTRA_SPACE, |
1128 | - boot_disk.block_size), |
1129 | + PARTITION_ALIGNMENT_SIZE, |
1130 | + False), |
1131 | root_partition.size) |
1132 | self.assertThat( |
1133 | root_partition.get_effective_filesystem(), |
1134 | @@ -622,7 +625,8 @@ |
1135 | root_partition = partitions[1] |
1136 | self.assertIsNotNone(root_partition) |
1137 | self.assertEquals( |
1138 | - round_size_by_blocks(root_size, boot_disk.block_size), |
1139 | + round_size_to_nearest_block( |
1140 | + root_size, PARTITION_ALIGNMENT_SIZE, False), |
1141 | root_partition.size) |
1142 | self.assertThat( |
1143 | root_partition.get_effective_filesystem(), |
1144 | @@ -659,8 +663,8 @@ |
1145 | boot_partition = partitions[1] |
1146 | self.assertIsNotNone(boot_partition) |
1147 | self.assertEquals( |
1148 | - round_size_by_blocks( |
1149 | - boot_size, boot_disk.block_size), |
1150 | + round_size_to_nearest_block( |
1151 | + boot_size, PARTITION_ALIGNMENT_SIZE, False), |
1152 | boot_partition.size) |
1153 | self.assertThat( |
1154 | boot_partition.get_effective_filesystem(), |
1155 | @@ -674,7 +678,8 @@ |
1156 | root_partition = partitions[2] |
1157 | self.assertIsNotNone(root_partition) |
1158 | self.assertEquals( |
1159 | - round_size_by_blocks(root_size, boot_disk.block_size), |
1160 | + round_size_to_nearest_block( |
1161 | + root_size, PARTITION_ALIGNMENT_SIZE, False), |
1162 | root_partition.size) |
1163 | self.assertThat( |
1164 | root_partition.get_effective_filesystem(), |
1165 | @@ -716,7 +721,8 @@ |
1166 | 'id').all()[0] |
1167 | self.assertIsNotNone(root_partition) |
1168 | self.assertEquals( |
1169 | - round_size_by_blocks(root_size, root_device.block_size), |
1170 | + round_size_to_nearest_block( |
1171 | + root_size, PARTITION_ALIGNMENT_SIZE, False), |
1172 | root_partition.size) |
1173 | self.assertThat( |
1174 | root_partition.get_effective_filesystem(), |
1175 | @@ -980,7 +986,9 @@ |
1176 | 1, volume_group.virtual_devices.count(), |
1177 | "Should have only 1 logical volume.") |
1178 | logical_volume = volume_group.virtual_devices.first() |
1179 | - self.assertEquals(lv_size, logical_volume.size) |
1180 | + expected_size = round_size_to_nearest_block( |
1181 | + lv_size, PARTITION_ALIGNMENT_SIZE, False) |
1182 | + self.assertEquals(expected_size, logical_volume.size) |
1183 | self.assertEquals(layout.DEFAULT_LV_NAME, logical_volume.name) |
1184 | self.assertThat( |
1185 | logical_volume.get_effective_filesystem(), |
1186 | @@ -1003,14 +1011,13 @@ |
1187 | root_partition = partitions[0] |
1188 | volume_group = VolumeGroup.objects.get( |
1189 | filesystems__partition=root_partition) |
1190 | - number_of_blocks = MAX_PARTITION_SIZE_FOR_MBR / boot_disk.block_size |
1191 | self.assertIsNotNone(volume_group) |
1192 | self.assertEquals( |
1193 | 4, partition_table.partitions.count(), |
1194 | "Should have 4 partitions.") |
1195 | - self.assertEquals( |
1196 | - boot_disk.block_size * (number_of_blocks - 1), |
1197 | - root_partition.size) |
1198 | + expected_size = round_size_to_nearest_block( |
1199 | + MAX_PARTITION_SIZE_FOR_MBR, PARTITION_ALIGNMENT_SIZE, False) |
1200 | + self.assertEquals(expected_size, root_partition.size) |
1201 | |
1202 | |
1203 | class TestBcacheStorageLayoutBase(MAASServerTestCase): |
1204 | @@ -1185,7 +1192,7 @@ |
1205 | ssd = factory.make_PhysicalBlockDevice( |
1206 | node=node, size=5 * 1024 * 1024 * 1024, block_size=4096, |
1207 | tags=['ssd']) |
1208 | - cache_size = round_size_by_blocks( |
1209 | + cache_size = round_size_to_nearest_block( |
1210 | random.randint( |
1211 | 3 * 1024 * 1024 * 1024, 5 * 1024 * 1024 * 1024), |
1212 | 4096) |
1213 | @@ -1200,7 +1207,10 @@ |
1214 | self.assertIsNotNone(partition_table) |
1215 | partition = partition_table.partitions.order_by('id').all()[0] |
1216 | self.assertEquals(partition, cache_device) |
1217 | - self.assertEquals(cache_size, partition.size) |
1218 | + self.assertEquals( |
1219 | + round_size_to_nearest_block( |
1220 | + cache_size, PARTITION_ALIGNMENT_SIZE, False), |
1221 | + partition.size) |
1222 | |
1223 | def test_raises_error_when_invalid_cache_device(self): |
1224 | node = make_Node_with_uefi_boot_method() |
1225 | @@ -1234,7 +1244,8 @@ |
1226 | "Cannot use cache_size and cache_no_part at the same time."], |
1227 | "cache_no_part": [ |
1228 | "Cannot use cache_size and cache_no_part at the same time."], |
1229 | - }, layout.errors) |
1230 | + }, |
1231 | + layout.errors) |
1232 | |
1233 | def test_raises_error_when_precentage_to_low_for_cache_size(self): |
1234 | node = make_Node_with_uefi_boot_method() |
1235 | |
1236 | === modified file 'src/maasserver/utils/converters.py' |
1237 | --- src/maasserver/utils/converters.py 2015-10-11 00:26:09 +0000 |
1238 | +++ src/maasserver/utils/converters.py 2015-11-16 07:08:21 +0000 |
1239 | @@ -100,12 +100,14 @@ |
1240 | return int(humanized) |
1241 | |
1242 | |
1243 | -def round_size_to_nearest_block(size, block_size): |
1244 | +def round_size_to_nearest_block(size, block_size, round_up=True): |
1245 | """Round the size to the nearest block returning the new size. |
1246 | |
1247 | - :param round_up: Round the size to fill an entire block. |
1248 | + :param size: The requested size to round. |
1249 | + :param block_size: The block size to round to. |
1250 | + :param round_up: If True, will round up to fill current block, else down. |
1251 | """ |
1252 | number_of_blocks = size / block_size |
1253 | - if size % block_size > 0: |
1254 | + if round_up and size % block_size > 0: |
1255 | number_of_blocks += 1 |
1256 | return block_size * number_of_blocks |
1257 | |
1258 | === modified file 'src/maasserver/utils/tests/test_converters.py' |
1259 | --- src/maasserver/utils/tests/test_converters.py 2015-08-14 13:48:59 +0000 |
1260 | +++ src/maasserver/utils/tests/test_converters.py 2015-11-16 07:08:21 +0000 |
1261 | @@ -114,18 +114,34 @@ |
1262 | |
1263 | class TestRoundSizeToNearestBlock(MAASTestCase): |
1264 | |
1265 | - def test__adds_extra_block(self): |
1266 | + def test__round_up_adds_extra_block(self): |
1267 | block_size = 4096 |
1268 | size = block_size + 1 |
1269 | self.assertEquals( |
1270 | 2 * block_size, |
1271 | - round_size_to_nearest_block(size, block_size), |
1272 | - "Should add another block to the size.") |
1273 | + round_size_to_nearest_block(size, block_size, True), |
1274 | + "Should add an extra block to the size.") |
1275 | |
1276 | - def test__doesnt_add_extra_block(self): |
1277 | + def test__round_up_doesnt_add_extra_block(self): |
1278 | block_size = 4096 |
1279 | size = block_size |
1280 | self.assertEquals( |
1281 | size, |
1282 | - round_size_to_nearest_block(size, block_size), |
1283 | - "Shouldn't add another block to the size.") |
1284 | + round_size_to_nearest_block(size, block_size, True), |
1285 | + "Shouldn't add an extra block to the size.") |
1286 | + |
1287 | + def test__round_down_removes_block(self): |
1288 | + block_size = 4096 |
1289 | + size = block_size + 1 |
1290 | + self.assertEquals( |
1291 | + 1 * block_size, |
1292 | + round_size_to_nearest_block(size, block_size, False), |
1293 | + "Should remove block from the size.") |
1294 | + |
1295 | + def test__round_down_doesnt_remove_block(self): |
1296 | + block_size = 4096 |
1297 | + size = block_size * 2 |
1298 | + self.assertEquals( |
1299 | + size, |
1300 | + round_size_to_nearest_block(size, block_size, False), |
1301 | + "Shouldn't remove a block from the size.") |
1302 | |
1303 | === modified file 'src/maasserver/websockets/handlers/tests/test_node.py' |
1304 | --- src/maasserver/websockets/handlers/tests/test_node.py 2015-11-10 23:41:49 +0000 |
1305 | +++ src/maasserver/websockets/handlers/tests/test_node.py 2015-11-16 07:08:21 +0000 |
1306 | @@ -48,7 +48,10 @@ |
1307 | from maasserver.models.interface import Interface |
1308 | from maasserver.models.node import Node |
1309 | from maasserver.models.nodeprobeddetails import get_single_probed_details |
1310 | -from maasserver.models.partition import Partition |
1311 | +from maasserver.models.partition import ( |
1312 | + Partition, |
1313 | + PARTITION_ALIGNMENT_SIZE, |
1314 | +) |
1315 | from maasserver.node_action import compile_node_actions |
1316 | from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture |
1317 | from maasserver.testing.architecture import make_usable_architecture |
1318 | @@ -66,6 +69,7 @@ |
1319 | from maasserver.third_party_drivers import get_third_party_driver |
1320 | from maasserver.utils.converters import ( |
1321 | human_readable_bytes, |
1322 | + round_size_to_nearest_block, |
1323 | XMLToYAML, |
1324 | ) |
1325 | from maasserver.utils.orm import ( |
1326 | @@ -1477,7 +1481,9 @@ |
1327 | self.assertEquals( |
1328 | 1, Partition.objects.count()) |
1329 | self.assertEquals( |
1330 | - human_readable_bytes(size), |
1331 | + human_readable_bytes( |
1332 | + round_size_to_nearest_block( |
1333 | + size, PARTITION_ALIGNMENT_SIZE, False)), |
1334 | human_readable_bytes(Partition.objects.first().size)) |
1335 | |
1336 | def test_create_partition_with_filesystem(self): |
1337 | @@ -1502,7 +1508,9 @@ |
1338 | self.assertEquals( |
1339 | 1, Partition.objects.count()) |
1340 | self.assertEquals( |
1341 | - human_readable_bytes(size), |
1342 | + human_readable_bytes( |
1343 | + round_size_to_nearest_block( |
1344 | + size, PARTITION_ALIGNMENT_SIZE, False)), |
1345 | human_readable_bytes(Partition.objects.first().size)) |
1346 | self.assertEquals( |
1347 | fstype, |
Looks really good. Good work. Please backport his change as well. Let me know if you need help with this.