Merge "Fix typo in DSU installation error message"
diff --git a/aidl/android/gsi/IImageService.aidl b/aidl/android/gsi/IImageService.aidl
index 1195c00..db348ba 100644
--- a/aidl/android/gsi/IImageService.aidl
+++ b/aidl/android/gsi/IImageService.aidl
@@ -98,4 +98,9 @@
* @return True on success, false otherwise.
*/
void zeroFillNewImage(@utf8InCpp String name, long bytes);
+
+ /**
+ * Find and remove all images in the containing folder of this instance.
+ */
+ void removeAllImages();
}
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 14e7640..5ef4914 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -448,6 +448,7 @@
binder::Status backingImageExists(const std::string& name, bool* _aidl_return) override;
binder::Status isImageMapped(const std::string& name, bool* _aidl_return) override;
binder::Status zeroFillNewImage(const std::string& name, int64_t bytes) override;
+ binder::Status removeAllImages() override;
private:
bool CheckUid();
@@ -543,6 +544,16 @@
return binder::Status::ok();
}
+binder::Status ImageService::removeAllImages() {
+ if (!CheckUid()) return UidSecurityError();
+
+ std::lock_guard<std::mutex> guard(parent_->lock());
+ if (!impl_->RemoveAllImages()) {
+ return BinderError("Failed to remove all images");
+ }
+ return binder::Status::ok();
+}
+
bool ImageService::CheckUid() {
return uid_ == IPCThreadState::self()->getCallingUid();
}
diff --git a/libfiemap/binder.cpp b/libfiemap/binder.cpp
index dcb887a..49779f4 100644
--- a/libfiemap/binder.cpp
+++ b/libfiemap/binder.cpp
@@ -42,6 +42,7 @@
bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
std::string* dev) override;
bool ZeroFillNewImage(const std::string& name, uint64_t bytes) override;
+ bool RemoveAllImages() override;
std::vector<std::string> GetAllBackingImages() override;
@@ -152,6 +153,16 @@
return true;
}
+bool ImageManagerBinder::RemoveAllImages() {
+ auto status = manager_->removeAllImages();
+ if (!status.isOk()) {
+ LOG(ERROR) << __PRETTY_FUNCTION__
+ << " binder returned: " << status.exceptionMessage().string();
+ return false;
+ }
+ return true;
+}
+
static android::sp<IGsid> AcquireIGsid(const std::chrono::milliseconds& timeout_ms) {
if (android::base::GetProperty("init.svc.gsid", "") != "running") {
if (!android::base::SetProperty("ctl.start", "gsid") ||
diff --git a/libfiemap/fiemap_writer.cpp b/libfiemap/fiemap_writer.cpp
index 9b947e2..4f26387 100644
--- a/libfiemap/fiemap_writer.cpp
+++ b/libfiemap/fiemap_writer.cpp
@@ -530,7 +530,69 @@
return false;
}
- *num_extents = fiemap.fm_mapped_extents;
+ if (num_extents) {
+ *num_extents = fiemap.fm_mapped_extents;
+ }
+ return true;
+}
+
+static bool IsValidExtent(const fiemap_extent* extent, std::string_view file_path) {
+ if (extent->fe_flags & kUnsupportedExtentFlags) {
+ LOG(ERROR) << "Extent at location " << extent->fe_logical << " of file " << file_path
+ << " has unsupported flags";
+ return false;
+ }
+ return true;
+}
+
+static bool IsLastExtent(const fiemap_extent* extent) {
+ if (!(extent->fe_flags & FIEMAP_EXTENT_LAST)) {
+ LOG(ERROR) << "Extents are being received out-of-order";
+ return false;
+ }
+ return true;
+}
+
+static bool FiemapToExtents(struct fiemap* fiemap, std::vector<struct fiemap_extent>* extents,
+ uint32_t num_extents, std::string_view file_path) {
+ if (num_extents == 0) return false;
+
+ const struct fiemap_extent* last_extent = &fiemap->fm_extents[num_extents - 1];
+ if (!IsLastExtent(last_extent)) {
+ LOG(ERROR) << "FIEMAP did not return a final extent for file: " << file_path;
+ return false;
+ }
+
+ // Iterate through each extent, read and make sure its valid before adding it to the vector
+ // merging contiguous extents.
+ fiemap_extent* prev = &fiemap->fm_extents[0];
+ if (!IsValidExtent(prev, file_path)) return false;
+
+ for (uint32_t i = 1; i < num_extents; i++) {
+ fiemap_extent* next = &fiemap->fm_extents[i];
+
+ // Make sure extents are returned in order
+ if (next != last_extent && IsLastExtent(next)) return false;
+
+ // Check if extent's flags are valid
+ if (!IsValidExtent(next, file_path)) return false;
+
+ // Check if the current extent is contiguous with the previous one.
+ // An extent can be combined with its predecessor only if:
+ // 1. There is no physical space between the previous and the current
+ // extent, and
+ // 2. The physical distance between the previous and current extent
+ // corresponds to their logical distance (contiguous mapping).
+ if (prev->fe_physical + prev->fe_length == next->fe_physical &&
+ next->fe_physical - prev->fe_physical == next->fe_logical - prev->fe_logical) {
+ prev->fe_length += next->fe_length;
+ } else {
+ extents->emplace_back(*prev);
+ prev = next;
+ }
+ }
+ extents->emplace_back(*prev);
+
return true;
}
@@ -575,27 +637,7 @@
return false;
}
- const struct fiemap_extent* last_extent = &fiemap->fm_extents[num_extents - 1];
- if (!(last_extent->fe_flags & FIEMAP_EXTENT_LAST)) {
- LOG(ERROR) << "FIEMAP did not return a final extent for file: " << file_path;
- return false;
- }
-
- // Iterate through each extent read and make sure its valid before adding it to the vector
- for (uint32_t i = 0; i < num_extents; i++) {
- const struct fiemap_extent* extent = &fiemap->fm_extents[i];
- if (extent->fe_flags & kUnsupportedExtentFlags) {
- LOG(ERROR) << "Extent " << i + 1 << " of file " << file_path
- << " has unsupported flags";
- return false;
- }
- if ((extent->fe_flags & FIEMAP_EXTENT_LAST) && extent != last_extent) {
- LOG(ERROR) << "Extents are being received out-of-order";
- return false;
- }
- extents->emplace_back(*extent);
- }
- return true;
+ return FiemapToExtents(fiemap, extents, num_extents, file_path);
}
static bool ReadFibmap(int file_fd, const std::string& file_path,
diff --git a/libfiemap/include/libfiemap/image_manager.h b/libfiemap/include/libfiemap/image_manager.h
index efbe9bd..5ff4628 100644
--- a/libfiemap/include/libfiemap/image_manager.h
+++ b/libfiemap/include/libfiemap/image_manager.h
@@ -91,6 +91,9 @@
// whole file if filled with zeros.
virtual bool ZeroFillNewImage(const std::string& name, uint64_t bytes) = 0;
+ // Find and remove all images and metadata for this manager.
+ virtual bool RemoveAllImages() = 0;
+
virtual bool UnmapImageIfExists(const std::string& name);
};
@@ -115,15 +118,13 @@
bool IsImageMapped(const std::string& name) override;
bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
std::string* dev) override;
+ bool RemoveAllImages() override;
std::vector<std::string> GetAllBackingImages();
// Same as CreateBackingImage, but provides a progress notification.
bool CreateBackingImage(const std::string& name, uint64_t size, int flags,
std::function<bool(uint64_t, uint64_t)>&& on_progress);
- // Find and remove all images and metadata for a given image dir.
- bool RemoveAllImages();
-
// Returns true if the named partition exists. This does not check the
// consistency of the backing image/data file.
bool PartitionExists(const std::string& name);