136 lines
6.7 KiB
C++
136 lines
6.7 KiB
C++
//
|
|
// Copyright (C) 2015 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.
|
|
//
|
|
|
|
#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
|
|
#define UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <base/macros.h>
|
|
#include <brillo/secure_blob.h>
|
|
|
|
#include "update_engine/payload_consumer/payload_constants.h"
|
|
#include "update_engine/payload_generator/blob_file_writer.h"
|
|
#include "update_engine/payload_generator/extent_utils.h"
|
|
#include "update_engine/payload_generator/filesystem_interface.h"
|
|
#include "update_engine/payload_generator/operations_generator.h"
|
|
#include "update_engine/payload_generator/payload_generation_config.h"
|
|
#include "update_engine/update_metadata.pb.h"
|
|
|
|
namespace chromeos_update_engine {
|
|
|
|
// The ABGenerator is an operations generator that generates payloads using the
|
|
// A-to-B operations SOURCE_COPY and SOURCE_BSDIFF introduced in the payload
|
|
// minor version 2 format.
|
|
class ABGenerator : public OperationsGenerator {
|
|
public:
|
|
ABGenerator() = default;
|
|
|
|
// Generate the update payload operations for the given partition using
|
|
// SOURCE_* operations, used for generating deltas for the minor version
|
|
// kSourceMinorPayloadVersion. This function will generate operations in the
|
|
// partition that will read blocks from the source partition in random order
|
|
// and write the new image on the target partition, also possibly in random
|
|
// order. The operations are stored in |aops| and should be executed in that
|
|
// order. All the offsets in the operations reference the data written to
|
|
// |blob_file|.
|
|
bool GenerateOperations(const PayloadGenerationConfig& config,
|
|
const PartitionConfig& old_part,
|
|
const PartitionConfig& new_part,
|
|
BlobFileWriter* blob_file,
|
|
std::vector<AnnotatedOperation>* aops) override;
|
|
|
|
// Split the operations in the vector of AnnotatedOperations |aops| such that
|
|
// for every operation there is only one dst extent and updates |aops| with
|
|
// the new list of operations. All kinds of operations are fragmented except
|
|
// BSDIFF and SOURCE_BSDIFF, PUFFDIFF and BROTLI_BSDIFF operations. The
|
|
// |target_part_path| is the filename of the new image, where the destination
|
|
// extents refer to. The blobs of the operations in |aops| should reference
|
|
// |blob_file|. |blob_file| are updated if needed.
|
|
static bool FragmentOperations(const PayloadVersion& version,
|
|
std::vector<AnnotatedOperation>* aops,
|
|
const std::string& target_part_path,
|
|
BlobFileWriter* blob_file);
|
|
|
|
// Takes a vector of AnnotatedOperations |aops| and sorts them by the first
|
|
// start block in their destination extents. Sets |aops| to a vector of the
|
|
// sorted operations.
|
|
static void SortOperationsByDestination(
|
|
std::vector<AnnotatedOperation>* aops);
|
|
|
|
// Takes an SOURCE_COPY install operation, |aop|, and adds one operation for
|
|
// each dst extent in |aop| to |ops|. The new operations added to |ops| will
|
|
// have only one dst extent. The src extents are split so the number of blocks
|
|
// in the src and dst extents are equal.
|
|
// E.g. we have a SOURCE_COPY operation:
|
|
// src extents: [(1, 3), (5, 1), (7, 1)], dst extents: [(2, 2), (6, 3)]
|
|
// Then we will get 2 new operations:
|
|
// 1. src extents: [(1, 2)], dst extents: [(2, 2)]
|
|
// 2. src extents: [(3, 1),(5, 1),(7, 1)], dst extents: [(6, 3)]
|
|
static bool SplitSourceCopy(const AnnotatedOperation& original_aop,
|
|
std::vector<AnnotatedOperation>* result_aops);
|
|
|
|
// Takes a REPLACE, REPLACE_BZ or REPLACE_XZ operation |aop|, and adds one
|
|
// operation for each dst extent in |aop| to |ops|. The new operations added
|
|
// to |ops| will have only one dst extent each, and may be of a different
|
|
// type depending on whether compression is advantageous.
|
|
static bool SplitAReplaceOp(const PayloadVersion& version,
|
|
const AnnotatedOperation& original_aop,
|
|
const std::string& target_part,
|
|
std::vector<AnnotatedOperation>* result_aops,
|
|
BlobFileWriter* blob_file);
|
|
|
|
// Takes a sorted (by first destination extent) vector of operations |aops|
|
|
// and merges SOURCE_COPY, REPLACE, REPLACE_BZ and REPLACE_XZ, operations in
|
|
// that vector.
|
|
// It will merge two operations if:
|
|
// - They are both REPLACE_*, or they are both SOURCE_COPY,
|
|
// - Their destination blocks are contiguous.
|
|
// - Their combined blocks do not exceed |chunk_blocks| blocks.
|
|
// Note that unlike other methods, you can't pass a negative number in
|
|
// |chunk_blocks|.
|
|
static bool MergeOperations(std::vector<AnnotatedOperation>* aops,
|
|
const PayloadVersion& version,
|
|
size_t chunk_blocks,
|
|
const std::string& target_part,
|
|
BlobFileWriter* blob_file);
|
|
|
|
// Takes a vector of AnnotatedOperations |aops|, adds source hash to all
|
|
// operations that have src_extents.
|
|
static bool AddSourceHash(std::vector<AnnotatedOperation>* aops,
|
|
const std::string& source_part_path);
|
|
|
|
private:
|
|
// Adds the data payload for a REPLACE/REPLACE_BZ/REPLACE_XZ operation |aop|
|
|
// by reading its output extents from |target_part_path| and appending a
|
|
// corresponding data blob to |blob_file|. The blob will be compressed if this
|
|
// is smaller than the uncompressed form, and the operation type will be set
|
|
// accordingly. |*blob_file| will be updated as well. If the operation happens
|
|
// to have the right type and already points to a data blob, nothing is
|
|
// written. Caller should only set type and data blob if it's valid.
|
|
static bool AddDataAndSetType(AnnotatedOperation* aop,
|
|
const PayloadVersion& version,
|
|
const std::string& target_part_path,
|
|
BlobFileWriter* blob_file);
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ABGenerator);
|
|
};
|
|
|
|
} // namespace chromeos_update_engine
|
|
|
|
#endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
|