summaryrefslogtreecommitdiff
path: root/cmds/installd/InstalldNativeService.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/installd/InstalldNativeService.cpp')
-rw-r--r--cmds/installd/InstalldNativeService.cpp78
1 files changed, 67 insertions, 11 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index 8146cc6f98..c7d9245d17 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -167,6 +167,15 @@ binder::Status checkArgumentUuid(const std::unique_ptr<std::string>& uuid) {
}
}
+binder::Status checkArgumentUuidTestOrNull(const std::unique_ptr<std::string>& uuid) {
+ if (!uuid || strcmp(uuid->c_str(), kTestUuid) == 0) {
+ return ok();
+ } else {
+ return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
+ StringPrintf("UUID must be null or \"%s\", got: %s", kTestUuid, uuid->c_str()));
+ }
+}
+
binder::Status checkArgumentPackageName(const std::string& packageName) {
if (is_valid_package_name(packageName.c_str())) {
return ok();
@@ -219,6 +228,13 @@ binder::Status checkArgumentPath(const std::unique_ptr<std::string>& path) {
} \
}
+#define CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(uuid) { \
+ auto status = checkArgumentUuidTestOrNull(uuid); \
+ if (!status.isOk()) { \
+ return status; \
+ } \
+} \
+
#define CHECK_ARGUMENT_PACKAGE_NAME(packageName) { \
binder::Status status = \
checkArgumentPackageName((packageName)); \
@@ -768,20 +784,21 @@ static int32_t copy_directory_recursive(const char* from, const char* to) {
binder::Status InstalldNativeService::snapshotAppData(
const std::unique_ptr<std::string>& volumeUuid,
- const std::string& packageName, int32_t user, int32_t storageFlags) {
+ const std::string& packageName, int32_t user, int32_t storageFlags,
+ int64_t* _aidl_return) {
ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
std::lock_guard<std::recursive_mutex> lock(mLock);
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
const char* package_name = packageName.c_str();
- if (volume_uuid && strcmp(volume_uuid, kTestUuid)) {
- return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
- StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid));
- }
-
binder::Status res = ok();
+ // Default result to 0, it will be populated with inode of ce data snapshot
+ // if FLAG_STORAGE_CE has been passed.
+ if (_aidl_return != nullptr) *_aidl_return = 0;
+
bool clear_ce_on_exit = false;
bool clear_de_on_exit = false;
@@ -862,6 +879,16 @@ binder::Status InstalldNativeService::snapshotAppData(
clear_ce_on_exit = true;
return res;
}
+ if (_aidl_return != nullptr) {
+ auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid, user,
+ package_name);
+ rc = get_path_inode(ce_snapshot_path, reinterpret_cast<ino_t*>(_aidl_return));
+ if (rc != 0) {
+ res = error(rc, "Failed to get_path_inode for " + ce_snapshot_path);
+ clear_ce_on_exit = true;
+ return res;
+ }
+ }
}
return res;
@@ -872,17 +899,13 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot(
const int32_t appId, const int64_t ceDataInode, const std::string& seInfo,
const int32_t user, int32_t storageFlags) {
ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
CHECK_ARGUMENT_PACKAGE_NAME(packageName);
std::lock_guard<std::recursive_mutex> lock(mLock);
const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
const char* package_name = packageName.c_str();
- if (volume_uuid && strcmp(volume_uuid, kTestUuid)) {
- return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
- StringPrintf("volumeUuid must be null or \"%s\", got: %s", kTestUuid, volume_uuid));
- }
-
auto from_ce = create_data_misc_ce_rollback_package_path(volume_uuid,
user, package_name);
auto from_de = create_data_misc_de_rollback_package_path(volume_uuid,
@@ -933,6 +956,39 @@ binder::Status InstalldNativeService::restoreAppDataSnapshot(
return restoreconAppData(volumeUuid, packageName, user, storageFlags, appId, seInfo);
}
+binder::Status InstalldNativeService::destroyAppDataSnapshot(
+ const std::unique_ptr<std::string> &volumeUuid, const std::string& packageName,
+ const int32_t user, const int64_t ceSnapshotInode, int32_t storageFlags) {
+ ENFORCE_UID(AID_SYSTEM);
+ CHECK_ARGUMENT_UUID_IS_TEST_OR_NULL(volumeUuid);
+ CHECK_ARGUMENT_PACKAGE_NAME(packageName);
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+
+ const char* volume_uuid = volumeUuid ? volumeUuid->c_str() : nullptr;
+ const char* package_name = packageName.c_str();
+
+ if (storageFlags & FLAG_STORAGE_DE) {
+ auto de_snapshot_path = create_data_misc_de_rollback_package_path(volume_uuid,
+ user, package_name);
+
+ int res = delete_dir_contents_and_dir(de_snapshot_path, true /* ignore_if_missing */);
+ if (res != 0) {
+ return error(res, "Failed clearing snapshot " + de_snapshot_path);
+ }
+ }
+
+ if (storageFlags & FLAG_STORAGE_CE) {
+ auto ce_snapshot_path = create_data_misc_ce_rollback_package_path(volume_uuid,
+ user, package_name, ceSnapshotInode);
+ int res = delete_dir_contents_and_dir(ce_snapshot_path, true /* ignore_if_missing */);
+ if (res != 0) {
+ return error(res, "Failed clearing snapshot " + ce_snapshot_path);
+ }
+ }
+ return ok();
+}
+
+
binder::Status InstalldNativeService::moveCompleteApp(const std::unique_ptr<std::string>& fromUuid,
const std::unique_ptr<std::string>& toUuid, const std::string& packageName,
const std::string& dataAppName, int32_t appId, const std::string& seInfo,