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

Commit 7a4cc8c9 authored by aleasto's avatar aleasto Committed by Alessandro Astone
Browse files

recovery: Support writing to Virtual A/B partitions

Change-Id: Ice74e460242a58140fe31240b9fc464848b3aeea
parent c4b3e646
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#include <android-base/unique_fd.h>

#include "install/package.h"
#include "install/snapshot_utils.h"
#include "install/verifier.h"
#include "install/wipe_data.h"
#include "otautil/error_code.h"
@@ -352,6 +353,7 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
  bool device_supports_ab = android::base::GetBoolProperty("ro.build.ab_update", false);
  bool ab_device_supports_nonab = true;
  bool device_only_supports_ab = device_supports_ab && !ab_device_supports_nonab;
  bool device_supports_virtual_ab = android::base::GetBoolProperty("ro.virtual_ab.enabled", false);

  if (package_is_ab) {
    CHECK(package->GetType() == PackageType::kFile);
@@ -368,6 +370,15 @@ static InstallResult TryUpdateBinary(Package* package, bool* wipe_cache,
    }
  }

  if (!package_is_ab && !logical_partitions_mapped()) {
    CreateSnapshotPartitions();
    map_logical_partitions();
  } else if (package_is_ab && device_supports_virtual_ab && logical_partitions_mapped()) {
    LOG(ERROR) << "Logical partitions are mapped. "
               << "Please reboot recovery before installing an OTA update.";
    return INSTALL_ERROR;
  }

  ReadSourceTargetBuild(metadata, log_buffer);

  // The updater in child process writes to the pipe to communicate with recovery.
+3 −1
Original line number Diff line number Diff line
@@ -61,4 +61,6 @@ int setup_install_mounts();
// Returns true if there is /cache in the volumes.
bool HasCache();

void map_logical_partitions();

bool logical_partitions_mapped();
+28 −9
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@
using android::fs_mgr::Fstab;
using android::fs_mgr::FstabEntry;
using android::fs_mgr::ReadDefaultFstab;
using android::dm::DeviceMapper;
using android::dm::DmDeviceState;

static void write_fstab_entry(const FstabEntry& entry, FILE* file) {
  if (entry.fs_type != "emmc" && !entry.fs_mgr_flags.vold_managed && !entry.blk_device.empty() &&
@@ -339,8 +341,6 @@ int format_volume(const std::string& volume) {
  return format_volume(volume, "");
}

static bool logical_partitions_auto_mapped = false;

int setup_install_mounts() {
  if (fstab.empty()) {
    LOG(ERROR) << "can't set up install mounts: no fstab loaded";
@@ -364,7 +364,18 @@ int setup_install_mounts() {
      }
    }
  }
  // Map logical partitions
  return 0;
}

bool HasCache() {
  CHECK(!fstab.empty());
  static bool has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
  return has_cache;
}

static bool logical_partitions_auto_mapped = false;

void map_logical_partitions() {
  if (android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
      !logical_partitions_mapped()) {
    std::string super_name = fs_mgr_get_super_partition_name();
@@ -374,15 +385,23 @@ int setup_install_mounts() {
      logical_partitions_auto_mapped = true;
    }
  }
  return 0;
}

bool HasCache() {
  CHECK(!fstab.empty());
  static bool has_cache = volume_for_mount_point(CACHE_ROOT) != nullptr;
  return has_cache;
bool dm_find_system() {
  auto rec = GetEntryForPath(&fstab, android::fs_mgr::GetSystemRoot());
  if (!rec->fs_mgr_flags.logical) {
    return false;
  }
  // If the fstab entry for system it's a path instead of a name, then it was already mapped
  if (rec->blk_device[0] != '/') {
    if (DeviceMapper::Instance().GetState(rec->blk_device) == DmDeviceState::INVALID) {
      return false;
    }
  }
  return true;
}

bool logical_partitions_mapped() {
  return android::fs_mgr::LogicalPartitionsMapped() || logical_partitions_auto_mapped;
  return android::fs_mgr::LogicalPartitionsMapped() || logical_partitions_auto_mapped ||
      dm_find_system();
}