From patchwork Wed Jun 13 14:04:12 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Milo Casagrande X-Patchwork-Id: 9271 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A947423DEB for ; Wed, 13 Jun 2012 14:04:26 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 5A3B9A186F6 for ; Wed, 13 Jun 2012 14:04:26 +0000 (UTC) Received: by yenq6 with SMTP id q6so553186yen.11 for ; Wed, 13 Jun 2012 07:04:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=ul2jTL6TARmMjTBiKAWib5sOX2nDb/QFFMSwq2XcCiE=; b=SGJB/nJnMt46qSS0cCCO566YUFws8Uf0xj4xX7YoBr4Z4y8AJpIFMfuK3GcAuMolE8 g8wzi+PsoPNBNTY7WiFziJ4CYgDJKYPICWjyl2SLjBVq5VRicmCo+TOAfuat45TLui2i XBMqiGtBTu2nmfRAwzC2kR5lf6HjcfniqNt/RnZ+VfJJIGFH1dVqp2mUdNnehO9+AYVN hnaoDfJkVXxZ6qxKuglP433yNBIzqIg7HBdiVsjBxL24gRjJ3z6wrdId7LHLGHgW6ec8 07hbBFHj3l5T6vDH7N+E8k7Ul8hRxbfgikrOPuxUllgsr6kNd2iQOD/dlmObq6xpJ5UZ D0UA== Received: by 10.50.193.196 with SMTP id hq4mr10488945igc.57.1339596265556; Wed, 13 Jun 2012 07:04:25 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp23830ibb; Wed, 13 Jun 2012 07:04:24 -0700 (PDT) Received: by 10.180.101.103 with SMTP id ff7mr38159314wib.6.1339596263531; Wed, 13 Jun 2012 07:04:23 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id l4si10765120wiy.7.2012.06.13.07.04.23 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 13 Jun 2012 07:04:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1SeoBK-0000Qc-Sb for ; Wed, 13 Jun 2012 14:04:22 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id AA072E013A for ; Wed, 13 Jun 2012 14:04:12 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: linaro-image-tools X-Launchpad-Branch: ~linaro-image-tools/linaro-image-tools/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 525 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-image-tools/linaro-image-tools/trunk] Rev 525: [merge] Merged fixes for bug 1004199. Message-Id: <20120613140412.10955.58443.launchpad@ackee.canonical.com> Date: Wed, 13 Jun 2012 14:04:12 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15389"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 15b961336e80368536b697a2986d6765d5ffb600 X-Gm-Message-State: ALoCoQkTrRkHwPBhh13+72WfFyzbUtQTVigsoWxToGohDP6czBYsXRZhZMwk3a4LKxhnKIxx+2lw Merge authors: Milo Casagrande (milo) Related merge proposals: https://code.launchpad.net/~milo/linaro-image-tools/bug1004199/+merge/108747 proposed by: Milo Casagrande (milo) review: Approve - Данило Шеган (danilo) ------------------------------------------------------------ revno: 525 [merge] committer: Milo Casagrande branch nick: trunk timestamp: Wed 2012-06-13 16:01:28 +0200 message: [merge] Merged fixes for bug 1004199. modified: linaro_image_tools/media_create/partitions.py linaro_image_tools/media_create/tests/test_media_create.py --- lp:linaro-image-tools https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk You are subscribed to branch lp:linaro-image-tools. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-image-tools/linaro-image-tools/trunk/+edit-subscription === modified file 'linaro_image_tools/media_create/partitions.py' --- linaro_image_tools/media_create/partitions.py 2012-05-09 21:25:20 +0000 +++ linaro_image_tools/media_create/partitions.py 2012-06-13 13:42:08 +0000 @@ -17,15 +17,16 @@ # You should have received a copy of the GNU General Public License # along with Linaro Image Tools. If not, see . +from contextlib import contextmanager +from math import ceil import atexit -from contextlib import contextmanager +import dbus import glob import logging import re import subprocess import time -import dbus from parted import ( Device, Disk, @@ -35,7 +36,6 @@ from linaro_image_tools import cmd_runner - HEADS = 128 SECTORS = 32 SECTOR_SIZE = 512 # bytes @@ -45,13 +45,17 @@ # Max number of attempts to sleep (total sleep time in seconds = # 1+2+...+MAX_TTS) MAX_TTS = 10 +# Image size should be a multiple of 1MiB, expressed in bytes. This is also +# the minimum image size possible. +ROUND_IMAGE_TO = 2 ** 20 +MIN_IMAGE_SIZE = ROUND_IMAGE_TO def setup_android_partitions(board_config, media, image_size, bootfs_label, should_create_partitions, should_align_boot_part=False): cylinders = None if not media.is_block_device: - image_size_in_bytes = convert_size_to_bytes(image_size) + image_size_in_bytes = get_partition_size_in_bytes(image_size) cylinders = image_size_in_bytes / CYLINDER_SIZE proc = cmd_runner.run( ['dd', 'of=%s' % media.path, @@ -131,7 +135,7 @@ """ cylinders = None if not media.is_block_device: - image_size_in_bytes = convert_size_to_bytes(image_size) + image_size_in_bytes = get_partition_size_in_bytes(image_size) cylinders = image_size_in_bytes / CYLINDER_SIZE proc = cmd_runner.run( ['dd', 'of=%s' % media.path, @@ -478,14 +482,20 @@ path, 'DeviceFile', dbus_interface=DBUS_PROPERTIES)) -def convert_size_to_bytes(size): - """Convert a size string in Kbytes, Mbytes or Gbytes to bytes.""" +def get_partition_size_in_bytes(size): + """Convert a size string in Kbytes, Mbytes or Gbytes to bytes. + + The conversion rounds-up the size to the nearest MiB, considering a minimum + size of MIN_IMAGE_SIZE bytes. The conversion always assures to have a big + enough size for the partition. + """ unit = size[-1].upper() + real_size = float(size[:-1]) + # no unit? (ends with a digit) if unit in '0123456789': - return int(round(float(size))) - real_size = float(size[:-1]) - if unit == 'K': + real_size = float(size) + elif unit == 'K': real_size = real_size * 1024 elif unit == 'M': real_size = real_size * 1024 * 1024 @@ -494,8 +504,20 @@ else: raise ValueError("Unknown size format: %s. Use K[bytes], M[bytes] " "or G[bytes]" % size) - - return int(round(real_size)) + # Guarantee that is a multiple of ROUND_IMAGE_TO + real_size = _check_min_size(int(ceil(real_size / ROUND_IMAGE_TO) * + ROUND_IMAGE_TO)) + return real_size + + +def _check_min_size(size): + """Check that the image size is at least MIN_IMAGE_SIZE bytes. + + :param size: The size of the image to check, as a number. + """ + if (size < MIN_IMAGE_SIZE): + size = MIN_IMAGE_SIZE + return size def run_sfdisk_commands(commands, heads, sectors, cylinders, device, === modified file 'linaro_image_tools/media_create/tests/test_media_create.py' --- linaro_image_tools/media_create/tests/test_media_create.py 2012-06-07 13:12:42 +0000 +++ linaro_image_tools/media_create/tests/test_media_create.py 2012-06-12 14:08:45 +0000 @@ -38,11 +38,11 @@ from linaro_image_tools import cmd_runner import linaro_image_tools.media_create from linaro_image_tools.media_create import ( + android_boards, + boards, check_device, - boards, partitions, rootfs, - android_boards, ) from linaro_image_tools.media_create.boards import ( SECTOR_SIZE, @@ -64,8 +64,8 @@ BoardConfig, ) from linaro_image_tools.media_create.android_boards import ( + AndroidSnowballEmmcConfig, android_board_configs, - AndroidSnowballEmmcConfig, ) from linaro_image_tools.media_create.chroot_utils import ( copy_file, @@ -79,23 +79,25 @@ ) from linaro_image_tools.media_create.partitions import ( HEADS, + MIN_IMAGE_SIZE, + Media, SECTORS, + _check_min_size, + _get_device_file_for_partition_number, + _parse_blkid_output, + calculate_android_partition_size_and_offset, calculate_partition_size_and_offset, - calculate_android_partition_size_and_offset, - convert_size_to_bytes, create_partitions, ensure_partition_is_not_mounted, + get_android_loopback_devices, get_boot_and_root_loopback_devices, - get_android_loopback_devices, get_boot_and_root_partitions_for_media, - Media, + get_partition_size_in_bytes, + get_uuid, partition_mounted, run_sfdisk_commands, setup_partitions, - get_uuid, - _parse_blkid_output, wait_partition_to_settle, - _get_device_file_for_partition_number, ) from linaro_image_tools.media_create.rootfs import ( append_to_fstab, @@ -104,8 +106,8 @@ move_contents, populate_rootfs, rootfs_mount_options, + update_network_interfaces, write_data_to_protected_file, - update_network_interfaces, ) from linaro_image_tools.media_create.tests.fixtures import ( CreateTarballFixture, @@ -492,7 +494,9 @@ class config(BoardConfig): pass - self.assertRaises(AssertionError, config.set_metadata, 'ahwpack.tar.gz') + self.assertRaises(AssertionError, + config.set_metadata, + 'ahwpack.tar.gz') class TestGetMLOFile(TestCaseWithFixtures): @@ -767,8 +771,11 @@ uboot_file = os.path.join(uboot_dir, 'u-boot.bin') uboot_relative_file = uboot_file.replace(self.tempdir, '') with open(cfg_file, 'w') as f: - f.write('%s %s %i %#x %s\n' % ('NORMAL', uboot_relative_file, 0, - 0xBA0000, '9')) + f.write('%s %s %i %#x %s\n' % ('NORMAL', + uboot_relative_file, + 0, + 0xBA0000, + '9')) with open(uboot_file, 'w') as f: file_info = boards.SnowballEmmcConfig.get_file_info( self.tempdir, self.temp_bootdir_path) @@ -781,8 +788,10 @@ with open(cfg_file, 'w') as f: f.write('%s %s %i %#x %s\n' % ('NORMAL', 'u-boot.bin', 0, 0xBA0000, '9')) - self.assertRaises(AssertionError, boards.SnowballEmmcConfig.get_file_info, - self.tempdir, self.temp_bootdir_path) + self.assertRaises(AssertionError, + boards.SnowballEmmcConfig.get_file_info, + self.tempdir, + self.temp_bootdir_path) def test_file_name_size(self): ''' Test using a to large toc file ''' @@ -961,7 +970,8 @@ super(TestBootSteps, self).setUp() self.funcs_calls = [] self.mock_all_boards_funcs() - linaro_image_tools.media_create.boards.BoardConfig.hwpack_format = '1.0' + linaro_image_tools.media_create.boards.BoardConfig.hwpack_format = \ + '1.0' def mock_all_boards_funcs(self): """Mock functions of boards module with a call tracer.""" @@ -1037,8 +1047,8 @@ lambda: '1.0') self.make_boot_files(boards.SMDKV310Config) expected = [ - 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage', - 'make_uInitrd', 'make_boot_script'] + 'install_samsung_boot_loader', 'make_flashable_env', '_dd', + 'make_uImage', 'make_uInitrd', 'make_boot_script'] self.assertEqual(expected, self.funcs_calls) def test_origen_steps(self): @@ -1058,8 +1068,8 @@ lambda: '1.0') self.make_boot_files(boards.OrigenConfig) expected = [ - 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage', - 'make_uInitrd', 'make_boot_script'] + 'install_samsung_boot_loader', 'make_flashable_env', '_dd', + 'make_uImage', 'make_uInitrd', 'make_boot_script'] self.assertEqual(expected, self.funcs_calls) def test_ux500_steps(self): @@ -2424,32 +2434,46 @@ '98367,-,E\n98367,65536,L\n294975,131072,L\n' \ '426047,,,-', '%s' % self.android_image_size) + def test_check_min_size_small(self): + """Check that we get back the minimum size as expeceted.""" + self.assertEqual(MIN_IMAGE_SIZE, _check_min_size(12345)) + + def test_check_min_size_big(self): + """Check that we get back the same value we pass.""" + self.assertEqual(MIN_IMAGE_SIZE * 3, _check_min_size(3145728)) + + def test_convert_size_wrong_suffix(self): + self.assertRaises(ValueError, get_partition_size_in_bytes, "123456H") + def test_convert_size_no_suffix(self): - self.assertEqual(524288, convert_size_to_bytes('524288')) + self.assertEqual(2 ** 20, get_partition_size_in_bytes('123456')) + + def test_convert_size_one_mbyte(self): + self.assertEqual(2 ** 20, get_partition_size_in_bytes('1M')) def test_convert_size_in_kbytes_to_bytes(self): - self.assertEqual(512 * 1024, convert_size_to_bytes('512K')) + self.assertEqual(2 * 2 ** 20, get_partition_size_in_bytes('2048K')) def test_convert_size_in_mbytes_to_bytes(self): - self.assertEqual(100 * 1024 ** 2, convert_size_to_bytes('100M')) + self.assertEqual(100 * 2 ** 20, get_partition_size_in_bytes('100M')) def test_convert_size_in_gbytes_to_bytes(self): - self.assertEqual(12 * 1024 ** 3, convert_size_to_bytes('12G')) + self.assertEqual(12 * 2 ** 30, get_partition_size_in_bytes('12G')) def test_convert_size_float_no_suffix(self): - self.assertEqual(1539, convert_size_to_bytes('1539.49')) - - def test_convert_size_float_round_up(self): - self.assertEqual(1540, convert_size_to_bytes('1539.50')) + self.assertEqual(3 * 2 ** 20, get_partition_size_in_bytes('2348576.91')) def test_convert_size_float_in_kbytes_to_bytes(self): - self.assertEqual(int(round(234.8 * 1024)), convert_size_to_bytes('234.8K')) + self.assertEqual(3 * 2 ** 20, get_partition_size_in_bytes('2345.8K')) + + def test_convert_size_float_in_mbytes_to_bytes_double(self): + self.assertEqual(2 * 2 ** 20, get_partition_size_in_bytes('1.0000001M')) def test_convert_size_float_in_mbytes_to_bytes(self): - self.assertEqual(int(round(876.123 * 1024 ** 2)), convert_size_to_bytes('876.123M')) + self.assertEqual(877 * 2 ** 20, get_partition_size_in_bytes('876.123M')) def test_convert_size_float_in_gbytes_to_bytes(self): - self.assertEqual(int(round(1.9 * 1024 ** 3)), convert_size_to_bytes('1.9G')) + self.assertEqual(1946 * 2 ** 20, get_partition_size_in_bytes('1.9G')) def test_calculate_partition_size_and_offset(self): tmpfile = self._create_tmpfile() @@ -3400,6 +3424,7 @@ # Ensure the list of cleanup functions gets cleared to make sure tests # don't interfere with one another. + def clear_atexits(): linaro_image_tools.media_create.chroot_utils.local_atexit = [] self.addCleanup(clear_atexits)