summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYi-Yo Chiang <yochiang@google.com>2021-02-12 02:10:58 +0800
committerYo Chiang <yochiang@google.com>2021-02-17 09:02:33 +0000
commit645cdedb2fe69c57fc10df7efe933cbdcadfb8aa (patch)
tree563bad1da605d346df7e4925ea55660be7080d44
parentc4e74fde3115e27c2f754930cfabd4fca2c5f6bf (diff)
downloadgsid-645cdedb2fe69c57fc10df7efe933cbdcadfb8aa.tar.gz
gsid: suggestScratchSize() respect kMinimumFreeSpaceThreshold
gsid should take kMinimumFreeSpaceThreshold into account when calculating the suggested scratch partition size. Also use uint64_t to store any calculated intermediate result, so we can stay confortable from overflowing, and downcast the result to int64_t in the end, after we clamped the value within int64_t range. Bug: 165925766 Bug: 179980369 Test: Install DSU and verify adb remount works Change-Id: I919c723369d7d788c5c83a19e6b87f077fb2521b
-rw-r--r--gsi_service.cpp18
-rw-r--r--libgsi_private.h3
-rw-r--r--partition_installer.cpp4
3 files changed, 14 insertions, 11 deletions
diff --git a/gsi_service.cpp b/gsi_service.cpp
index cc6497a..66e01ee 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -510,20 +510,24 @@ binder::Status GsiService::getAvbPublicKey(AvbPublicKey* dst, int32_t* _aidl_ret
binder::Status GsiService::suggestScratchSize(int64_t* _aidl_return) {
ENFORCE_SYSTEM;
- static constexpr int64_t kMinScratchSize = 512_MiB;
- static constexpr int64_t kMaxScratchSize = 2_GiB;
+ static constexpr uint64_t kMinScratchSize = 512_MiB;
+ static constexpr uint64_t kMaxScratchSize = 2_GiB;
- int64_t size = 0;
+ uint64_t size = 0;
struct statvfs info;
if (statvfs(install_dir_.c_str(), &info)) {
PLOG(ERROR) << "Could not statvfs(" << install_dir_ << ")";
} else {
- const int64_t available_space = static_cast<int64_t>(info.f_bavail) * info.f_frsize;
- LOG(INFO) << "Available space of " << install_dir_ << ": " << available_space;
- // Use up to half of free space. Don't exhaust the storage device with scratch partition.
- size = available_space / 2;
+ // Keep the storage device at least 40% free, plus 1% for jitter.
+ constexpr int jitter = 1;
+ const uint64_t reserved_blocks =
+ static_cast<uint64_t>(info.f_blocks) * (kMinimumFreeSpaceThreshold + jitter) / 100;
+ if (info.f_bavail > reserved_blocks) {
+ size = (info.f_bavail - reserved_blocks) * info.f_frsize;
+ }
}
+ // We can safely downcast the result here, since we clamped the result within int64_t range.
*_aidl_return = std::clamp(size, kMinScratchSize, kMaxScratchSize);
return binder::Status::ok();
}
diff --git a/libgsi_private.h b/libgsi_private.h
index 51c7915..82814a9 100644
--- a/libgsi_private.h
+++ b/libgsi_private.h
@@ -28,5 +28,8 @@ static constexpr char kInstallStatusOk[] = "ok";
static constexpr char kInstallStatusWipe[] = "wipe";
static constexpr char kInstallStatusDisabled[] = "disabled";
+// We are looking for /data to have at least 40% free space.
+static constexpr uint32_t kMinimumFreeSpaceThreshold = 40;
+
} // namespace gsi
} // namespace android
diff --git a/partition_installer.cpp b/partition_installer.cpp
index 35ac884..fea1483 100644
--- a/partition_installer.cpp
+++ b/partition_installer.cpp
@@ -39,10 +39,6 @@ using namespace android::fiemap;
using namespace android::fs_mgr;
using android::base::unique_fd;
-// The default size of userdata.img for GSI.
-// We are looking for /data to have atleast 40% free space
-static constexpr uint32_t kMinimumFreeSpaceThreshold = 40;
-
PartitionInstaller::PartitionInstaller(GsiService* service, const std::string& install_dir,
const std::string& name, const std::string& active_dsu,
int64_t size, bool read_only)