Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59e5a9a1 authored by Kelvin Zhang's avatar Kelvin Zhang Committed by Automerger Merge Worker
Browse files

Merge "Store EROFS images uncompressed" am: 691f8b93 am: 828c6876 am: d5ab964e

Original change: https://android-review.googlesource.com/c/platform/build/+/1956494

Change-Id: I77669eba679c1c010b7402650748e47a3ccd0968
parents 4dd821f3 d5ab964e
Loading
Loading
Loading
Loading
+58 −19
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import shutil
import stat
import sys
import uuid
import tempfile
import zipfile

import build_image
@@ -104,9 +105,10 @@ class OutputFile(object):
    if self._output_zip:
      self._zip_name = os.path.join(*args)

  def Write(self):
  def Write(self, compress_type=None):
    if self._output_zip:
      common.ZipWrite(self._output_zip, self.name, self._zip_name)
      common.ZipWrite(self._output_zip, self.name,
                      self._zip_name, compress_type=compress_type)


def AddSystem(output_zip, recovery_img=None, boot_img=None):
@@ -139,7 +141,8 @@ def AddSystem(output_zip, recovery_img=None, boot_img=None):
    common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
                             boot_img, info_dict=OPTIONS.info_dict)

  block_list = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "system.map")
  block_list = OutputFile(output_zip, OPTIONS.input_tmp,
                          "IMAGES", "system.map")
  CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system", img,
              block_list=block_list)
  return img.name
@@ -187,7 +190,8 @@ def AddVendor(output_zip, recovery_img=None, boot_img=None):
    common.MakeRecoveryPatch(OPTIONS.input_tmp, output_sink, recovery_img,
                             boot_img, info_dict=OPTIONS.info_dict)

  block_list = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vendor.map")
  block_list = OutputFile(output_zip, OPTIONS.input_tmp,
                          "IMAGES", "vendor.map")
  CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "vendor", img,
              block_list=block_list)
  return img.name
@@ -390,7 +394,8 @@ def AddCustomImages(output_zip, partition_name):

  for img_name in OPTIONS.info_dict.get(
          "avb_{}_image_list".format(partition_name)).split():
    custom_image = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", img_name)
    custom_image = OutputFile(
        output_zip, OPTIONS.input_tmp, "IMAGES", img_name)
    if os.path.exists(custom_image.name):
      continue

@@ -499,7 +504,9 @@ def AddUserdata(output_zip):
  build_image.BuildImage(user_dir, image_props, img.name)

  common.CheckSize(img.name, "userdata.img", OPTIONS.info_dict)
  img.Write()
  # Always use compression for useradata image.
  # As it's likely huge and consist of lots of 0s.
  img.Write(zipfile.ZIP_DEFLATED)


def AddVBMeta(output_zip, partitions, name, needed_partitions):
@@ -841,7 +848,8 @@ def AddImagesToTargetFiles(filename):
    init_boot_image = common.GetBootableImage(
        "IMAGES/init_boot.img", "init_boot.img", OPTIONS.input_tmp, "INIT_BOOT")
    if init_boot_image:
      partitions['init_boot'] = os.path.join(OPTIONS.input_tmp, "IMAGES", "init_boot.img")
      partitions['init_boot'] = os.path.join(
          OPTIONS.input_tmp, "IMAGES", "init_boot.img")
      if not os.path.exists(partitions['init_boot']):
        init_boot_image.WriteToDir(OPTIONS.input_tmp)
        if output_zip:
@@ -1005,6 +1013,35 @@ def AddImagesToTargetFiles(filename):
                          OPTIONS.replace_updated_files_list)


def OptimizeCompressedEntries(zipfile_path):
  """Convert files that do not compress well to uncompressed storage

  EROFS images tend to be compressed already, so compressing them again
  yields little space savings. Leaving them uncompressed will make
  downstream tooling's job easier, and save compute time.
  """
  if not zipfile.is_zipfile(zipfile_path):
    return
  entries_to_store = []
  with tempfile.TemporaryDirectory() as tmpdir:
    with zipfile.ZipFile(zipfile_path, "r", allowZip64=True) as zfp:
      for zinfo in zfp.filelist:
        if not zinfo.filename.startswith("IMAGES/") and not zinfo.filename.startswith("META"):
          pass
        # Don't try to store userdata.img uncompressed, it's usually huge.
        if zinfo.filename.endswith("userdata.img"):
          pass
        if zinfo.compress_size > zinfo.file_size * 0.80 and zinfo.compress_type != zipfile.ZIP_STORED:
          entries_to_store.append(zinfo)
          zfp.extract(zinfo, tmpdir)
    # Remove these entries, then re-add them as ZIP_STORED
    common.RunAndCheckOutput(
        ["zip", "-d", zipfile_path] + [entry.filename for entry in entries_to_store])
    with zipfile.ZipFile(zipfile_path, "a", allowZip64=True) as zfp:
      for entry in entries_to_store:
        zfp.write(os.path.join(tmpdir, entry.filename), entry.filename, compress_type=zipfile.ZIP_STORED)


def main(argv):
  def option_handler(o, a):
    if o in ("-a", "--add_missing"):
@@ -1036,8 +1073,10 @@ def main(argv):
  common.InitLogging()

  AddImagesToTargetFiles(args[0])
  OptimizeCompressedEntries(args[0])
  logger.info("done.")


if __name__ == '__main__':
  try:
    common.CloseInheritedPipes()