Merge "Added support for FlashSuperLayoutTask"
This commit is contained in:
commit
769ea81c4c
4 changed files with 132 additions and 100 deletions
|
@ -982,7 +982,7 @@ static void DumpInfo() {
|
|||
fprintf(stderr, "--------------------------------------------\n");
|
||||
}
|
||||
|
||||
static std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size) {
|
||||
std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size) {
|
||||
if (max_size <= 0 || max_size > std::numeric_limits<uint32_t>::max()) {
|
||||
die("invalid max size %" PRId64, max_size);
|
||||
}
|
||||
|
@ -1027,7 +1027,7 @@ static uint64_t get_uint_var(const char* var_name) {
|
|||
return value;
|
||||
}
|
||||
|
||||
static int64_t get_sparse_limit(int64_t size) {
|
||||
int64_t get_sparse_limit(int64_t size) {
|
||||
int64_t limit = sparse_limit;
|
||||
if (limit == 0) {
|
||||
// Unlimited, so see what the target device's limit is.
|
||||
|
@ -1161,7 +1161,7 @@ static bool has_vbmeta_partition() {
|
|||
|
||||
// Note: this only works in userspace fastboot. In the bootloader, use
|
||||
// should_flash_in_userspace().
|
||||
static bool is_logical(const std::string& partition) {
|
||||
bool is_logical(const std::string& partition) {
|
||||
std::string value;
|
||||
return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes";
|
||||
}
|
||||
|
@ -1243,8 +1243,7 @@ static void copy_avb_footer(const std::string& partition, struct fastboot_buffer
|
|||
lseek(buf->fd.get(), 0, SEEK_SET);
|
||||
}
|
||||
|
||||
static void flash_partition_files(const std::string& partition,
|
||||
const std::vector<SparsePtr>& files) {
|
||||
void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files) {
|
||||
for (size_t i = 0; i < files.size(); i++) {
|
||||
sparse_file* s = files[i].get();
|
||||
int64_t sz = sparse_file_len(s, true, false);
|
||||
|
@ -1303,7 +1302,7 @@ static int get_slot_count() {
|
|||
return count;
|
||||
}
|
||||
|
||||
static bool supports_AB() {
|
||||
bool supports_AB() {
|
||||
return get_slot_count() >= 2;
|
||||
}
|
||||
|
||||
|
@ -1426,7 +1425,7 @@ void do_for_partitions(const std::string& part, const std::string& slot,
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_retrofit_device() {
|
||||
bool is_retrofit_device() {
|
||||
std::string value;
|
||||
if (fb->GetVar("super-partition-name", &value) != fastboot::SUCCESS) {
|
||||
return false;
|
||||
|
@ -1562,6 +1561,20 @@ static void CancelSnapshotIfNeeded() {
|
|||
}
|
||||
}
|
||||
|
||||
std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot) {
|
||||
auto slot = entry.second;
|
||||
if (slot.empty()) {
|
||||
slot = current_slot;
|
||||
}
|
||||
if (slot.empty()) {
|
||||
return entry.first->part_name;
|
||||
}
|
||||
if (slot == "all") {
|
||||
LOG(FATAL) << "Cannot retrieve a singular name when using all slots";
|
||||
}
|
||||
return entry.first->part_name + "_" + slot;
|
||||
}
|
||||
|
||||
class FlashAllTool {
|
||||
public:
|
||||
FlashAllTool(FlashingPlan* fp);
|
||||
|
@ -1575,15 +1588,12 @@ class FlashAllTool {
|
|||
void FlashImages(const std::vector<std::pair<const Image*, std::string>>& images);
|
||||
void FlashImage(const Image& image, const std::string& slot, fastboot_buffer* buf);
|
||||
void UpdateSuperPartition();
|
||||
bool OptimizedFlashSuper();
|
||||
|
||||
// If the image uses the default slot, or the user specified "all", then
|
||||
// the paired string will be empty. If the image requests a specific slot
|
||||
// (for example, system_other) it is specified instead.
|
||||
using ImageEntry = std::pair<const Image*, std::string>;
|
||||
|
||||
std::string GetPartitionName(const ImageEntry& entry);
|
||||
|
||||
std::vector<ImageEntry> boot_images_;
|
||||
std::vector<ImageEntry> os_images_;
|
||||
FlashingPlan* fp_;
|
||||
|
@ -1612,10 +1622,13 @@ void FlashAllTool::Flash() {
|
|||
// or in bootloader fastboot.
|
||||
FlashImages(boot_images_);
|
||||
|
||||
if (!OptimizedFlashSuper()) {
|
||||
auto flash_super_task = FlashSuperLayoutTask::Initialize(fp_, os_images_);
|
||||
|
||||
if (flash_super_task) {
|
||||
flash_super_task->Run();
|
||||
} else {
|
||||
// Sync the super partition. This will reboot to userspace fastboot if needed.
|
||||
UpdateSuperPartition();
|
||||
|
||||
// Resize any logical partition to 0, so each partition is reset to 0
|
||||
// extents, and will achieve more optimal allocation.
|
||||
for (const auto& [image, slot] : os_images_) {
|
||||
|
@ -1627,77 +1640,9 @@ void FlashAllTool::Flash() {
|
|||
do_for_partitions(image->part_name, slot, resize_partition, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Flash OS images, resizing logical partitions as needed.
|
||||
FlashImages(os_images_);
|
||||
}
|
||||
|
||||
bool FlashAllTool::OptimizedFlashSuper() {
|
||||
if (!supports_AB()) {
|
||||
LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
|
||||
return false;
|
||||
}
|
||||
if (fp_->slot == "all") {
|
||||
LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does this device use dynamic partitions at all?
|
||||
unique_fd fd = fp_->source->OpenFile("super_empty.img");
|
||||
if (fd < 0) {
|
||||
LOG(VERBOSE) << "could not open super_empty.img";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to find whether there is a super partition.
|
||||
std::string super_name;
|
||||
if (fb->GetVar("super-partition-name", &super_name) != fastboot::SUCCESS) {
|
||||
super_name = "super";
|
||||
}
|
||||
std::string partition_size_str;
|
||||
if (fb->GetVar("partition-size:" + super_name, &partition_size_str) != fastboot::SUCCESS) {
|
||||
LOG(VERBOSE) << "Cannot optimize super flashing: could not determine super partition";
|
||||
return false;
|
||||
}
|
||||
|
||||
SuperFlashHelper helper(*fp_->source);
|
||||
if (!helper.Open(fd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& entry : os_images_) {
|
||||
auto partition = GetPartitionName(entry);
|
||||
auto image = entry.first;
|
||||
|
||||
if (!helper.AddPartition(partition, image->img_name, image->optional_if_no_image)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto s = helper.GetSparseLayout();
|
||||
if (!s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<SparsePtr> files;
|
||||
if (int limit = get_sparse_limit(sparse_file_len(s.get(), false, false))) {
|
||||
files = resparse_file(s.get(), limit);
|
||||
} else {
|
||||
files.emplace_back(std::move(s));
|
||||
}
|
||||
|
||||
// Send the data to the device.
|
||||
flash_partition_files(super_name, files);
|
||||
|
||||
// Remove images that we already flashed, just in case we have non-dynamic OS images.
|
||||
auto remove_if_callback = [&, this](const ImageEntry& entry) -> bool {
|
||||
return helper.WillFlash(GetPartitionName(entry));
|
||||
};
|
||||
os_images_.erase(std::remove_if(os_images_.begin(), os_images_.end(), remove_if_callback),
|
||||
os_images_.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlashAllTool::CheckRequirements() {
|
||||
std::vector<char> contents;
|
||||
if (!fp_->source->ReadFile("android-info.txt", &contents)) {
|
||||
|
@ -1811,20 +1756,6 @@ void FlashAllTool::UpdateSuperPartition() {
|
|||
}
|
||||
}
|
||||
|
||||
std::string FlashAllTool::GetPartitionName(const ImageEntry& entry) {
|
||||
auto slot = entry.second;
|
||||
if (slot.empty()) {
|
||||
slot = fp_->current_slot;
|
||||
}
|
||||
if (slot.empty()) {
|
||||
return entry.first->part_name;
|
||||
}
|
||||
if (slot == "all") {
|
||||
LOG(FATAL) << "Cannot retrieve a singular name when using all slots";
|
||||
}
|
||||
return entry.first->part_name + "_" + slot;
|
||||
}
|
||||
|
||||
class ZipImageSource final : public ImageSource {
|
||||
public:
|
||||
explicit ZipImageSource(ZipArchiveHandle zip) : zip_(zip) {}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <string>
|
||||
#include "fastboot_driver.h"
|
||||
#include "super_flash_helper.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <bootimg.h>
|
||||
|
@ -82,7 +83,6 @@ struct FlashingPlan {
|
|||
std::string current_slot;
|
||||
std::string secondary_slot;
|
||||
fastboot::FastBootDriver* fb;
|
||||
|
||||
};
|
||||
|
||||
bool should_flash_in_userspace(const std::string& partition_name);
|
||||
|
@ -100,4 +100,12 @@ struct NetworkSerial {
|
|||
int port;
|
||||
};
|
||||
|
||||
Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
|
||||
Result<NetworkSerial, FastbootError> ParseNetworkSerial(const std::string& serial);
|
||||
bool supports_AB();
|
||||
std::string GetPartitionName(const ImageEntry& entry, std::string& current_slot_);
|
||||
void flash_partition_files(const std::string& partition, const std::vector<SparsePtr>& files);
|
||||
int64_t get_sparse_limit(int64_t size);
|
||||
std::vector<SparsePtr> resparse_file(sparse_file* s, int64_t max_size);
|
||||
|
||||
bool is_retrofit_device();
|
||||
bool is_logical(const std::string& partition);
|
||||
|
|
|
@ -14,11 +14,12 @@
|
|||
// limitations under the License.
|
||||
//
|
||||
#include "task.h"
|
||||
#include <iostream>
|
||||
#include "fastboot.h"
|
||||
#include "util.h"
|
||||
#include "filesystem.h"
|
||||
#include "super_flash_helper.h"
|
||||
|
||||
#include "fastboot.h"
|
||||
#include "util.h"
|
||||
using namespace std::string_literals;
|
||||
|
||||
FlashTask::FlashTask(const std::string& _slot, const std::string& _pname)
|
||||
: pname_(_pname), fname_(find_item(_pname)), slot_(_slot) {
|
||||
|
@ -66,3 +67,78 @@ void RebootTask::Run() {
|
|||
syntax_error("unknown reboot target %s", reboot_target_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
FlashSuperLayoutTask::FlashSuperLayoutTask(const std::string& super_name,
|
||||
std::unique_ptr<SuperFlashHelper> helper,
|
||||
SparsePtr sparse_layout)
|
||||
: super_name_(super_name),
|
||||
helper_(std::move(helper)),
|
||||
sparse_layout_(std::move(sparse_layout)) {}
|
||||
|
||||
void FlashSuperLayoutTask::Run() {
|
||||
std::vector<SparsePtr> files;
|
||||
if (int limit = get_sparse_limit(sparse_file_len(sparse_layout_.get(), false, false))) {
|
||||
files = resparse_file(sparse_layout_.get(), limit);
|
||||
} else {
|
||||
files.emplace_back(std::move(sparse_layout_));
|
||||
}
|
||||
|
||||
// Send the data to the device.
|
||||
flash_partition_files(super_name_, files);
|
||||
}
|
||||
|
||||
std::unique_ptr<FlashSuperLayoutTask> FlashSuperLayoutTask::Initialize(
|
||||
FlashingPlan* fp, std::vector<ImageEntry>& os_images) {
|
||||
if (!supports_AB()) {
|
||||
LOG(VERBOSE) << "Cannot optimize flashing super on non-AB device";
|
||||
return nullptr;
|
||||
}
|
||||
if (fp->slot == "all") {
|
||||
LOG(VERBOSE) << "Cannot optimize flashing super for all slots";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Does this device use dynamic partitions at all?
|
||||
unique_fd fd = fp->source->OpenFile("super_empty.img");
|
||||
|
||||
if (fd < 0) {
|
||||
LOG(VERBOSE) << "could not open super_empty.img";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string super_name;
|
||||
// Try to find whether there is a super partition.
|
||||
if (fp->fb->GetVar("super-partition-name", &super_name) != fastboot::SUCCESS) {
|
||||
super_name = "super";
|
||||
}
|
||||
std::string partition_size_str;
|
||||
|
||||
if (fp->fb->GetVar("partition-size:" + super_name, &partition_size_str) != fastboot::SUCCESS) {
|
||||
LOG(VERBOSE) << "Cannot optimize super flashing: could not determine super partition";
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<SuperFlashHelper> helper = std::make_unique<SuperFlashHelper>(*fp->source);
|
||||
if (!helper->Open(fd)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (const auto& entry : os_images) {
|
||||
auto partition = GetPartitionName(entry, fp->current_slot);
|
||||
auto image = entry.first;
|
||||
|
||||
if (!helper->AddPartition(partition, image->img_name, image->optional_if_no_image)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto s = helper->GetSparseLayout();
|
||||
if (!s) return nullptr;
|
||||
|
||||
// Remove images that we already flashed, just in case we have non-dynamic OS images.
|
||||
auto remove_if_callback = [&](const ImageEntry& entry) -> bool {
|
||||
return helper->WillFlash(GetPartitionName(entry, fp->current_slot));
|
||||
};
|
||||
os_images.erase(std::remove_if(os_images.begin(), os_images.end(), remove_if_callback),
|
||||
os_images.end());
|
||||
return std::make_unique<FlashSuperLayoutTask>(super_name, std::move(helper), std::move(s));
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "fastboot.h"
|
||||
#include "fastboot_driver.h"
|
||||
#include "super_flash_helper.h"
|
||||
#include "util.h"
|
||||
|
||||
class Task {
|
||||
public:
|
||||
|
@ -52,4 +54,19 @@ class RebootTask : public Task {
|
|||
private:
|
||||
const std::string reboot_target_ = "";
|
||||
FlashingPlan* fp_;
|
||||
};
|
||||
};
|
||||
|
||||
class FlashSuperLayoutTask : public Task {
|
||||
public:
|
||||
FlashSuperLayoutTask(const std::string& super_name, std::unique_ptr<SuperFlashHelper> helper,
|
||||
SparsePtr sparse_layout);
|
||||
static std::unique_ptr<FlashSuperLayoutTask> Initialize(FlashingPlan* fp,
|
||||
std::vector<ImageEntry>& os_images);
|
||||
using ImageEntry = std::pair<const Image*, std::string>;
|
||||
void Run() override;
|
||||
|
||||
private:
|
||||
const std::string super_name_;
|
||||
std::unique_ptr<SuperFlashHelper> helper_;
|
||||
SparsePtr sparse_layout_;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue