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(const PayloadGenerationConfig& config, 52 const PartitionConfig& old_part, 53 const PartitionConfig& new_part, 54 BlobFileWriter* blob_file, 55 std::vector<AnnotatedOperation>* aops) override; 56 57 // Split the operations in the vector of AnnotatedOperations |aops| such that 58 // for every operation there is only one dst extent and updates |aops| with 59 // the new list of operations. All kinds of operations are fragmented except 60 // BSDIFF and SOURCE_BSDIFF, PUFFDIFF and BROTLI_BSDIFF operations. The 61 // |target_part_path| is the filename of the new image, where the destination 62 // extents refer to. The blobs of the operations in |aops| should reference 63 // |blob_file|. |blob_file| are updated if needed. 64 static bool FragmentOperations(const PayloadVersion& version, 65 std::vector<AnnotatedOperation>* aops, 66 const std::string& target_part_path, 67 BlobFileWriter* blob_file); 68 69 // Takes a vector of AnnotatedOperations |aops| and sorts them by the first 70 // start block in their destination extents. Sets |aops| to a vector of the 71 // sorted operations. 72 static void SortOperationsByDestination( 73 std::vector<AnnotatedOperation>* aops); 74 75 // Takes an SOURCE_COPY install operation, |aop|, and adds one operation for 76 // each dst extent in |aop| to |ops|. The new operations added to |ops| will 77 // have only one dst extent. The src extents are split so the number of blocks 78 // in the src and dst extents are equal. 79 // E.g. we have a SOURCE_COPY operation: 80 // src extents: [(1, 3), (5, 1), (7, 1)], dst extents: [(2, 2), (6, 3)] 81 // Then we will get 2 new operations: 82 // 1. src extents: [(1, 2)], dst extents: [(2, 2)] 83 // 2. src extents: [(3, 1),(5, 1),(7, 1)], dst extents: [(6, 3)] 84 static bool SplitSourceCopy(const AnnotatedOperation& original_aop, 85 std::vector<AnnotatedOperation>* result_aops); 86 87 // Takes a REPLACE, REPLACE_BZ or REPLACE_XZ operation |aop|, and adds one 88 // operation for each dst extent in |aop| to |ops|. The new operations added 89 // to |ops| will have only one dst extent each, and may be of a different 90 // type depending on whether compression is advantageous. 91 static bool SplitAReplaceOp(const PayloadVersion& version, 92 const AnnotatedOperation& original_aop, 93 const std::string& target_part, 94 std::vector<AnnotatedOperation>* result_aops, 95 BlobFileWriter* blob_file); 96 97 // Takes a sorted (by first destination extent) vector of operations |aops| 98 // and merges SOURCE_COPY, REPLACE, REPLACE_BZ and REPLACE_XZ, operations in 99 // that vector. 100 // It will merge two operations if: 101 // - They are both REPLACE_*, or they are both SOURCE_COPY, 102 // - Their destination blocks are contiguous. 103 // - Their combined blocks do not exceed |chunk_blocks| blocks. 104 // Note that unlike other methods, you can't pass a negative number in 105 // |chunk_blocks|. 106 static bool MergeOperations(std::vector<AnnotatedOperation>* aops, 107 const PayloadVersion& version, 108 size_t chunk_blocks, 109 const std::string& target_part, 110 BlobFileWriter* blob_file); 111 112 // Takes a vector of AnnotatedOperations |aops|, adds source hash to all 113 // operations that have src_extents. 114 static bool AddSourceHash(std::vector<AnnotatedOperation>* aops, 115 const std::string& source_part_path); 116 117 private: 118 // Adds the data payload for a REPLACE/REPLACE_BZ/REPLACE_XZ operation |aop| 119 // by reading its output extents from |target_part_path| and appending a 120 // corresponding data blob to |blob_file|. The blob will be compressed if this 121 // is smaller than the uncompressed form, and the operation type will be set 122 // accordingly. |*blob_file| will be updated as well. If the operation happens 123 // to have the right type and already points to a data blob, nothing is 124 // written. Caller should only set type and data blob if it's valid. 125 static bool AddDataAndSetType(AnnotatedOperation* aop, 126 const PayloadVersion& version, 127 const std::string& target_part_path, 128 BlobFileWriter* blob_file); 129 130 DISALLOW_COPY_AND_ASSIGN(ABGenerator); 131 }; 132 133 } // namespace chromeos_update_engine 134 135 #endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_ 136