diff options
author | Yo Chiang <yochiang@google.com> | 2020-08-25 07:47:02 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-08-25 07:47:02 +0000 |
commit | dc8697e37290bfb78171bbb1c55b5b86c0d9d948 (patch) | |
tree | 397361d51990990440e2241eb51119069d16162e | |
parent | 6c1d2827fd90f7894a071269bd8c22cc8d062ff8 (diff) | |
parent | 99ab518ed6b7fae95ba29b132227f993e0a099d0 (diff) | |
download | gsid-dc8697e37290bfb78171bbb1c55b5b86c0d9d948.tar.gz |
Merge changes I3e283232,Iee004bc2,Ie4d798c9,If977b4da
* changes:
GsiService::enableGsi() checks return code of FinishInstall()
Refactor ~PartitionInstaller() and add FinishInstall()
Refactor and rename Finish() to CheckInstallState()
Check install status in ~PartitionInstaller()
-rw-r--r-- | gsi_service.cpp | 6 | ||||
-rw-r--r-- | partition_installer.cpp | 52 | ||||
-rw-r--r-- | partition_installer.h | 15 |
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_; }; |