ronnie
2022-10-23 5a83b14855e763445ac36672c35ddb68300e4b42
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// 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_