11d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey/* 21d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * Copyright (C) 2015 The Android Open Source Project 31d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * 41d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 51d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * you may not use this file except in compliance with the License. 61d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * You may obtain a copy of the License at 71d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * 81d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 91d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * 101d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 111d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 121d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * See the License for the specific language governing permissions and 141d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey * limitations under the License. 151d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey */ 161d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 171d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include "MoveTask.h" 181d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include "Utils.h" 191d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include "VolumeManager.h" 201d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include "ResponseCode.h" 211d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 227e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/stringprintf.h> 237e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/logging.h> 241d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include <private/android_filesystem_config.h> 25c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey#include <hardware_legacy/power.h> 261d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 271d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include <dirent.h> 281d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include <sys/wait.h> 291d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 30cc5d58085850e6643c82b9124477e19bd092b9a9Chih-Hung Hsieh#define CONSTRAIN(amount, low, high) ((amount) < (low) ? (low) : ((amount) > (high) ? (high) : (amount))) 311d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 32fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#define EXEC_BLOCKING 0 33fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey 341d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyusing android::base::StringPrintf; 351d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 361d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeynamespace android { 371d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeynamespace vold { 381d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 391d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey// TODO: keep in sync with PackageManager 401d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic const int kMoveSucceeded = -100; 411d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic const int kMoveFailedInternalError = -6; 421d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic const char* kCpPath = "/system/bin/cp"; 441d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic const char* kRmPath = "/system/bin/rm"; 451d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 46c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkeystatic const char* kWakeLock = "MoveTask"; 47c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey 481d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff SharkeyMoveTask::MoveTask(const std::shared_ptr<VolumeBase>& from, 491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey const std::shared_ptr<VolumeBase>& to) : 501d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey mFrom(from), mTo(to) { 511d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 521d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 531d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff SharkeyMoveTask::~MoveTask() { 541d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 551d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 561d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyvoid MoveTask::start() { 571d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey mThread = std::thread(&MoveTask::run, this); 581d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 591d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 601d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic void notifyProgress(int progress) { 611d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey VolumeManager::Instance()->getBroadcaster()->sendBroadcast(ResponseCode::MoveStatus, 621d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey StringPrintf("%d", progress).c_str(), false); 631d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 641d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 651d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd) { 661d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey DIR* dir = opendir(path.c_str()); 671d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (dir == NULL) { 681d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return -1; 691d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 701d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey bool found = false; 711d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey struct dirent* ent; 721d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey while ((ent = readdir(dir)) != NULL) { 731d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if ((!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, ".."))) { 741d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey continue; 751d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 761d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back(StringPrintf("%s/%s", path.c_str(), ent->d_name)); 771d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey found = true; 781d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 791d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey closedir(dir); 801d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return found ? OK : -1; 811d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 821d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 831d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic status_t execRm(const std::string& path, int startProgress, int stepProgress) { 841d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(startProgress); 851d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 861d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t expectedBytes = GetTreeBytes(path); 871d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t startFreeBytes = GetFreeBytes(path); 881d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 891d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey std::vector<std::string> cmd; 901d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back(kRmPath); 911d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-f"); /* force: remove without confirmation, no error if it doesn't exist */ 921d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-R"); /* recursive: remove directory contents */ 931d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pushBackContents(path, cmd) != OK) { 941d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(WARNING) << "No contents in " << path; 951d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return OK; 961d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 971d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 98fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#if EXEC_BLOCKING 99fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey return ForkExecvp(cmd); 100fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#else 1011d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey pid_t pid = ForkExecvpAsync(cmd); 1021d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pid == -1) return -1; 1031d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1041d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int status; 1051d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey while (true) { 1061d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (waitpid(pid, &status, WNOHANG) == pid) { 1071d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (WIFEXITED(status)) { 1081d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(DEBUG) << "Finished rm with status " << WEXITSTATUS(status); 1091d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return (WEXITSTATUS(status) == 0) ? OK : -1; 1101d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } else { 1111d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey break; 1121d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1131d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1141d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1151d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey sleep(1); 1161d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t deltaFreeBytes = GetFreeBytes(path) - startFreeBytes; 1171d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(startProgress + CONSTRAIN((int) 1181d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress)); 1191d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1201d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return -1; 121fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#endif 1221d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 1231d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1241d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic status_t execCp(const std::string& fromPath, const std::string& toPath, 1251d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int startProgress, int stepProgress) { 1261d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(startProgress); 1271d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1281d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t expectedBytes = GetTreeBytes(fromPath); 1291d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t startFreeBytes = GetFreeBytes(toPath); 1301d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 131a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey if (expectedBytes > startFreeBytes) { 132a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey LOG(ERROR) << "Data size " << expectedBytes << " is too large to fit in free space " 133a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey << startFreeBytes; 134a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey return -1; 135a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey } 136a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey 1371d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey std::vector<std::string> cmd; 1381d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back(kCpPath); 1391d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-p"); /* preserve timestamps, ownership, and permissions */ 1401d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-R"); /* recurse into subdirectories (DEST must be a directory) */ 1411d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-P"); /* Do not follow symlinks [default] */ 1421d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back("-d"); /* don't dereference symlinks */ 1431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pushBackContents(fromPath, cmd) != OK) { 1441d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(WARNING) << "No contents in " << fromPath; 1451d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return OK; 1461d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1471d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey cmd.push_back(toPath.c_str()); 1481d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 149fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#if EXEC_BLOCKING 150fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey return ForkExecvp(cmd); 151fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#else 1521d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey pid_t pid = ForkExecvpAsync(cmd); 1531d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pid == -1) return -1; 1541d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1551d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int status; 1561d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey while (true) { 1571d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (waitpid(pid, &status, WNOHANG) == pid) { 1581d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (WIFEXITED(status)) { 1591d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(DEBUG) << "Finished cp with status " << WEXITSTATUS(status); 1601d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return (WEXITSTATUS(status) == 0) ? OK : -1; 1611d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } else { 1621d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey break; 1631d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1641d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1651d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1661d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey sleep(1); 1671d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t deltaFreeBytes = startFreeBytes - GetFreeBytes(toPath); 1681d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(startProgress + CONSTRAIN((int) 1691d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress)); 1701d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 1711d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return -1; 172fce701b5f164fa0f135b008aafd84c5bf0ce7173Jeff Sharkey#endif 1731d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 1741d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1751d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic void bringOffline(const std::shared_ptr<VolumeBase>& vol) { 1761d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->destroy(); 1771d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->setSilent(true); 1781d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->create(); 1791d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->setMountFlags(0); 1801d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->mount(); 1811d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 1821d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1831d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic void bringOnline(const std::shared_ptr<VolumeBase>& vol) { 1841d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->destroy(); 1851d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->setSilent(false); 1861d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey vol->create(); 1871d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 1881d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1891d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyvoid MoveTask::run() { 190c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock); 191c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey 1921d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey std::string fromPath; 1931d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey std::string toPath; 1941d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1951d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // TODO: add support for public volumes 1961d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (mFrom->getType() != VolumeBase::Type::kEmulated) goto fail; 1971d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (mTo->getType() != VolumeBase::Type::kEmulated) goto fail; 1981d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 1991d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // Step 1: tear down volumes and mount silently without making 2001d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // visible to userspace apps 2017f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard { 2027f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock()); 2037f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOffline(mFrom); 2047f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOffline(mTo); 2057f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard } 2061d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2071d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey fromPath = mFrom->getInternalPath(); 2081d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey toPath = mTo->getInternalPath(); 2091d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2101d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // Step 2: clean up any stale data 2111d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (execRm(toPath, 10, 10) != OK) { 2121d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey goto fail; 2131d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 2141d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2151d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // Step 3: perform actual copy 2161d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (execCp(fromPath, toPath, 20, 60) != OK) { 21777f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard goto copy_fail; 2181d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 2191d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2201d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // NOTE: MountService watches for this magic value to know 2211d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // that move was successful 2221d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(82); 2237f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard { 2247f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock()); 2257f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOnline(mFrom); 2267f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOnline(mTo); 2277f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard } 2281d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2291d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // Step 4: clean up old data 2301d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (execRm(fromPath, 85, 15) != OK) { 2311d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey goto fail; 2321d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 2331d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2341d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(kMoveSucceeded); 235c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey release_wake_lock(kWakeLock); 2361d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return; 23777f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard 23877f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baardcopy_fail: 23977f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard // if we failed to copy the data we should not leave it laying around 24077f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard // in target location. Do not check return value, we can not do any 24177f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard // useful anyway. 24277f156d9f0e683d4d1cf5e1e4327c39d73c9247cHenrik Baard execRm(toPath, 80, 1); 2431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyfail: 2447f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard { 2457f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock()); 2467f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOnline(mFrom); 2477f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard bringOnline(mTo); 2487f52bca4850ca7dd1c1c3424283575c778424c97Henrik Baard } 2491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey notifyProgress(kMoveFailedInternalError); 250c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey release_wake_lock(kWakeLock); 2511d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return; 2521d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 2531d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2541d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} // namespace vold 2551d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} // namespace android 256