OSDN Git Service

Merge "Add ROLLBACK_RESISTANCE tag to key usage" into sc-dev am: 8f19fd90e3 am: 7c5c6...
[android-x86/system-vold.git] / MoveStorage.cpp
index 4624026..54e28a9 100644 (file)
 #include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
-#include <hardware_legacy/power.h>
 #include <private/android_filesystem_config.h>
+#include <wakelock/wakelock.h>
 
 #include <thread>
 
 #include <dirent.h>
 #include <sys/wait.h>
 
-#define CONSTRAIN(amount, low, high) ((amount) < (low) ? (low) : ((amount) > (high) ? (high) : (amount)))
+#define CONSTRAIN(amount, low, high) \
+    ((amount) < (low) ? (low) : ((amount) > (high) ? (high) : (amount)))
 
 static const char* kPropBlockingExec = "persist.sys.blocking_exec";
 
@@ -48,38 +49,36 @@ static const char* kRmPath = "/system/bin/rm";
 static const char* kWakeLock = "MoveTask";
 
 static void notifyProgress(int progress,
-        const android::sp<android::os::IVoldTaskListener>& listener) {
+                           const android::sp<android::os::IVoldTaskListener>& listener) {
     if (listener) {
         android::os::PersistableBundle extras;
         listener->onStatus(progress, extras);
     }
 }
 
-static status_t pushBackContents(const std::string& path, std::vector<std::string>& cmd,
-        bool addWildcard) {
-    DIR* dir = opendir(path.c_str());
-    if (dir == NULL) {
-        return -1;
+static bool pushBackContents(const std::string& path, std::vector<std::string>& cmd,
+                             int searchLevels) {
+    if (searchLevels == 0) {
+        cmd.emplace_back(path);
+        return true;
+    }
+    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(path.c_str()), closedir);
+    if (!dirp) {
+        PLOG(ERROR) << "Unable to open directory: " << path;
+        return false;
     }
     bool found = false;
     struct dirent* ent;
-    while ((ent = readdir(dir)) != NULL) {
-        if ((!strcmp(ent->d_name, ".")) || (!strcmp(ent->d_name, ".."))) {
-            continue;
-        }
-        if (addWildcard) {
-            cmd.push_back(StringPrintf("%s/%s/*", path.c_str(), ent->d_name));
-        } else {
-            cmd.push_back(StringPrintf("%s/%s", path.c_str(), ent->d_name));
-        }
-        found = true;
+    while ((ent = readdir(dirp.get())) != NULL) {
+        if (IsDotOrDotDot(*ent)) continue;
+        auto subdir = path + "/" + ent->d_name;
+        found |= pushBackContents(subdir, cmd, searchLevels - 1);
     }
-    closedir(dir);
-    return found ? OK : -1;
+    return found;
 }
 
 static status_t execRm(const std::string& path, int startProgress, int stepProgress,
-        const android::sp<android::os::IVoldTaskListener>& listener) {
+                       const android::sp<android::os::IVoldTaskListener>& listener) {
     notifyProgress(startProgress, listener);
 
     uint64_t expectedBytes = GetTreeBytes(path);
@@ -89,7 +88,7 @@ static status_t execRm(const std::string& path, int startProgress, int stepProgr
     cmd.push_back(kRmPath);
     cmd.push_back("-f"); /* force: remove without confirmation, no error if it doesn't exist */
     cmd.push_back("-R"); /* recursive: remove directory contents */
-    if (pushBackContents(path, cmd, true) != OK) {
+    if (!pushBackContents(path, cmd, 2)) {
         LOG(WARNING) << "No contents in " << path;
         return OK;
     }
@@ -114,14 +113,17 @@ static status_t execRm(const std::string& path, int startProgress, int stepProgr
 
         sleep(1);
         uint64_t deltaFreeBytes = GetFreeBytes(path) - startFreeBytes;
-        notifyProgress(startProgress + CONSTRAIN((int)
-                ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress), listener);
+        notifyProgress(
+            startProgress +
+                CONSTRAIN((int)((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress),
+            listener);
     }
     return -1;
 }
 
 static status_t execCp(const std::string& fromPath, const std::string& toPath, int startProgress,
-        int stepProgress, const android::sp<android::os::IVoldTaskListener>& listener) {
+                       int stepProgress,
+                       const android::sp<android::os::IVoldTaskListener>& listener) {
     notifyProgress(startProgress, listener);
 
     uint64_t expectedBytes = GetTreeBytes(fromPath);
@@ -129,7 +131,7 @@ static status_t execCp(const std::string& fromPath, const std::string& toPath, i
 
     if (expectedBytes > startFreeBytes) {
         LOG(ERROR) << "Data size " << expectedBytes << " is too large to fit in free space "
-                << startFreeBytes;
+                   << startFreeBytes;
         return -1;
     }
 
@@ -139,7 +141,7 @@ static status_t execCp(const std::string& fromPath, const std::string& toPath, i
     cmd.push_back("-R"); /* recurse into subdirectories (DEST must be a directory) */
     cmd.push_back("-P"); /* Do not follow symlinks [default] */
     cmd.push_back("-d"); /* don't dereference symlinks */
-    if (pushBackContents(fromPath, cmd, false) != OK) {
+    if (!pushBackContents(fromPath, cmd, 1)) {
         LOG(WARNING) << "No contents in " << fromPath;
         return OK;
     }
@@ -165,8 +167,10 @@ static status_t execCp(const std::string& fromPath, const std::string& toPath, i
 
         sleep(1);
         uint64_t deltaFreeBytes = startFreeBytes - GetFreeBytes(toPath);
-        notifyProgress(startProgress + CONSTRAIN((int)
-                ((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress), listener);
+        notifyProgress(
+            startProgress +
+                CONSTRAIN((int)((deltaFreeBytes * stepProgress) / expectedBytes), 0, stepProgress),
+            listener);
     }
     return -1;
 }
@@ -186,8 +190,8 @@ static void bringOnline(const std::shared_ptr<VolumeBase>& vol) {
 }
 
 static status_t moveStorageInternal(const std::shared_ptr<VolumeBase>& from,
-        const std::shared_ptr<VolumeBase>& to,
-        const android::sp<android::os::IVoldTaskListener>& listener) {
+                                    const std::shared_ptr<VolumeBase>& to,
+                                    const android::sp<android::os::IVoldTaskListener>& listener) {
     std::string fromPath;
     std::string toPath;
 
@@ -239,26 +243,29 @@ copy_fail:
     // useful anyway.
     execRm(toPath, 80, 1, listener);
 fail:
+    // clang-format off
     {
         std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock());
         bringOnline(from);
         bringOnline(to);
     }
+    // clang-format on
     notifyProgress(kMoveFailedInternalError, listener);
     return -1;
 }
 
 void MoveStorage(const std::shared_ptr<VolumeBase>& from, const std::shared_ptr<VolumeBase>& to,
-        const android::sp<android::os::IVoldTaskListener>& listener) {
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, kWakeLock);
+                 const android::sp<android::os::IVoldTaskListener>& listener) {
+    auto wl = android::wakelock::WakeLock::tryGet(kWakeLock);
+    if (!wl.has_value()) {
+        return;
+    }
 
     android::os::PersistableBundle extras;
     status_t res = moveStorageInternal(from, to, listener);
     if (listener) {
         listener->onFinished(res, extras);
     }
-
-    release_wake_lock(kWakeLock);
 }
 
 }  // namespace vold