Alex Deymo | aea4c1c | 2015-08-19 20:24:43 -0700 | [diff] [blame] | 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 | // |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 16 | |
| 17 | #ifndef UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_UTILS_H_ |
| 18 | #define UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_UTILS_H_ |
| 19 | |
| 20 | #include <string> |
| 21 | #include <vector> |
| 22 | |
Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 23 | #include <brillo/secure_blob.h> |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 24 | |
| 25 | #include "update_engine/payload_generator/annotated_operation.h" |
Alex Deymo | f006135 | 2015-07-01 14:59:15 -0700 | [diff] [blame] | 26 | #include "update_engine/payload_generator/extent_ranges.h" |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 27 | #include "update_engine/payload_generator/payload_generation_config.h" |
| 28 | #include "update_engine/update_metadata.pb.h" |
| 29 | |
| 30 | namespace chromeos_update_engine { |
| 31 | |
| 32 | namespace diff_utils { |
| 33 | |
Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 34 | // Create operations in |aops| to produce all the blocks in the |new_part| |
| 35 | // partition using the filesystem opened in that PartitionConfig. |
| 36 | // It uses the files reported by the filesystem in |old_part| and the data |
| 37 | // blocks in that partition (if available) to determine the best way to compress |
| 38 | // the new files (REPLACE, REPLACE_BZ, COPY, BSDIFF) and writes any necessary |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 39 | // data to |blob_file|. |hard_chunk_blocks| and |soft_chunk_blocks| are the hard |
| 40 | // and soft chunk limits in number of blocks respectively. The soft chunk limit |
| 41 | // is used to split MOVE and SOURCE_COPY operations and REPLACE_BZ of zeroed |
| 42 | // blocks, while the hard limit is used to split a file when generating other |
| 43 | // operations. A value of -1 in |hard_chunk_blocks| means whole files. |
Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 44 | bool DeltaReadPartition(std::vector<AnnotatedOperation>* aops, |
| 45 | const PartitionConfig& old_part, |
| 46 | const PartitionConfig& new_part, |
Alex Deymo | 2d3b2d6 | 2015-07-17 17:34:36 -0700 | [diff] [blame] | 47 | ssize_t hard_chunk_blocks, |
| 48 | size_t soft_chunk_blocks, |
Sen Jiang | 8cc502d | 2015-08-10 10:04:54 -0700 | [diff] [blame] | 49 | BlobFileWriter* blob_file, |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 50 | bool imgdiff_allowed, |
Alex Deymo | b42b98d | 2015-07-06 17:42:38 -0700 | [diff] [blame] | 51 | bool src_ops_allowed); |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 52 | |
Alex Deymo | f006135 | 2015-07-01 14:59:15 -0700 | [diff] [blame] | 53 | // Create operations in |aops| for identical blocks that moved around in the old |
| 54 | // and new partition and also handle zeroed blocks. The old and new partition |
| 55 | // are stored in the |old_part| and |new_part| files and have |old_num_blocks| |
| 56 | // and |new_num_blocks| respectively. The maximum operation size is |
| 57 | // |chunk_blocks| blocks, or unlimited if |chunk_blocks| is -1. The blobs of the |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 58 | // produced operations are stored in the |blob_file|. |
Alex Deymo | f006135 | 2015-07-01 14:59:15 -0700 | [diff] [blame] | 59 | // The collections |old_visited_blocks| and |new_visited_blocks| state what |
| 60 | // blocks already have operations reading or writing them and only operations |
| 61 | // for unvisited blocks are produced by this function updating both collections |
| 62 | // with the used blocks. |
| 63 | bool DeltaMovedAndZeroBlocks(std::vector<AnnotatedOperation>* aops, |
| 64 | const std::string& old_part, |
| 65 | const std::string& new_part, |
| 66 | size_t old_num_blocks, |
| 67 | size_t new_num_blocks, |
Alex Deymo | 2d3b2d6 | 2015-07-17 17:34:36 -0700 | [diff] [blame] | 68 | ssize_t chunk_blocks, |
Alex Deymo | f006135 | 2015-07-01 14:59:15 -0700 | [diff] [blame] | 69 | bool src_ops_allowed, |
Sen Jiang | 8cc502d | 2015-08-10 10:04:54 -0700 | [diff] [blame] | 70 | BlobFileWriter* blob_file, |
Alex Deymo | f006135 | 2015-07-01 14:59:15 -0700 | [diff] [blame] | 71 | ExtentRanges* old_visited_blocks, |
| 72 | ExtentRanges* new_visited_blocks); |
| 73 | |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 74 | // For a given file |name| append operations to |aops| to produce it in the |
| 75 | // |new_part|. The file will be split in chunks of |chunk_blocks| blocks each |
| 76 | // or treated as a single chunk if |chunk_blocks| is -1. The file data is |
| 77 | // stored in |new_part| in the blocks described by |new_extents| and, if it |
| 78 | // exists, the old version exists in |old_part| in the blocks described by |
| 79 | // |old_extents|. The operations added to |aops| reference the data blob |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 80 | // in the |blob_file|. Returns true on success. |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 81 | bool DeltaReadFile(std::vector<AnnotatedOperation>* aops, |
| 82 | const std::string& old_part, |
| 83 | const std::string& new_part, |
| 84 | const std::vector<Extent>& old_extents, |
| 85 | const std::vector<Extent>& new_extents, |
| 86 | const std::string& name, |
Alex Deymo | 2d3b2d6 | 2015-07-17 17:34:36 -0700 | [diff] [blame] | 87 | ssize_t chunk_blocks, |
Sen Jiang | 8cc502d | 2015-08-10 10:04:54 -0700 | [diff] [blame] | 88 | BlobFileWriter* blob_file, |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 89 | bool imgdiff_allowed, |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 90 | bool src_ops_allowed); |
| 91 | |
| 92 | // Reads the blocks |old_extents| from |old_part| (if it exists) and the |
| 93 | // |new_extents| from |new_part| and determines the smallest way to encode |
| 94 | // this |new_extents| for the diff. It stores necessary data in |out_data| and |
| 95 | // fills in |out_op|. If there's no change in old and new files, it creates a |
| 96 | // MOVE operation. If there is a change, the smallest of REPLACE, REPLACE_BZ, |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 97 | // BSDIFF (if |bsdiff_allowed|) or IMGDIFF (if |imgdiff_allowed|) wins. |
| 98 | // |new_extents| must not be empty. |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 99 | // If |src_ops_allowed| is true, it will emit SOURCE_COPY and SOURCE_BSDIFF |
| 100 | // operations instead of MOVE and BSDIFF, respectively. |
| 101 | // Returns true on success. |
| 102 | bool ReadExtentsToDiff(const std::string& old_part, |
| 103 | const std::string& new_part, |
| 104 | const std::vector<Extent>& old_extents, |
| 105 | const std::vector<Extent>& new_extents, |
| 106 | bool bsdiff_allowed, |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 107 | bool imgdiff_allowed, |
Alex Vakulenko | 3f39d5c | 2015-10-13 09:27:13 -0700 | [diff] [blame] | 108 | brillo::Blob* out_data, |
Alex Deymo | a12ee11 | 2015-08-12 22:19:32 -0700 | [diff] [blame] | 109 | InstallOperation* out_op, |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 110 | bool src_ops_allowed); |
| 111 | |
Sen Jiang | 55c4f9b | 2016-02-10 11:26:20 -0800 | [diff] [blame] | 112 | // Runs the bsdiff or imgdiff tool in |diff_path| on two files and returns the |
| 113 | // resulting delta in |out|. Returns true on success. |
| 114 | bool DiffFiles(const std::string& diff_path, |
| 115 | const std::string& old_file, |
| 116 | const std::string& new_file, |
| 117 | brillo::Blob* out); |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 118 | |
| 119 | // Returns true if |op| is a no-op operation that doesn't do any useful work |
| 120 | // (e.g., a move operation that copies blocks onto themselves). |
Alex Deymo | a12ee11 | 2015-08-12 22:19:32 -0700 | [diff] [blame] | 121 | bool IsNoopOperation(const InstallOperation& op); |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 122 | |
| 123 | // Filters all the operations that are no-op, maintaining the relative order |
| 124 | // of the rest of the operations. |
| 125 | void FilterNoopOperations(std::vector<AnnotatedOperation>* ops); |
| 126 | |
| 127 | bool InitializePartitionInfo(const PartitionConfig& partition, |
| 128 | PartitionInfo* info); |
| 129 | |
Alex Deymo | 3b2c7d0 | 2015-07-16 16:08:16 -0700 | [diff] [blame] | 130 | // Compare two AnnotatedOperations by the start block of the first Extent in |
| 131 | // their destination extents. |
| 132 | bool CompareAopsByDestination(AnnotatedOperation first_aop, |
| 133 | AnnotatedOperation second_aop); |
| 134 | |
Alex Deymo | 1415857 | 2015-06-13 03:37:08 -0700 | [diff] [blame] | 135 | } // namespace diff_utils |
| 136 | |
| 137 | } // namespace chromeos_update_engine |
| 138 | |
| 139 | #endif // UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_UTILS_H_ |