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

Commit bb4ab1e3 authored by Tao Bao's avatar Tao Bao Committed by Brint E. Kriebel
Browse files

Assert the stash size when generating OTAs.

With block-based OTA v2 and v3, it requires stash space on the /cache
partition to back up blocks during an update. We need to ensure that
it doesn't exceed the partition size. Since there might be other files
on /cache as well, we use cache_size * threshold as the maximum allowed
size. The threshold defaults to 0.8, which can be overridden by command
line option '--stash_threshold'.

Change-Id: I5c2e353ea4716328d6cdc6a7f758520de8d88b8e
(cherry picked from commit 23ac4042)
parent 52ffc468
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ from __future__ import print_function

from collections import deque, OrderedDict
from hashlib import sha1
import common
import heapq
import itertools
import multiprocessing
@@ -438,10 +439,20 @@ class BlockImageDiff(object):
      if free_string:
        out.append("".join(free_string))


      # sanity check: abort if we're going to need more than 512 MB if
      # stash space
      assert max_stashed_blocks * self.tgt.blocksize < (512 << 20)
      if self.version >= 2:
        # Sanity check: abort if we're going to need more stash space than
        # the allowed size (cache_size * threshold). There are two purposes
        # of having a threshold here. a) Part of the cache may have been
        # occupied by some recovery logs. b) It will buy us some time to deal
        # with the oversize issue.
        cache_size = common.OPTIONS.cache_size
        stash_threshold = common.OPTIONS.stash_threshold
        max_allowed = cache_size * stash_threshold
        assert max_stashed_blocks * self.tgt.blocksize < max_allowed, \
               'Stash size %d (%d * %d) exceeds the limit %d (%d * %.2f)' % (
                   max_stashed_blocks * self.tgt.blocksize, max_stashed_blocks,
                   self.tgt.blocksize, max_allowed, cache_size,
                   stash_threshold)

    all_tgt = RangeSet(data=(0, self.tgt.total_blocks))
    if performs_read:
@@ -469,8 +480,11 @@ class BlockImageDiff(object):
        f.write(i)

    if self.version >= 2:
      print("max stashed blocks: %d  (%d bytes)\n" % (
          max_stashed_blocks, max_stashed_blocks * self.tgt.blocksize))
      max_stashed_size = max_stashed_blocks * self.tgt.blocksize
      max_allowed = common.OPTIONS.cache_size * common.OPTIONS.stash_threshold
      print("max stashed blocks: %d  (%d bytes), limit: %d bytes (%.2f%%)\n" % (
          max_stashed_blocks, max_stashed_size, max_allowed,
          max_stashed_size * 100.0 / max_allowed))

  def ComputePatches(self, prefix):
    print("Reticulating splines...")
+19 −0
Original line number Diff line number Diff line
@@ -83,6 +83,10 @@ Usage: ota_from_target_files [flags] input_target_files output_ota_package
      Specifies the number of worker-threads that will be used when
      generating patches for incremental updates (defaults to 3).

  --stash_threshold <float>
      Specifies the threshold that will be used to compute the maximum
      allowed stash size (defaults to 0.8).

  --backup <boolean>
      Enable or disable the execution of backuptool.sh.
      Disabled by default.
@@ -140,6 +144,9 @@ OPTIONS.block_based = False
OPTIONS.updater_binary = None
OPTIONS.oem_source = None
OPTIONS.fallback_to_full = True
# Stash size cannot exceed cache_size * threshold.
OPTIONS.cache_size = None
OPTIONS.stash_threshold = 0.8
OPTIONS.backuptool = False
OPTIONS.override_device = 'auto'
OPTIONS.override_prop = False
@@ -1538,6 +1545,12 @@ def main(argv):
      OPTIONS.updater_binary = a
    elif o in ("--no_fallback_to_full",):
      OPTIONS.fallback_to_full = False
    elif o == "--stash_threshold":
      try:
        OPTIONS.stash_threshold = float(a)
      except ValueError:
        raise ValueError("Cannot parse value %r for option %r - expecting "
                         "a float" % (a, o))
    elif o in ("--backup"):
      OPTIONS.backuptool = bool(a.lower() == 'true')
    elif o in ("--override_device"):
@@ -1569,6 +1582,7 @@ def main(argv):
                                              "oem_settings=",
                                              "verify",
                                              "no_fallback_to_full",
                                              "stash_threshold=",
                                              "backup=",
                                              "override_device=",
                                              "override_prop=",
@@ -1628,6 +1642,11 @@ def main(argv):
      output_zip = zipfile.ZipFile(temp_zip_file, "w",
                                   compression=zipfile.ZIP_DEFLATED)

    cache_size = OPTIONS.info_dict.get("cache_size", None)
    if cache_size is None:
      raise RuntimeError("can't determine the cache partition size")
    OPTIONS.cache_size = cache_size

    if OPTIONS.incremental_source is None:
      WriteFullOTAPackage(input_zip, output_zip)
      if OPTIONS.package_key is None: