Loading services/incremental/IncrementalService.cpp +40 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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, Loading @@ -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 Loading services/incremental/ServiceWrappers.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -134,10 +134,11 @@ private: } mLooper; }; class RealIncFs : public IncFsWrapper { class RealIncFs final : public IncFsWrapper { public: RealIncFs() = default; ~RealIncFs() final = default; Features features() const final { return incfs::features(); } void listExistingMounts(const ExistingMountCallback& cb) const final { for (auto mount : incfs::defaultMountRegistry().copyMounts()) { auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it. Loading @@ -153,6 +154,10 @@ public: incfs::NewFileParams params) const final { return incfs::makeFile(control, path, mode, id, params); } ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode, incfs::NewMappedFileParams params) const final { return incfs::makeMappedFile(control, path, mode, params); } ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final { return incfs::makeDir(control, path, mode); } Loading services/incremental/ServiceWrappers.h +4 −0 Original line number Diff line number Diff line Loading @@ -77,18 +77,22 @@ public: using ErrorCode = incfs::ErrorCode; using UniqueFd = incfs::UniqueFd; using WaitResult = incfs::WaitResult; using Features = incfs::Features; using ExistingMountCallback = std::function<void(std::string_view root, std::string_view backingDir, std::span<std::pair<std::string_view, std::string_view>> binds)>; virtual ~IncFsWrapper() = default; virtual Features features() const = 0; virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0; virtual Control openMount(std::string_view path) const = 0; virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs, IncFsFd blocksWritten) const = 0; virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id, incfs::NewFileParams params) const = 0; virtual ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode, incfs::NewMappedFileParams params) const = 0; virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0; virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0; virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0; Loading services/incremental/test/IncrementalServiceTest.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ private: class MockIncFs : public IncFsWrapper { public: MOCK_CONST_METHOD0(features, Features()); MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb)); MOCK_CONST_METHOD1(openMount, Control(std::string_view path)); MOCK_CONST_METHOD4(createControl, Loading @@ -330,6 +331,9 @@ public: MOCK_CONST_METHOD5(makeFile, ErrorCode(const Control& control, std::string_view path, int mode, FileId id, NewFileParams params)); MOCK_CONST_METHOD4(makeMappedFile, ErrorCode(const Control& control, std::string_view path, int mode, NewMappedFileParams params)); MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode)); MOCK_CONST_METHOD3(makeDirs, ErrorCode(const Control& control, std::string_view path, int mode)); Loading Loading
services/incremental/IncrementalService.cpp +40 −4 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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, Loading @@ -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 Loading
services/incremental/ServiceWrappers.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -134,10 +134,11 @@ private: } mLooper; }; class RealIncFs : public IncFsWrapper { class RealIncFs final : public IncFsWrapper { public: RealIncFs() = default; ~RealIncFs() final = default; Features features() const final { return incfs::features(); } void listExistingMounts(const ExistingMountCallback& cb) const final { for (auto mount : incfs::defaultMountRegistry().copyMounts()) { auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it. Loading @@ -153,6 +154,10 @@ public: incfs::NewFileParams params) const final { return incfs::makeFile(control, path, mode, id, params); } ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode, incfs::NewMappedFileParams params) const final { return incfs::makeMappedFile(control, path, mode, params); } ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final { return incfs::makeDir(control, path, mode); } Loading
services/incremental/ServiceWrappers.h +4 −0 Original line number Diff line number Diff line Loading @@ -77,18 +77,22 @@ public: using ErrorCode = incfs::ErrorCode; using UniqueFd = incfs::UniqueFd; using WaitResult = incfs::WaitResult; using Features = incfs::Features; using ExistingMountCallback = std::function<void(std::string_view root, std::string_view backingDir, std::span<std::pair<std::string_view, std::string_view>> binds)>; virtual ~IncFsWrapper() = default; virtual Features features() const = 0; virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0; virtual Control openMount(std::string_view path) const = 0; virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs, IncFsFd blocksWritten) const = 0; virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id, incfs::NewFileParams params) const = 0; virtual ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode, incfs::NewMappedFileParams params) const = 0; virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0; virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0; virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0; Loading
services/incremental/test/IncrementalServiceTest.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -322,6 +322,7 @@ private: class MockIncFs : public IncFsWrapper { public: MOCK_CONST_METHOD0(features, Features()); MOCK_CONST_METHOD1(listExistingMounts, void(const ExistingMountCallback& cb)); MOCK_CONST_METHOD1(openMount, Control(std::string_view path)); MOCK_CONST_METHOD4(createControl, Loading @@ -330,6 +331,9 @@ public: MOCK_CONST_METHOD5(makeFile, ErrorCode(const Control& control, std::string_view path, int mode, FileId id, NewFileParams params)); MOCK_CONST_METHOD4(makeMappedFile, ErrorCode(const Control& control, std::string_view path, int mode, NewMappedFileParams params)); MOCK_CONST_METHOD3(makeDir, ErrorCode(const Control& control, std::string_view path, int mode)); MOCK_CONST_METHOD3(makeDirs, ErrorCode(const Control& control, std::string_view path, int mode)); Loading