summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYo Chiang <yochiang@google.com>2020-12-28 19:29:47 +0800
committerYo Chiang <yochiang@google.com>2020-12-30 13:16:10 +0800
commit721a0e4b06184fada0035cce390df9c8b6d8720e (patch)
tree7d3e9b94db70ba9b138f49838fd9bf90ec9cc42b
parentfdd02739c24f76846d37807c17c3424d4f0cf718 (diff)
downloadgsid-721a0e4b06184fada0035cce390df9c8b6d8720e.tar.gz
Add IGsiService::suggestScratchSize()
DSU installation service could call this method to get a suggested scratch partition size, if the DSU guest system would need overlayFS (remount) feature. This size is just a suggestion, and is not guaranteed to work. The caller (framework) should still check if the DSU scratch partition is allocated successfully. The scratch partition allocation could fail if the suggested size is larger than available free space. Bug: 165925766 Test: TH Change-Id: Ie6202d15a76a21f59219a80dc3a20e9405ed7f66
-rw-r--r--Android.bp3
-rw-r--r--aidl/android/gsi/IGsiService.aidl5
-rw-r--r--gsi_service.cpp24
-rw-r--r--gsi_service.h1
4 files changed, 33 insertions, 0 deletions
diff --git a/Android.bp b/Android.bp
index 8e3acaa..cb6c077 100644
--- a/Android.bp
+++ b/Android.bp
@@ -101,6 +101,9 @@ cc_binary {
"libc++fs",
"libvold_binder",
],
+ header_libs: [
+ "libstorage_literals_headers",
+ ],
target: {
android: {
shared_libs: [
diff --git a/aidl/android/gsi/IGsiService.aidl b/aidl/android/gsi/IGsiService.aidl
index 8b38504..f706098 100644
--- a/aidl/android/gsi/IGsiService.aidl
+++ b/aidl/android/gsi/IGsiService.aidl
@@ -229,4 +229,9 @@ interface IGsiService {
* @return 0 on success, an error code on failure.
*/
int getAvbPublicKey(out AvbPublicKey dst);
+
+ /**
+ * Returns the suggested scratch partition size for overlayFS.
+ */
+ long suggestScratchSize();
}
diff --git a/gsi_service.cpp b/gsi_service.cpp
index 14ef1d4..6d310a4 100644
--- a/gsi_service.cpp
+++ b/gsi_service.cpp
@@ -16,6 +16,7 @@
#include "gsi_service.h"
+#include <sys/statvfs.h>
#include <sys/vfs.h>
#include <unistd.h>
@@ -42,6 +43,7 @@
#include <libfiemap/image_manager.h>
#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
+#include <storage_literals/storage_literals.h>
#include "file_paths.h"
#include "libgsi_private.h"
@@ -52,6 +54,7 @@ namespace gsi {
using namespace std::literals;
using namespace android::fs_mgr;
using namespace android::fiemap;
+using namespace android::storage_literals;
using android::base::ReadFileToString;
using android::base::ReadFullyAtOffset;
using android::base::RemoveFileIfExists;
@@ -493,6 +496,27 @@ binder::Status GsiService::getAvbPublicKey(AvbPublicKey* dst, int32_t* _aidl_ret
return binder::Status::ok();
}
+binder::Status GsiService::suggestScratchSize(int64_t* _aidl_return) {
+ ENFORCE_SYSTEM;
+
+ static constexpr int64_t kMinScratchSize = 512_MiB;
+ static constexpr int64_t kMaxScratchSize = 2_GiB;
+
+ int64_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;
+ }
+
+ *_aidl_return = std::clamp(size, kMinScratchSize, kMaxScratchSize);
+ return binder::Status::ok();
+}
+
bool GsiService::CreateInstallStatusFile() {
if (!android::base::WriteStringToFile("0", kDsuInstallStatusFile)) {
PLOG(ERROR) << "write " << kDsuInstallStatusFile;
diff --git a/gsi_service.h b/gsi_service.h
index 3f81786..c9e4e05 100644
--- a/gsi_service.h
+++ b/gsi_service.h
@@ -68,6 +68,7 @@ class GsiService : public BinderService<GsiService>, public BnGsiService {
android::sp<IImageService>* _aidl_return) override;
binder::Status dumpDeviceMapperDevices(std::string* _aidl_return) override;
binder::Status getAvbPublicKey(AvbPublicKey* dst, int32_t* _aidl_return) override;
+ binder::Status suggestScratchSize(int64_t* _aidl_return) override;
// This is in GsiService, rather than GsiInstaller, since we need to access
// it outside of the main lock which protects the unique_ptr.