Home | History | Annotate | Download | only in payload_generator
      1 //
      2 // Copyright (C) 2015 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
     18 #define UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
     19 
     20 #include <string>
     21 #include <vector>
     22 
     23 #include <base/macros.h>
     24 #include <brillo/secure_blob.h>
     25 
     26 #include "update_engine/payload_consumer/payload_constants.h"
     27 #include "update_engine/payload_generator/blob_file_writer.h"
     28 #include "update_engine/payload_generator/extent_utils.h"
     29 #include "update_engine/payload_generator/filesystem_interface.h"
     30 #include "update_engine/payload_generator/operations_generator.h"
     31 #include "update_engine/payload_generator/payload_generation_config.h"
     32 #include "update_engine/update_metadata.pb.h"
     33 
     34 namespace chromeos_update_engine {
     35 
     36 // The ABGenerator is an operations generator that generates payloads using the
     37 // A-to-B operations SOURCE_COPY and SOURCE_BSDIFF introduced in the payload
     38 // minor version 2 format.
     39 class ABGenerator : public OperationsGenerator {
     40  public:
     41   ABGenerator() = default;
     42 
     43   // Generate the update payload operations for the given partition using
     44   // SOURCE_* operations, used for generating deltas for the minor version
     45   // kSourceMinorPayloadVersion. This function will generate operations in the
     46   // partition that will read blocks from the source partition in random order
     47   // and write the new image on the target partition, also possibly in random
     48   // order. The operations are stored in |aops| and should be executed in that
     49   // order. All the offsets in the operations reference the data written to
     50   // |blob_file|.
     51   bool GenerateOperations(
     52       const PayloadGenerationConfig& config,
     53       const PartitionConfig& old_part,
     54       const PartitionConfig& new_part,
     55       BlobFileWriter* blob_file,
     56       std::vector<AnnotatedOperation>* aops) override;
     57 
     58   // Split the operations in the vector of AnnotatedOperations |aops| such that
     59   // for every operation there is only one dst extent and updates |aops| with
     60   // the new list of operations. All kinds of operations are fragmented except
     61   // BSDIFF and SOURCE_BSDIFF, PUFFDIFF and BROTLI_BSDIFF operations.  The
     62   // |target_part_path| is the filename of the new image, where the destination
     63   // extents refer to. The blobs of the operations in |aops| should reference
     64   // |blob_file|. |blob_file| are updated if needed.
     65   static bool FragmentOperations(const PayloadVersion& version,
     66                                  std::vector<AnnotatedOperation>* aops,
     67                                  const std::string& target_part_path,
     68                                  BlobFileWriter* blob_file);
     69 
     70   // Takes a vector of AnnotatedOperations |aops| and sorts them by the first
     71   // start block in their destination extents. Sets |aops| to a vector of the
     72   // sorted operations.
     73   static void SortOperationsByDestination(
     74       std::vector<AnnotatedOperation>* aops);
     75 
     76   // Takes an SOURCE_COPY install operation, |aop|, and adds one operation for
     77   // each dst extent in |aop| to |ops|. The new operations added to |ops| will
     78   // have only one dst extent. The src extents are split so the number of blocks
     79   // in the src and dst extents are equal.
     80   // E.g. we have a SOURCE_COPY operation:
     81   //   src extents: [(1, 3), (5, 1), (7, 1)], dst extents: [(2, 2), (6, 3)]
     82   // Then we will get 2 new operations:
     83   //   1. src extents: [(1, 2)], dst extents: [(2, 2)]
     84   //   2. src extents: [(3, 1),(5, 1),(7, 1)], dst extents: [(6, 3)]
     85   static bool SplitSourceCopy(const AnnotatedOperation& original_aop,
     86                               std::vector<AnnotatedOperation>* result_aops);
     87 
     88   // Takes a REPLACE, REPLACE_BZ or REPLACE_XZ operation |aop|, and adds one
     89   // operation for each dst extent in |aop| to |ops|. The new operations added
     90   // to |ops| will have only one dst extent each, and may be of a different
     91   // type depending on whether compression is advantageous.
     92   static bool SplitAReplaceOp(const PayloadVersion& version,
     93                               const AnnotatedOperation& original_aop,
     94                               const std::string& target_part,
     95                               std::vector<AnnotatedOperation>* result_aops,
     96                               BlobFileWriter* blob_file);
     97 
     98   // Takes a sorted (by first destination extent) vector of operations |aops|
     99   // and merges SOURCE_COPY, REPLACE, REPLACE_BZ and REPLACE_XZ, operations in
    100   // that vector.
    101   // It will merge two operations if:
    102   //   - They are both REPLACE_*, or they are both SOURCE_COPY,
    103   //   - Their destination blocks are contiguous.
    104   //   - Their combined blocks do not exceed |chunk_blocks| blocks.
    105   // Note that unlike other methods, you can't pass a negative number in
    106   // |chunk_blocks|.
    107   static bool MergeOperations(std::vector<AnnotatedOperation>* aops,
    108                               const PayloadVersion& version,
    109                               size_t chunk_blocks,
    110                               const std::string& target_part,
    111                               BlobFileWriter* blob_file);
    112 
    113   // Takes a vector of AnnotatedOperations |aops|, adds source hash to all
    114   // operations that have src_extents.
    115   static bool AddSourceHash(std::vector<AnnotatedOperation>* aops,
    116                             const std::string& source_part_path);
    117 
    118  private:
    119   // Adds the data payload for a REPLACE/REPLACE_BZ/REPLACE_XZ operation |aop|
    120   // by reading its output extents from |target_part_path| and appending a
    121   // corresponding data blob to |blob_file|. The blob will be compressed if this
    122   // is smaller than the uncompressed form, and the operation type will be set
    123   // accordingly. |*blob_file| will be updated as well. If the operation happens
    124   // to have the right type and already points to a data blob, nothing is
    125   // written. Caller should only set type and data blob if it's valid.
    126   static bool AddDataAndSetType(AnnotatedOperation* aop,
    127                                 const PayloadVersion& version,
    128                                 const std::string& target_part_path,
    129                                 BlobFileWriter* blob_file);
    130 
    131   DISALLOW_COPY_AND_ASSIGN(ABGenerator);
    132 };
    133 
    134 }  // namespace chromeos_update_engine
    135 
    136 #endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
    137