diff options
author | Howard Chen <howardsoc@google.com> | 2021-01-07 16:07:52 +0800 |
---|---|---|
committer | Howard Chen <howardsoc@google.com> | 2021-01-22 14:16:21 +0800 |
commit | 3a5e19a5bfb588626b9b39f529316949df93378a (patch) | |
tree | f64e045ffc8170b4ab5e6a9e849b77eea6199ac7 | |
parent | 721a0e4b06184fada0035cce390df9c8b6d8720e (diff) | |
download | gsid-3a5e19a5bfb588626b9b39f529316949df93378a.tar.gz |
Refine the DSU SD card support
Refine the openImageService and allow images to be installed in a SD card.
This also fixes the error when execute the "gsi_tool status" command.
Bug: 171861574
Test: execute following command on a device with a SD card inserted
adb shell am start-activity \
-n com.android.dynsystem/com.android.dynsystem.VerificationActivity \
-a android.os.image.action.START_INSTALL \
-d file:///storage/emulated/0/Download/system.raw.gz \
--el KEY_SYSTEM_SIZE $(du -b system.raw|cut -f1) \
--el KEY_USERDATA_SIZE 4294967296
Change-Id: I764cf66984e74ab66cc4316b087751937e20a242
-rw-r--r-- | gsi_service.cpp | 23 | ||||
-rw-r--r-- | include/libgsi/libgsi.h | 2 |
2 files changed, 21 insertions, 4 deletions
diff --git a/gsi_service.cpp b/gsi_service.cpp index 6d310a4..cc6497a 100644 --- a/gsi_service.cpp +++ b/gsi_service.cpp @@ -116,6 +116,8 @@ int GsiService::SaveInstallation(const std::string& installation) { return INSTALL_OK; } +static bool IsExternalStoragePath(const std::string& path); + binder::Status GsiService::openInstall(const std::string& install_dir, int* _aidl_return) { ENFORCE_SYSTEM; std::lock_guard<std::mutex> guard(lock_); @@ -128,6 +130,15 @@ binder::Status GsiService::openInstall(const std::string& install_dir, int* _aid *_aidl_return = status; return binder::Status::ok(); } + if (access(install_dir_.c_str(), F_OK) != 0 && errno == ENOENT) { + if (IsExternalStoragePath(install_dir_)) { + if (mkdir(install_dir_.c_str(), 0755) != 0) { + PLOG(ERROR) << "Failed to create " << install_dir_; + *_aidl_return = IGsiService::INSTALL_ERROR_GENERIC; + return binder::Status::ok(); + } + } + } std::string message; auto dsu_slot = GetDsuSlot(install_dir_); if (!RemoveFileIfExists(GetCompleteIndication(dsu_slot), &message)) { @@ -752,6 +763,8 @@ bool ImageService::CheckUid() { binder::Status GsiService::openImageService(const std::string& prefix, android::sp<IImageService>* _aidl_return) { + using android::base::StartsWith; + static constexpr char kImageMetadataPrefix[] = "/metadata/gsi/"; static constexpr char kImageDataPrefix[] = "/data/gsi/"; @@ -773,9 +786,11 @@ binder::Status GsiService::openImageService(const std::string& prefix, PLOG(ERROR) << "realpath failed for data: " << in_data_dir; return BinderError("Invalid path"); } - if (!android::base::StartsWith(metadata_dir, kImageMetadataPrefix) || - !android::base::StartsWith(data_dir, kImageDataPrefix)) { - return BinderError("Invalid path"); + if (!StartsWith(metadata_dir, kImageMetadataPrefix)) { + return BinderError("Invalid metadata path"); + } + if (!StartsWith(data_dir, kImageDataPrefix) && !StartsWith(data_dir, kDsuSDPrefix)) { + return BinderError("Invalid data path"); } uid_t uid = IPCThreadState::self()->getCallingUid(); @@ -808,7 +823,7 @@ binder::Status GsiService::CheckUid(AccessLevel level) { } static bool IsExternalStoragePath(const std::string& path) { - if (!android::base::StartsWith(path, "/mnt/media_rw/")) { + if (!android::base::StartsWith(path, kDsuSDPrefix)) { return false; } unique_fd fd(open(path.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); diff --git a/include/libgsi/libgsi.h b/include/libgsi/libgsi.h index 1e3cd07..17066ff 100644 --- a/include/libgsi/libgsi.h +++ b/include/libgsi/libgsi.h @@ -38,6 +38,8 @@ static constexpr char kDsuAvbKeyDir[] = DSU_METADATA_PREFIX "avb/"; static constexpr char kDsuMetadataKeyDirPrefix[] = "/metadata/vold/metadata_encryption/dsu/"; +static constexpr char kDsuSDPrefix[] = "/mnt/media_rw/"; + static inline std::string DsuLpMetadataFile(const std::string& dsu_slot) { return DSU_METADATA_PREFIX + dsu_slot + "/lp_metadata"; } |