Reboots to fastbootd (userspace fastboot) take a long time, particularly due to the orange AVB screen and the likelihood of devices having uart enabled. For "flashall", there is rarely a need to actually go into userspace, because all of super is getting thrown away. We can just flash super in the bootloader. In the past we didn't do this because computing super.img is expensive - both in terms of time (due to reading dependent images) and in terms of space (it's easily over 5GB). But we don't actually need to fully compute super.img. We can build a sparse_file containing the metadata/headers, with additional references to each image file containing partition data. Liblp provides the API to do that, and here, we simply need to translate the layout to libsparse. On Pixel, this reduces flashall time by around 35-50 seconds, or around 20% of total time, depending on whether uart is in use. There are some caveats, in which case we'll fall back to normal fastbootd. This does not work on non-A/B devices, on retrofit dynamic partition devices (Pixel 3), and in some other edge-casey scenarios. If it fails, -v will add logging information about why. Bue: 266982466 Test: fastboot flashall on Pixel 5+ Change-Id: Ie040da597d739faa7f834202184cec8f8e412076
56 lines
1.8 KiB
C++
56 lines
1.8 KiB
C++
//
|
|
// Copyright (C) 2023 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
|
|
#include <android-base/unique_fd.h>
|
|
#include <liblp/liblp.h>
|
|
#include <liblp/super_layout_builder.h>
|
|
|
|
#include "util.h"
|
|
|
|
class SuperFlashHelper final {
|
|
public:
|
|
explicit SuperFlashHelper(const ImageSource& source);
|
|
|
|
bool Open(android::base::borrowed_fd fd);
|
|
bool IncludeInSuper(const std::string& partition);
|
|
bool AddPartition(const std::string& partition, const std::string& image_name, bool optional);
|
|
|
|
// Note: the SparsePtr if non-null should not outlive SuperFlashHelper, since
|
|
// it depends on open fds and data pointers.
|
|
SparsePtr GetSparseLayout();
|
|
|
|
bool WillFlash(const std::string& partition) const {
|
|
return will_flash_.find(partition) != will_flash_.end();
|
|
}
|
|
|
|
private:
|
|
const ImageSource& source_;
|
|
android::fs_mgr::SuperLayoutBuilder builder_;
|
|
std::unique_ptr<android::fs_mgr::LpMetadata> base_metadata_;
|
|
std::vector<android::fs_mgr::SuperImageExtent> extents_;
|
|
|
|
// Cache open image fds. This keeps them alive while we flash the sparse
|
|
// file.
|
|
std::unordered_map<std::string, android::base::unique_fd> image_fds_;
|
|
std::unordered_set<std::string> will_flash_;
|
|
};
|