summaryrefslogtreecommitdiff
path: root/services/incremental/IncrementalService.cpp
diff options
context:
space:
mode:
authorYurii Zubrytskyi <zyy@google.com>2021-02-17 14:24:14 -0800
committerYurii Zubrytskyi <zyy@google.com>2021-02-22 04:05:11 +0000
commita5946f7056fe30957f8eebd2beac06ea389dbbc9 (patch)
tree6404cf7149837c75f6b2b6b34b7db2a06195d512 /services/incremental/IncrementalService.cpp
parentddfb6c46f2e8f943a204ae4cfa65309b4b26d19a (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.cpp44
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