Merge "Retry adjusting the size computation for reserved blocks."
This commit is contained in:
commit
f40a34fd23
2 changed files with 68 additions and 17 deletions
|
@ -701,6 +701,7 @@ $(if $(INTERNAL_USERIMAGES_EXT_VARIANT),$(hide) echo "fs_type=$(INTERNAL_USERIMA
|
||||||
$(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
|
$(if $(BOARD_SYSTEMIMAGE_PARTITION_SIZE),$(hide) echo "system_size=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE)" >> $(1))
|
||||||
$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
$(if $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "system_fs_type=$(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
||||||
$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
|
$(if $(BOARD_SYSTEMIMAGE_JOURNAL_SIZE),$(hide) echo "system_journal_size=$(BOARD_SYSTEMIMAGE_JOURNAL_SIZE)" >> $(1))
|
||||||
|
$(if $(BOARD_HAS_EXT4_RESERVED_BLOCKS),$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(1))
|
||||||
$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
$(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
||||||
$(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
|
$(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
|
||||||
$(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
$(if $(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "cache_fs_type=$(BOARD_CACHEIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
|
||||||
|
@ -965,7 +966,15 @@ define build-systemimage-target
|
||||||
$(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) \
|
$(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) \
|
||||||
|| ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
|
|| ( echo "Out of space? the tree size of $(TARGET_OUT) is (MB): " 1>&2 ;\
|
||||||
du -sm $(TARGET_OUT) 1>&2;\
|
du -sm $(TARGET_OUT) 1>&2;\
|
||||||
echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
|
if [ "$(INTERNAL_USERIMAGES_EXT_VARIANT)" == "ext4" ]; then \
|
||||||
|
maxsize=$(BOARD_SYSTEMIMAGE_PARTITION_SIZE); \
|
||||||
|
if [ "$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" == "true" ]; then \
|
||||||
|
maxsize=$$((maxsize - 4096 * 4096)); \
|
||||||
|
fi; \
|
||||||
|
echo "The max is $$(( maxsize / 1048576 )) MB." 1>&2 ;\
|
||||||
|
else \
|
||||||
|
echo "The max is $$(( $(BOARD_SYSTEMIMAGE_PARTITION_SIZE) / 1048576 )) MB." 1>&2 ;\
|
||||||
|
fi; \
|
||||||
mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
|
mkdir -p $(DIST_DIR); cp $(INSTALLED_FILES_FILE) $(DIST_DIR)/installed-files-rescued.txt; \
|
||||||
exit 1 )
|
exit 1 )
|
||||||
endef
|
endef
|
||||||
|
@ -1456,6 +1465,9 @@ endif
|
||||||
ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
|
ifdef BOARD_RECOVERYIMAGE_PARTITION_SIZE
|
||||||
$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
|
$(hide) echo "recovery_size=$(BOARD_RECOVERYIMAGE_PARTITION_SIZE)" >> $(zip_root)/META/misc_info.txt
|
||||||
endif
|
endif
|
||||||
|
ifdef BOARD_HAS_EXT4_RESERVED_BLOCKS
|
||||||
|
$(hide) echo "has_ext4_reserved_blocks=$(BOARD_HAS_EXT4_RESERVED_BLOCKS)" >> $(zip_root)/META/misc_info.txt
|
||||||
|
endif
|
||||||
ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
|
ifdef TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS
|
||||||
@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
|
@# TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS can be empty to indicate that nothing but defaults should be used.
|
||||||
$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
|
$(hide) echo "recovery_mount_options=$(TARGET_RECOVERY_FSTYPE_MOUNT_OPTIONS)" >> $(zip_root)/META/misc_info.txt
|
||||||
|
|
|
@ -22,6 +22,7 @@ Usage: build_image input_directory properties_file output_image_file
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import commands
|
import commands
|
||||||
|
@ -31,17 +32,18 @@ import tempfile
|
||||||
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
|
FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
|
||||||
|
|
||||||
def RunCommand(cmd):
|
def RunCommand(cmd):
|
||||||
""" Echo and run the given command.
|
"""Echo and run the given command.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
cmd: the command represented as a list of strings.
|
cmd: the command represented as a list of strings.
|
||||||
Returns:
|
Returns:
|
||||||
The exit code.
|
A tuple of the output and the exit code.
|
||||||
"""
|
"""
|
||||||
print "Running: ", " ".join(cmd)
|
print "Running: ", " ".join(cmd)
|
||||||
p = subprocess.Popen(cmd)
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
p.communicate()
|
output, _ = p.communicate()
|
||||||
return p.returncode
|
print "%s" % (output.rstrip(),)
|
||||||
|
return (output, p.returncode)
|
||||||
|
|
||||||
def GetVerityTreeSize(partition_size):
|
def GetVerityTreeSize(partition_size):
|
||||||
cmd = "build_verity_tree -s %d"
|
cmd = "build_verity_tree -s %d"
|
||||||
|
@ -142,7 +144,7 @@ def UnsparseImage(sparse_image_path, replace=True):
|
||||||
else:
|
else:
|
||||||
return True, unsparse_image_path
|
return True, unsparse_image_path
|
||||||
inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
|
inflate_command = ["simg2img", sparse_image_path, unsparse_image_path]
|
||||||
exit_code = RunCommand(inflate_command)
|
(_, exit_code) = RunCommand(inflate_command)
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
os.remove(unsparse_image_path)
|
os.remove(unsparse_image_path)
|
||||||
return False, None
|
return False, None
|
||||||
|
@ -233,11 +235,12 @@ def BuildImage(in_dir, prop_dict, out_file):
|
||||||
|
|
||||||
fs_spans_partition = True
|
fs_spans_partition = True
|
||||||
if fs_type.startswith("squash"):
|
if fs_type.startswith("squash"):
|
||||||
fs_spans_partition = False
|
fs_spans_partition = False
|
||||||
|
|
||||||
is_verity_partition = "verity_block_device" in prop_dict
|
is_verity_partition = "verity_block_device" in prop_dict
|
||||||
verity_supported = prop_dict.get("verity") == "true"
|
verity_supported = prop_dict.get("verity") == "true"
|
||||||
# adjust the partition size to make room for the hashes if this is to be verified
|
# Adjust the partition size to make room for the hashes if this is to be
|
||||||
|
# verified.
|
||||||
if verity_supported and is_verity_partition and fs_spans_partition:
|
if verity_supported and is_verity_partition and fs_spans_partition:
|
||||||
partition_size = int(prop_dict.get("partition_size"))
|
partition_size = int(prop_dict.get("partition_size"))
|
||||||
adjusted_size = AdjustPartitionSizeForVerity(partition_size)
|
adjusted_size = AdjustPartitionSizeForVerity(partition_size)
|
||||||
|
@ -294,8 +297,15 @@ def BuildImage(in_dir, prop_dict, out_file):
|
||||||
staging_system = os.path.join(in_dir, "system")
|
staging_system = os.path.join(in_dir, "system")
|
||||||
shutil.rmtree(staging_system, ignore_errors=True)
|
shutil.rmtree(staging_system, ignore_errors=True)
|
||||||
shutil.copytree(origin_in, staging_system, symlinks=True)
|
shutil.copytree(origin_in, staging_system, symlinks=True)
|
||||||
|
|
||||||
|
reserved_blocks = prop_dict.get("has_ext4_reserved_blocks") == "true"
|
||||||
|
ext4fs_output = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
exit_code = RunCommand(build_command)
|
if reserved_blocks and fs_type.startswith("ext4"):
|
||||||
|
(ext4fs_output, exit_code) = RunCommand(build_command)
|
||||||
|
else:
|
||||||
|
(_, exit_code) = RunCommand(build_command)
|
||||||
finally:
|
finally:
|
||||||
if in_dir != origin_in:
|
if in_dir != origin_in:
|
||||||
# Clean up temporary directories and files.
|
# Clean up temporary directories and files.
|
||||||
|
@ -305,17 +315,42 @@ def BuildImage(in_dir, prop_dict, out_file):
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Bug: 21522719, 22023465
|
||||||
|
# There are some reserved blocks on ext4 FS (lesser of 4096 blocks and 2%).
|
||||||
|
# We need to deduct those blocks from the available space, since they are
|
||||||
|
# not writable even with root privilege. It only affects devices using
|
||||||
|
# file-based OTA and a kernel version of 3.10 or greater (currently just
|
||||||
|
# sprout).
|
||||||
|
if reserved_blocks and fs_type.startswith("ext4"):
|
||||||
|
assert ext4fs_output is not None
|
||||||
|
ext4fs_stats = re.compile(
|
||||||
|
r'Created filesystem with .* (?P<used_blocks>[0-9]+)/'
|
||||||
|
r'(?P<total_blocks>[0-9]+) blocks')
|
||||||
|
m = ext4fs_stats.match(ext4fs_output.strip().split('\n')[-1])
|
||||||
|
used_blocks = int(m.groupdict().get('used_blocks'))
|
||||||
|
total_blocks = int(m.groupdict().get('total_blocks'))
|
||||||
|
reserved_blocks = min(4096, int(total_blocks * 0.02))
|
||||||
|
adjusted_blocks = total_blocks - reserved_blocks
|
||||||
|
if used_blocks > adjusted_blocks:
|
||||||
|
mount_point = prop_dict.get("mount_point")
|
||||||
|
print("Error: Not enough room on %s (total: %d blocks, used: %d blocks, "
|
||||||
|
"reserved: %d blocks, available: %d blocks)" % (
|
||||||
|
mount_point, total_blocks, used_blocks, reserved_blocks,
|
||||||
|
adjusted_blocks))
|
||||||
|
return False
|
||||||
|
|
||||||
if not fs_spans_partition:
|
if not fs_spans_partition:
|
||||||
mount_point = prop_dict.get("mount_point")
|
mount_point = prop_dict.get("mount_point")
|
||||||
partition_size = int(prop_dict.get("partition_size"))
|
partition_size = int(prop_dict.get("partition_size"))
|
||||||
image_size = os.stat(out_file).st_size
|
image_size = os.stat(out_file).st_size
|
||||||
if image_size > partition_size:
|
if image_size > partition_size:
|
||||||
print "Error: %s image size of %d is larger than partition size of %d" % (mount_point, image_size, partition_size)
|
print("Error: %s image size of %d is larger than partition size of "
|
||||||
return False
|
"%d" % (mount_point, image_size, partition_size))
|
||||||
|
return False
|
||||||
if verity_supported and is_verity_partition:
|
if verity_supported and is_verity_partition:
|
||||||
if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
|
if 2 * image_size - AdjustPartitionSizeForVerity(image_size) > partition_size:
|
||||||
print "Error: No more room on %s to fit verity data" % mount_point
|
print "Error: No more room on %s to fit verity data" % mount_point
|
||||||
return False
|
return False
|
||||||
prop_dict["original_partition_size"] = prop_dict["partition_size"]
|
prop_dict["original_partition_size"] = prop_dict["partition_size"]
|
||||||
prop_dict["partition_size"] = str(image_size)
|
prop_dict["partition_size"] = str(image_size)
|
||||||
|
|
||||||
|
@ -331,7 +366,7 @@ def BuildImage(in_dir, prop_dict, out_file):
|
||||||
|
|
||||||
# Run e2fsck on the inflated image file
|
# Run e2fsck on the inflated image file
|
||||||
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
|
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
|
||||||
exit_code = RunCommand(e2fsck_command)
|
(_, exit_code) = RunCommand(e2fsck_command)
|
||||||
|
|
||||||
os.remove(unsparse_image)
|
os.remove(unsparse_image)
|
||||||
|
|
||||||
|
@ -378,6 +413,7 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
|
||||||
copy_prop("system_verity_block_device", "verity_block_device")
|
copy_prop("system_verity_block_device", "verity_block_device")
|
||||||
copy_prop("system_root_image", "system_root_image")
|
copy_prop("system_root_image", "system_root_image")
|
||||||
copy_prop("ramdisk_dir", "ramdisk_dir")
|
copy_prop("ramdisk_dir", "ramdisk_dir")
|
||||||
|
copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
|
||||||
elif mount_point == "data":
|
elif mount_point == "data":
|
||||||
# Copy the generic fs type first, override with specific one if available.
|
# Copy the generic fs type first, override with specific one if available.
|
||||||
copy_prop("fs_type", "fs_type")
|
copy_prop("fs_type", "fs_type")
|
||||||
|
@ -391,10 +427,12 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
|
||||||
copy_prop("vendor_size", "partition_size")
|
copy_prop("vendor_size", "partition_size")
|
||||||
copy_prop("vendor_journal_size", "journal_size")
|
copy_prop("vendor_journal_size", "journal_size")
|
||||||
copy_prop("vendor_verity_block_device", "verity_block_device")
|
copy_prop("vendor_verity_block_device", "verity_block_device")
|
||||||
|
copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
|
||||||
elif mount_point == "oem":
|
elif mount_point == "oem":
|
||||||
copy_prop("fs_type", "fs_type")
|
copy_prop("fs_type", "fs_type")
|
||||||
copy_prop("oem_size", "partition_size")
|
copy_prop("oem_size", "partition_size")
|
||||||
copy_prop("oem_journal_size", "journal_size")
|
copy_prop("oem_journal_size", "journal_size")
|
||||||
|
copy_prop("has_ext4_reserved_blocks", "has_ext4_reserved_blocks")
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
@ -424,7 +462,8 @@ def main(argv):
|
||||||
|
|
||||||
glob_dict = LoadGlobalDict(glob_dict_file)
|
glob_dict = LoadGlobalDict(glob_dict_file)
|
||||||
if "mount_point" in glob_dict:
|
if "mount_point" in glob_dict:
|
||||||
# The caller knows the mount point and provides a dictionay needed by BuildImage().
|
# The caller knows the mount point and provides a dictionay needed by
|
||||||
|
# BuildImage().
|
||||||
image_properties = glob_dict
|
image_properties = glob_dict
|
||||||
else:
|
else:
|
||||||
image_filename = os.path.basename(out_file)
|
image_filename = os.path.basename(out_file)
|
||||||
|
|
Loading…
Reference in a new issue