summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYo Chiang <yochiang@google.com>2020-08-25 08:18:46 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-08-25 08:18:46 +0000
commit31c838f0394f586d7b2329dd95d8507a35d16312 (patch)
tree397361d51990990440e2241eb51119069d16162e
parent6c1d2827fd90f7894a071269bd8c22cc8d062ff8 (diff)
parentdc8697e37290bfb78171bbb1c55b5b86c0d9d948 (diff)
downloadgsid-31c838f0394f586d7b2329dd95d8507a35d16312.tar.gz
Merge changes I3e283232,Iee004bc2,Ie4d798c9,If977b4da am: dc8697e372
Original change: https://android-review.googlesource.com/c/platform/system/gsid/+/1404707 Change-Id: Ifb459a1f04caa01234c93da8144d07ef813f152a
-rw-r--r--gsi_service.cpp6
-rw-r--r--partition_installer.cpp52
-rw-r--r--partition_installer.h15
3 files changed, 39 insertions, 34 deletions
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 1bcd3dc..490655c 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -272,7 +272,13 @@ binder::Status GsiService::enableGsi(bool one_shot, const std::string& dsuSlot,
}
if (installer_) {
ENFORCE_SYSTEM;
+ int status = installer_->FinishInstall();
installer_ = {};
+ if (status != IGsiService::INSTALL_OK) {
+ *_aidl_return = status;
+ LOG(ERROR) << "Installation failed, cannot enable DSU for slot: " << dsuSlot;
+ return binder::Status::ok();
+ }
// Note: create the install status file last, since this is the actual boot
// indicator.
if (!SetBootMode(one_shot) || !CreateInstallStatusFile()) {
diff --git a/partition_installer.cpp b/partition_installer.cpp
index 357df50..35ac884 100644
--- a/partition_installer.cpp
+++ b/partition_installer.cpp
@@ -56,33 +56,32 @@ PartitionInstaller::PartitionInstaller(GsiService* service, const std::string& i
}
PartitionInstaller::~PartitionInstaller() {
- Finish();
- if (!succeeded_) {
- // Close open handles before we remove files.
- system_device_ = nullptr;
- PostInstallCleanup(images_.get());
+ if (FinishInstall() != IGsiService::INSTALL_OK) {
+ LOG(ERROR) << "Installation failed: install_dir=" << install_dir_
+ << ", dsu_slot=" << active_dsu_ << ", partition_name=" << name_;
}
if (IsAshmemMapped()) {
UnmapAshmem();
}
}
-void PartitionInstaller::PostInstallCleanup() {
- auto manager = ImageManager::Open(MetadataDir(active_dsu_), install_dir_);
- if (!manager) {
- LOG(ERROR) << "Could not open image manager";
- return;
- }
- return PostInstallCleanup(manager.get());
-}
-
-void PartitionInstaller::PostInstallCleanup(ImageManager* manager) {
- std::string file = GetBackingFile(name_);
- if (manager->IsImageMapped(file)) {
- LOG(ERROR) << "unmap " << file;
- manager->UnmapImageDevice(file);
+int PartitionInstaller::FinishInstall() {
+ if (finished_) {
+ return finished_status_;
+ }
+ finished_ = true;
+ finished_status_ = CheckInstallState();
+ system_device_ = nullptr;
+ if (finished_status_ != IGsiService::INSTALL_OK) {
+ auto file = GetBackingFile(name_);
+ LOG(ERROR) << "Installation failed, clean up: " << file;
+ if (images_->IsImageMapped(file)) {
+ LOG(ERROR) << "unmap " << file;
+ images_->UnmapImageDevice(file);
+ }
+ images_->DeleteBackingImage(file);
}
- manager->DeleteBackingImage(file);
+ return finished_status_;
}
int PartitionInstaller::StartInstall() {
@@ -96,7 +95,6 @@ int PartitionInstaller::StartInstall() {
if (!Format()) {
return IGsiService::INSTALL_ERROR_GENERIC;
}
- succeeded_ = true;
} else {
// Map ${name}_gsi so we can write to it.
system_device_ = OpenPartition(GetBackingFile(name_));
@@ -308,26 +306,22 @@ bool PartitionInstaller::Format() {
return true;
}
-int PartitionInstaller::Finish() {
- if (readOnly_ && gsi_bytes_written_ != size_) {
+int PartitionInstaller::CheckInstallState() {
+ if (readOnly_ && !IsFinishedWriting()) {
// We cannot boot if the image is incomplete.
LOG(ERROR) << "image incomplete; expected " << size_ << " bytes, waiting for "
<< (size_ - gsi_bytes_written_) << " bytes";
return IGsiService::INSTALL_ERROR_GENERIC;
}
- if (system_device_ != nullptr && fsync(system_device_->fd())) {
- PLOG(ERROR) << "fsync failed for " << name_ << "_gsi";
+ if (system_device_ != nullptr && fsync(GetPartitionFd())) {
+ PLOG(ERROR) << "fsync failed for " << GetBackingFile(name_);
return IGsiService::INSTALL_ERROR_GENERIC;
}
- system_device_ = {};
-
// If files moved (are no longer pinned), the metadata file will be invalid.
// This check can be removed once b/133967059 is fixed.
if (!images_->Validate()) {
return IGsiService::INSTALL_ERROR_GENERIC;
}
-
- succeeded_ = true;
return IGsiService::INSTALL_OK;
}
diff --git a/partition_installer.h b/partition_installer.h
index 1503648..920af47 100644
--- a/partition_installer.h
+++ b/partition_installer.h
@@ -53,14 +53,17 @@ class PartitionInstaller final {
static int WipeWritable(const std::string& active_dsu, const std::string& install_dir,
const std::string& name);
- // Clean up install state if gsid crashed and restarted.
- void PostInstallCleanup();
- void PostInstallCleanup(ImageManager* manager);
+ // Finish a partition installation and release resources.
+ // If the installation is incomplete or corrupted, the backing image would
+ // be cleaned up and an error code is returned.
+ // No method other than FinishInstall() and ~PartitionInstaller() should be
+ // called after calling this method.
+ // This method is also called by the destructor to free up resources.
+ int FinishInstall();
const std::string& install_dir() const { return install_dir_; }
private:
- int Finish();
int PerformSanityChecks();
int Preallocate();
bool Format();
@@ -82,10 +85,12 @@ class PartitionInstaller final {
bool readOnly_;
// Remaining data we're waiting to receive for the GSI image.
uint64_t gsi_bytes_written_ = 0;
- bool succeeded_ = false;
uint64_t ashmem_size_ = -1;
void* ashmem_data_ = MAP_FAILED;
+ bool finished_ = false;
+ int finished_status_ = 0;
+
std::unique_ptr<MappedDevice> system_device_;
};