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