Commit graph

147 commits

Author SHA1 Message Date
Tianjie Xu
2903cddb58 Improve imgdiff for large zip files
Due to the cache size limit for OTA generation, we used to split large
zip files linearly into pieces and do bsdiff on them. As a result, i) we
lose the advantage of imgdiff; ii) if there's an accidental order change
of some huge files inside the zip, we'll create an insanely large patch.

This patch splits the src&tgt more smartly based on the zip entry_name.
If the entry_name is empty or no matching source is found for a target
chunk, we'll skip adding its source and later do a bsdiff against the
whole split source image (this rarely happens in our use cases except
for the metadata inside a ziparchive).

After the split, the target pieces are continuous and block aligned,
while the sources pieces are mutually exclusive. (Some of the source
blocks may not be used if there's no matching entry_name in the target.)
Then we will generate patches accordingly between each split image
pairs.

Afterwards, if we apply imgpatch to each pair of split source/target
images and add up the patched result, we can get back the original
target image.

For example:
Input: [src_image, tgt_image]
Split: [src-0,tgt-0; src-1,tgt-1, src-2,tgt-2]
Diff:  [  patch-0;     patch-1;    patch-2]

Patch: [(src-0,patch-0)=tgt-0; (src-1,patch-1)=tgt-1;
(src-2,patch-2)=tgt-2;]
Append: [tgt-0 + tgt-1 + tgt-2 = tgt_image]

Peformance:
For the small package in b/34220646, we decrease the patch size of
chrome.apk dramatically from 30M to 400K due to the order change of
two big .so files.

On two versions of angler, I also observe decent patch size decrease.
For chrome.apk, we reduced the size from 5.9M to 3.2M; and for
vevlet.apk from 8.0M to 6.5M.

Bug: 34220646
Test: recovery component test && apply imgdiff & imgpatch on two
chrome.apk
Change-Id: I145d802984fa805efbbac9d01a2e64d82ef9728b
2017-09-05 15:09:58 -07:00
Tianjie Xu
c89d1e7e2a Turn on -Wall for recovery modules
Turn on -Wall for all modules. Also remove the obsolete file_cmp() in
apply_patch test and now() in wear_ui.

The only exception is lib_edify due to the unused functions in the
intermediate cpp files generated from the lex files. It will be handled
in a seperate CL.

Bug: 64939312
Test: mma, unit tests pass
Change-Id: Ic53f76b60b6401ab20db3d98130d674c08e3702f
2017-08-28 21:56:33 -07:00
Tianjie Xu
57dd961995 Move Image/ImageChunk/PatchChunk declaration into header files
1. Move the declaration of the Image classes to the header file to make
testing easier.
2. Also move rangeset.h to bootable/recovery to allow access in imgdiff.

Test: recovery component test
Change-Id: I68a863e60a3f2e7ae46ee48f48eb15391f5f4330
2017-08-18 17:56:22 -07:00
Tianjie Xu
d82a2ed50b Add a new PatchChunk class in imgdiff
This way we can keep the input images const when calling
genetatepatches().

Test: recovery component test; diff and patch on chrome.apk; generate
recovery-from-boot.p for angler.
Change-Id: I65b5689b88f6719c6ede46bb82def0c4caeb8a61
2017-08-12 22:07:43 -07:00
Tianjie Xu
6b03ba7902 Refactor the imgdiff
This helps us to add a new mode to handle large APKs in the follow
up CL.

Changes include:
1. Create a new interface class 'Image'
1. Create subclasses 'ZipModeImage' and 'ImageModeImage' and move the
   related functions there.

Bug: 63542719
Test: recovery_component_test passes
Change-Id: I7729b0ba39b19a9c84811636a60dd0a0b1acc2f0
2017-08-02 14:29:45 -07:00
Tianjie Xu
14ebc1e5ae Fix a rare failure for imgdiff when random data equals gzip header
In a rare case, a random chunk will pass both the gzip header check
and the inflation process; but fail the uncompressed length check in the
footer. This leads to a imgdiff failure. So, we should treat this chunk
as 'normal' instead of 'inflated' while generating the patch.

Bug: 63334984
Test: imgdiff generates patch successfully on previous failing images.
Change-Id: Ice84f22d3653bce9756bda91e70528c0d2f264a0
2017-07-06 16:49:11 -07:00
Tianjie Xu
a897f95bd5 Implement a custom deflate sink function for bspatch
This new sink function works as a wrapper of the old sink. It deflates
the available patch data on the fly. Therefore, we don't need to store
the full uncompressed patch data in memory.

Test: recovery_component_test && apply an incremental update on angler
Change-Id: I2274ec50a1607089abcc9d0954a2a748f28c3122
2017-05-26 14:05:20 -07:00
Tianjie Xu
ce5fa5e538 Print SHA1 of the patch if bsdiff fails with data error
This will help us to identify the patch corruption.

Meanwhile fix a wrong size parameter passed to bspatch.
(patch->data.size() into patch->data.size() - patch_offset).

Also remove the only usage of "ApplyBSDiffPatchMem()" and inline its
Sink function for simplicity.

Bug: 37855643
Test: Prints SHA1 for corrupted patch in imgdiff_test.
Change-Id: Ibf2db8c08b0ded1409bb7c91a3547a6bf99c601d
2017-05-16 12:39:14 -07:00
Tao Bao
d5ae4253c1 Merge "applypatch: Remove the obsolete support for "applypatch -s"." 2017-04-26 16:49:48 +00:00
Tao Bao
8ab28082b7 applypatch: Remove the obsolete support for "applypatch -s".
The SpaceMode (applypatch -s) was used in amend script (cupcake) only,
which has been removed since commit
9ce2ebf5d300eba5f6086583b0941ef68a3e4b42 (platform/build). The later
(and current) edify script uses apply_patch_space().

Note that other modes (PatchMode, CheckMode) of applypatch executable
are mostly used by install-recovery.sh script.

Test: No active user of "applypatch -s".
Test: recovery_component_test
Change-Id: I1d689b7fedd3884077e88ed1d6c22f7a2198859d
2017-04-25 21:23:12 -07:00
Jinguang Dong
391bb7bb92 applypatch: Add determine the return value of ApplyDiffPatch and
capture the error flow.

Construct ota package which is bsdiff exception scene ,then do
simulation test, native code can not capture exception scenes.

Test: recovery_component_test
Test: Apply an bsdiff exception scene ota package.
Change-Id: Icd9f6eac78739bd35c74b9fcaaf8154335d680a5
2017-04-26 10:59:57 +08:00
Tao Bao
c3ef089dfa applypatch: Remove duplicate test files.
CL in commit b8a693bbc7 has ported the
tests to gtest-based recovery_component_tests.

Test: N/A
Change-Id: I485fa11413df68a11416d4a9f91f090f302bcfc0
2017-04-02 11:27:13 -07:00
Tao Bao
c0e1c46a70 applypatch: Let Apply{BSDiff,Image}Patch accept std::function.
Test: mmma bootable/recovery system/update_engine
Test: recovery_component_test
Change-Id: I93c2caa87bf94a53509bb37f98f2c02bcadb6f5c
2017-03-28 10:14:53 -07:00
Tao Bao
f7eb760fe7 applypatch: Change the ssize_t length parameters to size_t.
Mostly for applypatch family APIs like ApplyBSDiffPatch() and
ApplyImagePatch(). Changing to size_t doesn't indicate they would
necessarily work with very large size_t (e.g. > ssize_t), just
similar to write(2). But otherwise accepting negative length doesn't
make much sense.

Also change the return type of SinkFn from ssize_t to size_t. Callers
tell a successful sink by comparing the number of written bytes against
the desired value. Negative return values like -1 are not needed. This
also makes it consistent with bsdiff::bspatch interface.

Test: recovery_component_test
Test: Apply an incremental with the new updater.
Change-Id: I7ff1615203a5c9854134f75d019e266f4ea6e714
2017-03-28 10:13:38 -07:00
Tao Bao
b4c4f8c494 Merge "applypatch: Drop the support for patching non-EMMC targets." 2017-03-26 18:00:20 +00:00
Tianjie Xu
12b90553d7 More cleanup to imgdiff & imgpatch
Also remove the utils in applypatch and replace them with the
corresponding libbase functions.

Test: recovery tests pass.
Change-Id: I77254c141bd3e7d3d6894c23b60e866009516f81
2017-03-16 12:09:49 -07:00
Tao Bao
40e144dae8 applypatch: Drop the support for patching non-EMMC targets.
Patching regular files is used in file-based OTA only, which has become
obsolete.

Bug: 35853185
Test: Apply an incremental that patches the boot.img.
Test: /system/bin/install-recovery.sh works.
Test: recovery_component_test passes.
Change-Id: Id44e42c4bc63f2162ecc8a6df1cb528b7ae6b0a9
2017-03-16 00:49:49 -07:00
Tianjie Xu
1ea84d6da9 Refractor the code for imgdiff
Put ImageChunk and some helper functions into a class. Also switch to
using std::vector instead of malloc.

Bug: 18606652
Test: imgdiff_test passed on host. Also generate a complete incremental OTA package.
The file content is the same and time consumption is similar.

Change-Id: Id603ada4e130ef521218400761a119001a86ca79
2017-03-06 15:41:02 -08:00
Sen Jiang
25c56979dd Use bspatch from external/bsdiff.
Now ApplyBSDiffPatch() will stream the output to sink as we go instead
of sinking everything at the end.

Test: recovery_host_test
Bug: 26982501

Change-Id: I05b6ed40d45e4b1b19ae72784cf705b731b976e3
2017-02-02 14:41:05 -08:00
Tao Bao
7ab9c3812d Merge "bootable/recovery: cleanup compiler warnings (potential leak of memory)" 2017-02-01 05:10:15 +00:00
Tao Bao
e78ca37656 Merge "imgpatch: Compile with ZLIB_CONST defined." 2017-01-20 20:15:57 +00:00
Tao Bao
087bc0c7d3 imgpatch: Compile with ZLIB_CONST defined.
So z_stream.next_in takes pointer to const data.

Test: mmma bootable/recovery/applypatch
Change-Id: If269b766a7c84fa2f67424ee61ba5afab0159261
2017-01-20 12:13:28 -08:00
Sen Jiang
930edb6661 imgdiff: cache bsdiff suffix array in zip mode.
In zip mode, if a chunk is not deflate or its filename can't be found
in source chunks, the entire source file is used as old data for bsdiff,
To avoid repeatedly construct the suffix array used by bsdiff, we cache
the suffix array of the entire source file.

Bug: 34281147
Test: =time -v imgdiff -z Chrome-ORF74B.apk Chrome-ORF76B.apk Chrome.imgdiff
Change-Id: Ifd957ccecf7226fcb44dbf28c58969a06ef74f4b
2017-01-18 17:26:42 -08:00
Tao Bao
3b828d879b Merge "imgdiff: Fix an edge case that leads to infinite loop." 2017-01-04 21:59:26 +00:00
Tao Bao
d37ce8f082 imgdiff: Fix an edge case that leads to infinite loop.
When the input image ends with the magic value sequence of 0x1f, 0x8b,
0x0b (optionally with 0x00), the image parsing code will be stuck in an
infinite loop.

Test: recovery_component_test passes.
Change-Id: Ie3629dfdc41360387b19cc3e0359c95ae4fb998e
2016-12-28 14:29:48 -08:00
Tao Bao
c8e79340e4 applypatch: Don't expose FindMatchingPatch().
Test: make
Change-Id: Ic77c4669574b6129e06aa6051804f419bcc8196c
2016-12-28 10:11:22 -08:00
Tao Bao
97555da4a6 Add tests for imgdiff.
Factor out libimgdiff static library for testing purpose.

This CL adds the imgdiff tests on host and on target both (similar to
libimgpatch). In practice, we only need imgdiff binary on host, and
libimgpatch on target. But they should build and pass tests on both
platforms.

Test: recovery_host_test passes; recovery_component_test passes.
Change-Id: I0eafb7faf727cdf70066310e845af6ee245d4f60
2016-12-19 16:53:03 -08:00
katao
9a6f520419 Bugfix:updater always retry apply patch failed,when memcpy failed.
https://code.google.com/p/android/issues/detail?id=230602
On the second attempt, open the file with O_RDONLY,
which causing a write failure。

Change-Id: If89165b8c7619fe25722073a46b3cc7c61530a71
Signed-off-by: katao <ustckato@gmail.com>
2016-12-19 08:51:07 +00:00
Rahul Chaudhry
8b640ffabc bootable/recovery: cleanup compiler warnings (potential leak of memory)
bootable/recovery/applypatch/imgdiff.cpp:195:5: warning: Potential leak
of memory pointed to by 'img' [clang-analyzer-unix.Malloc]

Bug: 26936282
Test: WITH_TIDY=1 WITH_STATIC_ANALYZER=1 mm
Change-Id: Ie79c780233ddfebf85686a24df3bf2561f831580
2016-12-06 15:10:41 -08:00
Tao Bao
ef3bea15b8 Merge "bootable/recovery: cleanup compiler warnings (unused value)" 2016-12-01 17:03:13 +00:00
Tao Bao
d255b661a1 Merge "bootable/recovery: cleanup compiler warnings (potential leak of memory)" 2016-11-30 21:19:42 +00:00
Rahul Chaudhry
a793c58208 bootable/recovery: cleanup compiler warnings (unused value)
bootable/recovery/applypatch/imgdiff.cpp:322:11: warning: Value stored to 'ret' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
bootable/recovery/applypatch/imgdiff.cpp:447:11: warning: Value stored to 'ret' during its initialization is never read [clang-analyzer-deadcode.DeadStores]
bootable/recovery/applypatch/imgdiff.cpp:553:3: warning: Value stored to 'ret' is never read [clang-analyzer-deadcode.DeadStores]

Bug: 26936282
Test: WITH_TIDY=1 WITH_STATIC_ANALYZER=1 mm
Change-Id: I3f865e3e9b9d19e5ea5e8dfd2fe2c644254ffbb5
2016-11-30 11:18:32 -08:00
Tao Bao
358c2ec1dc Remove ota_close(int) and ota_fclose(FILE*).
We should always use unique_fd or unique_file to hold the FD or FILE*
pointer when opening via ota_(f)open functions.

This CL avoids accidentally closing raw FDs or FILE* pointers that are
managed by unique_fd/unique_file.

Test: recovery_component_test passes.
Change-Id: If58eb8b5c5da507563f85efd5d56276472a1c957
2016-11-28 12:09:39 -08:00
Tao Bao
3dc14cb429 Add ota_close(unique_fd&) and ota_fclose(std::unique_ptr<FILE>&).
We were using the below sequence prior to the CL in [1].

unique_fd fd(ota_open(...));
ota_close(fd);
fd.reset(ota_open(...));

fd.reset() may unintentionally close the newly opened FD if it
has the same value as the early ota_open. The CL in [1] changed to
"ota_close(fd.release())" to avoid the issue. This CL adds a new
overloaded function ota_close(unique_fd&) to handle the release
automatically.

Similarly add ota_fclose(std::unique_ptr<FILE>&).

[1] commit 48cf770471.

Bug: 33034669
Test: recovery_component_test passes.
Change-Id: Ief91edc590e95a7426e33364b28754173efb1056
2016-11-22 16:44:41 -08:00
Tao Bao
48cf770471 applypatch: Release FD when explicitly calling close.
We use android::base::unique_fd() to avoid leaking FD. We also want to
call close (or ota_close) to explicitly check the close result. When
combining the two together, we need to release the unique_fd to avoid
closing the same FD twice.

Bug: 33034669
Test: Trigger applypatch with install-recovery.sh.
Change-Id: I1a4f5d5fba7a23ef98d8bd7b7b07e87ae6f705c5
2016-11-21 09:47:34 -08:00
Tao Bao
6e02ea92ec applypatch: Use unique_fd to avoid leaking FDs.
Add unique_fd that calls ota_close() instead of the default closer.

Test: recovery_component_test passes.
Test: Apply a package that calls apply_patch().

Change-Id: I0c19921731757934f76cf7d5215916673a8f2777
2016-11-17 12:01:44 -08:00
Tao Bao
8fce75a069 applypatch: Clean up LoadPartitionContents().
We don't need three vectors to sort the (size, SHA-1) pairs.

Test: recovery_component_test passes.
Test: Apply a package that calls apply_patch_check() to patch EMMC
      partitions.
Change-Id: I4a6620630a6711f490822cf30f1e7fe5cea6ce49
2016-11-17 00:02:52 -08:00
Rahul Chaudhry
b29f23f7e7 Use static_cast to cast pointers returned by malloc/calloc/realloc/mmap.
static_cast is preferable to reinterpret_cast when casting from void*
pointers returned by malloc/calloc/realloc/mmap calls.

Discovered while looking at compiler warnings (b/26936282).

Test: WITH_TIDY=1 WITH_STATIC_ANALYZER=1 mma
Change-Id: Iaffd537784aa857108f6981fdfd82d0496eb5592
Merged-In: I151642d5a60c94f312d0611576ad0143c249ba3d
2016-11-15 23:24:54 -08:00
Rahul Chaudhry
3a5177b16d bootable/recovery: cleanup compiler warnings (potential leak of memory)
bootable/recovery/applypatch/imgdiff.cpp:1065:3: warning: Potential leak of memory pointed to by 'patch_data'
bootable/recovery/applypatch/imgdiff.cpp:1065:3: warning: Potential leak of memory pointed to by 'patch_size'
bootable/recovery/applypatch/imgdiff.cpp:226:7: warning: Potential leak of memory pointed to by 'temp_entries'

Bug: 26936282
Test: WITH_TIDY=1 WITH_STATIC_ANALYZER=1 mm
Change-Id: I3cac945d7677d367934d5619ef7419daf6f48d6f
2016-11-15 16:18:46 -08:00
Tao Bao
36c3511952 applypatch: Add testcases for applypatch executable.
Refactor applypatch/main.cpp into libapplypatch_modes so that we can add
testcases.

Some changes to applypatch/main.cpp:
 - Replace char** argv with const char**;
 - Use android::base::Split() to split ":";
 - Use android::base::ParseUInt().

Bug: 32383590
Test: Unit tests pass, install-recovery.sh works.

Change-Id: I44e7bfa5ab717d439ea1d0ee9ddb7b2c40bb95a4
2016-11-01 14:40:14 -07:00
Tao Bao
fada91ccf2 applypatch: Switch the parameter of Value** to std::vector.
Test: Unit tests and install-recovery.sh pass on angler and dragon.

Change-Id: I328e6554edca667cf850f5584ebf1ac211e3d4d1
2016-10-28 16:46:12 -07:00
Tao Bao
edf1b15fef applypatch: Fix the bug when constructing VAL_BLOB.
When constructing std::string from C-string, the string may be truncated
at null char. Use range constructor instead.

Bug: 32380016
Test: Use applypatch to install a previously failed recovery image.
Change-Id: Id3e2afb4a810594243cd21db526933d1fea5044b
2016-10-24 16:08:28 -07:00
Tianjie Xu
7df1850d37 Merge "Fix applypatch_check failure when applying update on angler" 2016-10-19 00:29:23 +00:00
Tianjie Xu
984d7d058e Fix applypatch_check failure when applying update on angler
Applypatch_check should be skipped if no sha is specified. As the
comments said: "It's okay to specify no sha1s; the check will pass if
the LoadFileContents is successful. Useful for reading partitions,
where the filename encodes the sha1s."

Test: The update package applied on angler successfully.
Bug: 32243751
Change-Id: Ib8f3dadf19f745c2dbd350d60da46ab12d75bc87
2016-10-18 21:22:48 +00:00
Tianjie Xu
8cf5c8f60f Replace minzip with libziparchive
Clean up the duplicated codes that handle the zip files in
bootable/recovery; and rename the library of the remaining
utility functions to libotautil.

Test: Update package installed successfully on angler.
Bug: 19472796

Change-Id: Iea8962fcf3004473cb0322b6bb3a9ea3ca7f679e
2016-10-17 17:41:51 -07:00
Tianjie Xu
aced5d9e4e Change StringValue to use std::string
Changing the field of 'Value' in edify to std::string from char*.
Meanwhile cleaning up the users of 'Value' and switching them to
cpp style.

Test: compontent tests passed.
Bug: 31713288

Change-Id: Iec5a7d601b1e4ca40935bf1c70d325dafecec235
2016-10-15 01:18:23 +00:00
Tianjie Xu
7aa88748f6 Turn on -Werror for recovery
Also remove the 0xff comparison when validating the bootloader
message fields. As the fields won't be erased to 0xff after we
remove the MTD support.

Bug: 28202046
Test: The recovery folder compiles for aosp_x86-eng
Change-Id: Ibb30ea1b2b28676fb08c7e92a1e5f7b6ef3247ab
2016-09-29 19:21:24 -07:00
Tianjie Xu
61590bbf0d Merge "Switch recovery to libbase logging" 2016-09-01 23:04:37 +00:00
Tianjie Xu
7b0ad9c638 Switch recovery to libbase logging
Clean up the recovery image and switch to libbase logging.

Bug: 28191554
Change-Id: Icd999c3cc832f0639f204b5c36cea8afe303ad35
Merged-In: Icd999c3cc832f0639f204b5c36cea8afe303ad35
2016-09-01 18:33:25 +00:00
Tianjie Xu
71e182bc38 Check an edge case when read(2) returns 0
We might end up in an infinite loop if read(2) reached EOF unexpectedly.
The problematic code in uncrypt mentioned in the bug has been fixed
by switching to libbase ReadFully(). So I grepped through the recovery
code and fixed some other occurences of the issue.

Bug: 31073201
Change-Id: Ib867029158ba23363b8f85d61c25058a635c5a6b
2016-08-31 19:11:41 -07:00