Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27d58a28 authored by Alan Stokes's avatar Alan Stokes Committed by Automerger Merge Worker
Browse files

Merge "Retry to get and mount CE data directory again" am: 5737120c am: 57fef244

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1479477

Change-Id: I0096c214ff5417cb6a1e57ca57d4f0cf271a02e7
parents 818c1642 57fef244
Loading
Loading
Loading
Loading
+40 −6
Original line number Diff line number Diff line
@@ -804,10 +804,14 @@ static void PrepareDirIfNotPresent(const std::string& dir, mode_t mode, uid_t ui
  PrepareDir(dir, mode, uid, gid, fail_fn);
}

static bool BindMount(const std::string& source_dir, const std::string& target_dir) {
  return !(TEMP_FAILURE_RETRY(mount(source_dir.c_str(), target_dir.c_str(), nullptr,
                                    MS_BIND | MS_REC, nullptr)) == -1);
}

static void BindMount(const std::string& source_dir, const std::string& target_dir,
                      fail_fn_t fail_fn) {
  if (TEMP_FAILURE_RETRY(mount(source_dir.c_str(), target_dir.c_str(), nullptr,
                               MS_BIND | MS_REC, nullptr)) == -1) {
  if (!BindMount(source_dir, target_dir)) {
    fail_fn(CREATE_ERROR("Failed to mount %s to %s: %s",
                         source_dir.c_str(), target_dir.c_str(), strerror(errno)));
  }
@@ -1194,9 +1198,9 @@ static pid_t ForkCommon(JNIEnv* env, bool is_system_server,

// Create an app data directory over tmpfs overlayed CE / DE storage, and bind mount it
// from the actual app data directory in data mirror.
static void createAndMountAppData(std::string_view package_name,
static bool createAndMountAppData(std::string_view package_name,
    std::string_view mirror_pkg_dir_name, std::string_view mirror_data_path,
    std::string_view actual_data_path, fail_fn_t fail_fn) {
    std::string_view actual_data_path, fail_fn_t fail_fn, bool call_fail_fn) {

  char mirrorAppDataPath[PATH_MAX];
  char actualAppDataPath[PATH_MAX];
@@ -1206,6 +1210,29 @@ static void createAndMountAppData(std::string_view package_name,

  PrepareDir(actualAppDataPath, 0700, AID_ROOT, AID_ROOT, fail_fn);

  // Bind mount from original app data directory in mirror.
  if (call_fail_fn) {
    BindMount(mirrorAppDataPath, actualAppDataPath, fail_fn);
  } else if(!BindMount(mirrorAppDataPath, actualAppDataPath)) {
    ALOGW("Failed to mount %s to %s: %s",
          mirrorAppDataPath, actualAppDataPath, strerror(errno));
    return false;
  }
  return true;
}

// There is an app data directory over tmpfs overlaid CE / DE storage
// bind mount it from the actual app data directory in data mirror.
static void mountAppData(std::string_view package_name,
    std::string_view mirror_pkg_dir_name, std::string_view mirror_data_path,
    std::string_view actual_data_path, fail_fn_t fail_fn) {

  char mirrorAppDataPath[PATH_MAX];
  char actualAppDataPath[PATH_MAX];
  snprintf(mirrorAppDataPath, PATH_MAX, "%s/%s", mirror_data_path.data(),
      mirror_pkg_dir_name.data());
  snprintf(actualAppDataPath, PATH_MAX, "%s/%s", actual_data_path.data(), package_name.data());

  // Bind mount from original app data directory in mirror.
  BindMount(mirrorAppDataPath, actualAppDataPath, fail_fn);
}
@@ -1284,10 +1311,17 @@ static void isolateAppDataPerPackage(int userId, std::string_view package_name,
  snprintf(mirrorCePath, PATH_MAX, "%s/%d", mirrorCeParent, userId);
  snprintf(mirrorDePath, PATH_MAX, "/data_mirror/data_de/%s/%d", volume_uuid.data(), userId);

  createAndMountAppData(package_name, package_name, mirrorDePath, actualDePath, fail_fn);
  createAndMountAppData(package_name, package_name, mirrorDePath, actualDePath, fail_fn,
                        true /*call_fail_fn*/);

  std::string ce_data_path = getAppDataDirName(mirrorCePath, package_name, ce_data_inode, fail_fn);
  createAndMountAppData(package_name, ce_data_path, mirrorCePath, actualCePath, fail_fn);
  if (!createAndMountAppData(package_name, ce_data_path, mirrorCePath, actualCePath, fail_fn,
                             false /*call_fail_fn*/)) {
    // CE might unlocks and the name is decrypted
    // get the name and mount again
    ce_data_path=getAppDataDirName(mirrorCePath, package_name, ce_data_inode, fail_fn);
    mountAppData(package_name, ce_data_path, mirrorCePath, actualCePath, fail_fn);
  }
}

// Relabel directory