ab_generator.h revision 14158570d3995008dc93a628004118b87a6bca01
1// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
6#define UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
7
8#include <string>
9#include <vector>
10
11#include <base/macros.h>
12#include <chromeos/secure_blob.h>
13
14#include "update_engine/payload_constants.h"
15#include "update_engine/payload_generator/extent_utils.h"
16#include "update_engine/payload_generator/filesystem_interface.h"
17#include "update_engine/payload_generator/operations_generator.h"
18#include "update_engine/payload_generator/payload_generation_config.h"
19#include "update_engine/update_metadata.pb.h"
20
21namespace chromeos_update_engine {
22
23// The ABGenerator is an operations generator that generates payloads using the
24// A-to-B operations SOURCE_COPY and SOURCE_BSDIFF introduced in the payload
25// minor version 2 format.
26class ABGenerator : public OperationsGenerator {
27 public:
28  ABGenerator() = default;
29
30  // Generate the update payload operations for the kernel and rootfs using
31  // SOURCE_* operations, used for generating deltas for the minor version
32  // kSourceMinorPayloadVersion. This function will generate operations in the
33  // rootfs that will read blocks from the source partition in random order and
34  // write the new image on the target partition, also possibly in random order.
35  // The rootfs operations are stored in |rootfs_ops| and should be executed in
36  // that order. The kernel operations are stored in |kernel_ops|. All
37  // the offsets in the operations reference the data written to |data_file_fd|.
38  // The total amount of data written to that file is stored in
39  // |data_file_size|.
40  bool GenerateOperations(
41      const PayloadGenerationConfig& config,
42      int data_file_fd,
43      off_t* data_file_size,
44      std::vector<AnnotatedOperation>* rootfs_ops,
45      std::vector<AnnotatedOperation>* kernel_ops) override;
46
47  // Split the operations in the vector of AnnotatedOperations |aops|
48  // such that for every operation there is only one dst extent and updates
49  // |aops| with the new list of operations. All kinds of operations are
50  // fragmented except BSDIFF and SOURCE_BSDIFF operations.
51  // The |target_rootfs_part| is the filename of the new image, where the
52  // destination extents refer to. The blobs of the operations in |aops| should
53  // reference the file |data_fd| whose initial size is |*data_file_size|. The
54  // file contents and the value pointed by |data_file_size| are updated if
55  // needed.
56  static bool FragmentOperations(std::vector<AnnotatedOperation>* aops,
57                                 const std::string& target_rootfs_part,
58                                 int data_fd,
59                                 off_t* data_file_size);
60
61  // Takes a vector of AnnotatedOperations |aops| and sorts them by the first
62  // start block in their destination extents. Sets |aops| to a vector of the
63  // sorted operations.
64  static void SortOperationsByDestination(
65      std::vector<AnnotatedOperation>* aops);
66
67  // Takes an SOURCE_COPY install operation, |aop|, and adds one operation for
68  // each dst extent in |aop| to |ops|. The new operations added to |ops| will
69  // have only one dst extent. The src extents are split so the number of blocks
70  // in the src and dst extents are equal.
71  // E.g. we have a SOURCE_COPY operation:
72  //   src extents: [(1, 3), (5, 1), (7, 1)], dst extents: [(2, 2), (6, 3)]
73  // Then we will get 2 new operations:
74  //   1. src extents: [(1, 2)], dst extents: [(2, 2)]
75  //   2. src extents: [(3, 1),(5, 1),(7, 1)], dst extents: [(6, 3)]
76  static bool SplitSourceCopy(const AnnotatedOperation& original_aop,
77                              std::vector<AnnotatedOperation>* result_aops);
78
79  // Takes a REPLACE/REPLACE_BZ operation |aop|, and adds one operation for each
80  // dst extent in |aop| to |ops|. The new operations added to |ops| will have
81  // only one dst extent each, and may be either a REPLACE or REPLACE_BZ
82  // depending on whether compression is advantageous.
83  static bool SplitReplaceOrReplaceBz(
84      const AnnotatedOperation& original_aop,
85      std::vector<AnnotatedOperation>* result_aops,
86      const std::string& target_part,
87      int data_fd,
88      off_t* data_file_size);
89
90  // Takes a sorted (by first destination extent) vector of operations |aops|
91  // and merges SOURCE_COPY, REPLACE, and REPLACE_BZ operations in that vector.
92  // It will merge two operations if:
93  //   - They are of the same type.
94  //   - They are contiguous.
95  //   - Their combined blocks do not exceed |chunk_size|.
96  static bool MergeOperations(std::vector<AnnotatedOperation>* aops,
97                              off_t chunk_size,
98                              const std::string& target_part,
99                              int data_fd,
100                              off_t* data_file_size);
101
102 private:
103  // Adds the data payload for a REPLACE/REPLACE_BZ operation |aop| by reading
104  // its output extents from |target_part_path| and appending a corresponding
105  // data blob to |data_fd|. The blob will be compressed if this is smaller than
106  // the uncompressed form, and the operation type will be set accordingly.
107  // |*data_file_size| will be updated as well. If the operation happens to have
108  // the right type and already points to a data blob, we check whether its
109  // content is identical to the new one, in which case nothing is written.
110  static bool AddDataAndSetType(AnnotatedOperation* aop,
111                                const std::string& target_part_path,
112                                int data_fd,
113                                off_t* data_file_size);
114
115  DISALLOW_COPY_AND_ASSIGN(ABGenerator);
116};
117
118}  // namespace chromeos_update_engine
119
120#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_AB_GENERATOR_H_
121