Merge "build: Split out mkfs in BuildImageMkfs (retry)"
am: a81a534c58
Change-Id: I8fea093ba5ace0f3a345dd2491cff8ee2736cbe6
This commit is contained in:
commit
bf95e44687
1 changed files with 110 additions and 81 deletions
|
@ -221,8 +221,8 @@ def CheckHeadroom(ext4fs_output, prop_dict):
|
|||
adjusted_blocks))
|
||||
|
||||
|
||||
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
||||
"""Builds an image for the files under in_dir and writes it to out_file.
|
||||
def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config):
|
||||
"""Builds a pure image for the files under in_dir and writes it to out_file.
|
||||
|
||||
Args:
|
||||
in_dir: Path to input directory.
|
||||
|
@ -233,81 +233,15 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||
points to the /system directory under PRODUCT_OUT. fs_config (the one
|
||||
under system/core/libcutils) reads device specific FS config files from
|
||||
there.
|
||||
fs_config: The fs_config file that drives the prototype
|
||||
|
||||
Raises:
|
||||
BuildImageError: On build image failures.
|
||||
"""
|
||||
original_mount_point = prop_dict["mount_point"]
|
||||
in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
|
||||
|
||||
build_command = []
|
||||
fs_type = prop_dict.get("fs_type", "")
|
||||
run_e2fsck = False
|
||||
|
||||
fs_spans_partition = True
|
||||
if fs_type.startswith("squash"):
|
||||
fs_spans_partition = False
|
||||
|
||||
# Get a builder for creating an image that's to be verified by Verified Boot,
|
||||
# or None if not applicable.
|
||||
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
|
||||
|
||||
if (prop_dict.get("use_dynamic_partition_size") == "true" and
|
||||
"partition_size" not in prop_dict):
|
||||
# If partition_size is not defined, use output of `du' + reserved_size.
|
||||
size = GetDiskUsage(in_dir)
|
||||
logger.info(
|
||||
"The tree size of %s is %d MB.", in_dir, size // BYTES_IN_MB)
|
||||
# If not specified, give us 16MB margin for GetDiskUsage error ...
|
||||
size += int(prop_dict.get("partition_reserved_size", BYTES_IN_MB * 16))
|
||||
# Round this up to a multiple of 4K so that avbtool works
|
||||
size = common.RoundUpTo4K(size)
|
||||
if fs_type.startswith("ext"):
|
||||
if verity_image_builder:
|
||||
size = verity_image_builder.CalculateDynamicPartitionSize(size)
|
||||
prop_dict["partition_size"] = str(size)
|
||||
if "extfs_inode_count" not in prop_dict:
|
||||
prop_dict["extfs_inode_count"] = str(GetInodeUsage(in_dir))
|
||||
logger.info(
|
||||
"First Pass based on estimates of %d MB and %s inodes.",
|
||||
size // BYTES_IN_MB, prop_dict["extfs_inode_count"])
|
||||
prop_dict["mount_point"] = original_mount_point
|
||||
BuildImage(in_dir, prop_dict, out_file, target_out)
|
||||
fs_dict = GetFilesystemCharacteristics(out_file)
|
||||
os.remove(out_file)
|
||||
block_size = int(fs_dict.get("Block size", "4096"))
|
||||
free_size = int(fs_dict.get("Free blocks", "0")) * block_size
|
||||
reserved_size = int(prop_dict.get("partition_reserved_size", 0))
|
||||
if free_size <= reserved_size:
|
||||
logger.info(
|
||||
"Not worth reducing image %d <= %d.", free_size, reserved_size)
|
||||
else:
|
||||
size -= free_size
|
||||
size += reserved_size
|
||||
if block_size <= 4096:
|
||||
size = common.RoundUpTo4K(size)
|
||||
else:
|
||||
size = ((size + block_size - 1) // block_size) * block_size
|
||||
extfs_inode_count = prop_dict["extfs_inode_count"]
|
||||
inodes = int(fs_dict.get("Inode count", extfs_inode_count))
|
||||
inodes -= int(fs_dict.get("Free inodes", "0"))
|
||||
prop_dict["extfs_inode_count"] = str(inodes)
|
||||
prop_dict["partition_size"] = str(size)
|
||||
logger.info(
|
||||
"Allocating %d Inodes for %s.", inodes, out_file)
|
||||
if verity_image_builder:
|
||||
size = verity_image_builder.CalculateDynamicPartitionSize(size)
|
||||
prop_dict["partition_size"] = str(size)
|
||||
logger.info(
|
||||
"Allocating %d MB for %s.", size // BYTES_IN_MB, out_file)
|
||||
|
||||
prop_dict["image_size"] = prop_dict["partition_size"]
|
||||
|
||||
# Adjust the image size to make room for the hashes if this is to be verified.
|
||||
if verity_image_builder:
|
||||
max_image_size = verity_image_builder.CalculateMaxImageSize()
|
||||
prop_dict["image_size"] = str(max_image_size)
|
||||
|
||||
if fs_type.startswith("ext"):
|
||||
build_command = [prop_dict["ext_mkuserimg"]]
|
||||
if "extfs_sparse_flag" in prop_dict:
|
||||
|
@ -400,8 +334,8 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||
logger.exception("Failed to compute disk usage with du")
|
||||
du_str = "unknown"
|
||||
print(
|
||||
"Out of space? The tree size of {} is {}, with reserved space of {} "
|
||||
"bytes ({} MB).".format(
|
||||
"Out of space? Out of inodes? The tree size of {} is {}, "
|
||||
"with reserved space of {} bytes ({} MB).".format(
|
||||
in_dir, du_str,
|
||||
int(prop_dict.get("partition_reserved_size", 0)),
|
||||
int(prop_dict.get("partition_reserved_size", 0)) // BYTES_IN_MB))
|
||||
|
@ -414,6 +348,111 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||
int(prop_dict["partition_size"]) // BYTES_IN_MB))
|
||||
raise
|
||||
|
||||
if run_e2fsck and prop_dict.get("skip_fsck") != "true":
|
||||
unsparse_image = UnsparseImage(out_file, replace=False)
|
||||
|
||||
# Run e2fsck on the inflated image file
|
||||
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
|
||||
try:
|
||||
common.RunAndCheckOutput(e2fsck_command)
|
||||
finally:
|
||||
os.remove(unsparse_image)
|
||||
|
||||
return mkfs_output
|
||||
|
||||
|
||||
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
||||
"""Builds an image for the files under in_dir and writes it to out_file.
|
||||
|
||||
Args:
|
||||
in_dir: Path to input directory.
|
||||
prop_dict: A property dict that contains info like partition size. Values
|
||||
will be updated with computed values.
|
||||
out_file: The output image file.
|
||||
target_out: Path to the TARGET_OUT directory as in Makefile. It actually
|
||||
points to the /system directory under PRODUCT_OUT. fs_config (the one
|
||||
under system/core/libcutils) reads device specific FS config files from
|
||||
there.
|
||||
|
||||
Raises:
|
||||
BuildImageError: On build image failures.
|
||||
"""
|
||||
in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
|
||||
|
||||
build_command = []
|
||||
fs_type = prop_dict.get("fs_type", "")
|
||||
|
||||
fs_spans_partition = True
|
||||
if fs_type.startswith("squash"):
|
||||
fs_spans_partition = False
|
||||
|
||||
# Get a builder for creating an image that's to be verified by Verified Boot,
|
||||
# or None if not applicable.
|
||||
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
|
||||
|
||||
if (prop_dict.get("use_dynamic_partition_size") == "true" and
|
||||
"partition_size" not in prop_dict):
|
||||
# If partition_size is not defined, use output of `du' + reserved_size.
|
||||
size = GetDiskUsage(in_dir)
|
||||
logger.info(
|
||||
"The tree size of %s is %d MB.", in_dir, size // BYTES_IN_MB)
|
||||
# If not specified, give us 16MB margin for GetDiskUsage error ...
|
||||
reserved_size = int(prop_dict.get("partition_reserved_size", BYTES_IN_MB * 16))
|
||||
partition_headroom = int(prop_dict.get("partition_headroom", 0))
|
||||
if fs_type.startswith("ext4") and partition_headroom > reserved_size:
|
||||
reserved_size = partition_headroom
|
||||
size += reserved_size
|
||||
# Round this up to a multiple of 4K so that avbtool works
|
||||
size = common.RoundUpTo4K(size)
|
||||
if fs_type.startswith("ext"):
|
||||
prop_dict["partition_size"] = str(size)
|
||||
prop_dict["image_size"] = str(size)
|
||||
if "extfs_inode_count" not in prop_dict:
|
||||
prop_dict["extfs_inode_count"] = str(GetInodeUsage(in_dir))
|
||||
logger.info(
|
||||
"First Pass based on estimates of %d MB and %s inodes.",
|
||||
size // BYTES_IN_MB, prop_dict["extfs_inode_count"])
|
||||
BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
|
||||
fs_dict = GetFilesystemCharacteristics(out_file)
|
||||
os.remove(out_file)
|
||||
block_size = int(fs_dict.get("Block size", "4096"))
|
||||
free_size = int(fs_dict.get("Free blocks", "0")) * block_size
|
||||
reserved_size = int(prop_dict.get("partition_reserved_size", 0))
|
||||
partition_headroom = int(fs_dict.get("partition_headroom", 0))
|
||||
if fs_type.startswith("ext4") and partition_headroom > reserved_size:
|
||||
reserved_size = partition_headroom
|
||||
if free_size <= reserved_size:
|
||||
logger.info(
|
||||
"Not worth reducing image %d <= %d.", free_size, reserved_size)
|
||||
else:
|
||||
size -= free_size
|
||||
size += reserved_size
|
||||
if block_size <= 4096:
|
||||
size = common.RoundUpTo4K(size)
|
||||
else:
|
||||
size = ((size + block_size - 1) // block_size) * block_size
|
||||
extfs_inode_count = prop_dict["extfs_inode_count"]
|
||||
inodes = int(fs_dict.get("Inode count", extfs_inode_count))
|
||||
inodes -= int(fs_dict.get("Free inodes", "0"))
|
||||
prop_dict["extfs_inode_count"] = str(inodes)
|
||||
prop_dict["partition_size"] = str(size)
|
||||
logger.info(
|
||||
"Allocating %d Inodes for %s.", inodes, out_file)
|
||||
if verity_image_builder:
|
||||
size = verity_image_builder.CalculateDynamicPartitionSize(size)
|
||||
prop_dict["partition_size"] = str(size)
|
||||
logger.info(
|
||||
"Allocating %d MB for %s.", size // BYTES_IN_MB, out_file)
|
||||
|
||||
prop_dict["image_size"] = prop_dict["partition_size"]
|
||||
|
||||
# Adjust the image size to make room for the hashes if this is to be verified.
|
||||
if verity_image_builder:
|
||||
max_image_size = verity_image_builder.CalculateMaxImageSize()
|
||||
prop_dict["image_size"] = str(max_image_size)
|
||||
|
||||
mkfs_output = BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
|
||||
|
||||
# Check if there's enough headroom space available for ext4 image.
|
||||
if "partition_headroom" in prop_dict and fs_type.startswith("ext4"):
|
||||
CheckHeadroom(mkfs_output, prop_dict)
|
||||
|
@ -425,16 +464,6 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
|
|||
if verity_image_builder:
|
||||
verity_image_builder.Build(out_file)
|
||||
|
||||
if run_e2fsck and prop_dict.get("skip_fsck") != "true":
|
||||
unsparse_image = UnsparseImage(out_file, replace=False)
|
||||
|
||||
# Run e2fsck on the inflated image file
|
||||
e2fsck_command = ["e2fsck", "-f", "-n", unsparse_image]
|
||||
try:
|
||||
common.RunAndCheckOutput(e2fsck_command)
|
||||
finally:
|
||||
os.remove(unsparse_image)
|
||||
|
||||
|
||||
def ImagePropFromGlobalDict(glob_dict, mount_point):
|
||||
"""Build an image property dictionary from the global dictionary.
|
||||
|
|
Loading…
Reference in a new issue