diff options
author | Yurii Zubrytskyi <zyy@google.com> | 2021-02-17 14:24:14 -0800 |
---|---|---|
committer | Yurii Zubrytskyi <zyy@google.com> | 2021-02-22 04:05:11 +0000 |
commit | a5946f7056fe30957f8eebd2beac06ea389dbbc9 (patch) | |
tree | 6404cf7149837c75f6b2b6b34b7db2a06195d512 /services/incremental/IncrementalService.cpp | |
parent | ddfb6c46f2e8f943a204ae4cfa65309b4b26d19a (diff) |
[incremental] Use file range mapping for .so if available
Bug: 180535478
Test: IncrementalService unit tests
Change-Id: I663dcdce337c289cacc5dc7224dedf5a55605c86
Diffstat (limited to 'services/incremental/IncrementalService.cpp')
-rw-r--r-- | services/incremental/IncrementalService.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp index 2fa927bcccfd..24623b2dacfc 100644 --- a/services/incremental/IncrementalService.cpp +++ b/services/incremental/IncrementalService.cpp @@ -1617,7 +1617,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ // Need a shared pointer: will be passing it into all unpacking jobs. std::shared_ptr<ZipArchive> zipFile(zipFileHandle, [](ZipArchiveHandle h) { CloseArchive(h); }); void* cookie = nullptr; - const auto libFilePrefix = path::join(constants().libDir, abi) + "/"; + const auto libFilePrefix = path::join(constants().libDir, abi) += "/"; if (StartIteration(zipFile.get(), &cookie, libFilePrefix, constants().libSuffix)) { LOG(ERROR) << "Failed to start zip iteration for " << apkFullPath; return false; @@ -1627,6 +1627,17 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ auto openZipTs = Clock::now(); + auto mapFiles = (mIncFs->features() & incfs::Features::v2); + incfs::FileId sourceId; + if (mapFiles) { + sourceId = mIncFs->getFileId(ifs->control, apkFullPath); + if (!incfs::isValidFileId(sourceId)) { + LOG(WARNING) << "Error getting IncFS file ID for apk path '" << apkFullPath + << "', mapping disabled"; + mapFiles = false; + } + } + std::vector<Job> jobQueue; ZipEntry entry; std::string_view fileName; @@ -1635,13 +1646,16 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ continue; } + const auto entryUncompressed = entry.method == kCompressStored; + const auto entryPageAligned = (entry.offset & (constants().blockSize - 1)) == 0; + if (!extractNativeLibs) { // ensure the file is properly aligned and unpacked - if (entry.method != kCompressStored) { + if (!entryUncompressed) { LOG(WARNING) << "Library " << fileName << " must be uncompressed to mmap it"; return false; } - if ((entry.offset & (constants().blockSize - 1)) != 0) { + if (!entryPageAligned) { LOG(WARNING) << "Library " << fileName << " must be page-aligned to mmap it, offset = 0x" << std::hex << entry.offset; @@ -1665,6 +1679,28 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ continue; } + if (mapFiles && entryUncompressed && entryPageAligned && entry.uncompressed_length > 0) { + incfs::NewMappedFileParams mappedFileParams = { + .sourceId = sourceId, + .sourceOffset = entry.offset, + .size = entry.uncompressed_length, + }; + + if (auto res = mIncFs->makeMappedFile(ifs->control, targetLibPathAbsolute, 0755, + mappedFileParams); + res == 0) { + if (perfLoggingEnabled()) { + auto doneTs = Clock::now(); + LOG(INFO) << "incfs: Mapped " << libName << ": " + << elapsedMcs(startFileTs, doneTs) << "mcs"; + } + continue; + } else { + LOG(WARNING) << "Failed to map file for: '" << targetLibPath << "' errno: " << res + << "; falling back to full extraction"; + } + } + // Create new lib file without signature info incfs::NewFileParams libFileParams = { .size = entry.uncompressed_length, @@ -1673,7 +1709,7 @@ bool IncrementalService::configureNativeBinaries(StorageId storage, std::string_ .metadata = {targetLibPath.c_str(), (IncFsSize)targetLibPath.size()}, }; incfs::FileId libFileId = idFromMetadata(targetLibPath); - if (auto res = mIncFs->makeFile(ifs->control, targetLibPathAbsolute, 0777, libFileId, + if (auto res = mIncFs->makeFile(ifs->control, targetLibPathAbsolute, 0755, libFileId, libFileParams)) { LOG(ERROR) << "Failed to make file for: " << targetLibPath << " errno: " << res; // If one lib file fails to be created, abort others as well |