delta_diff_utils.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_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/filesystem_interface.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 files reported by |new_fs|,
23// including all the blocks not reported by any file.
24// It uses the files reported by |old_fs| and the data in |old_part| to
25// determine the best way to compress the new files (REPLACE, REPLACE_BZ,
26// COPY, BSDIFF) and writes any necessary data to the end of data_fd updating
27// data_file_size accordingly.
28bool DeltaReadFilesystem(std::vector<AnnotatedOperation>* aops,
29                         const std::string& old_part,
30                         const std::string& new_part,
31                         FilesystemInterface* old_fs,
32                         FilesystemInterface* new_fs,
33                         off_t chunk_blocks,
34                         int data_fd,
35                         off_t* data_file_size,
36                         bool skip_block_0,
37                         bool src_ops_allowed);
38
39// For a given file |name| append operations to |aops| to produce it in the
40// |new_part|. The file will be split in chunks of |chunk_blocks| blocks each
41// or treated as a single chunk if |chunk_blocks| is -1. The file data is
42// stored in |new_part| in the blocks described by |new_extents| and, if it
43// exists, the old version exists in |old_part| in the blocks described by
44// |old_extents|. The operations added to |aops| reference the data blob
45// in the file |data_fd|, which has length *data_file_size. *data_file_size is
46// updated appropriately. Returns true on success.
47bool DeltaReadFile(std::vector<AnnotatedOperation>* aops,
48                   const std::string& old_part,
49                   const std::string& new_part,
50                   const std::vector<Extent>& old_extents,
51                   const std::vector<Extent>& new_extents,
52                   const std::string& name,
53                   off_t chunk_blocks,
54                   int data_fd,
55                   off_t* data_file_size,
56                   bool src_ops_allowed);
57
58// Reads the blocks |old_extents| from |old_part| (if it exists) and the
59// |new_extents| from |new_part| and determines the smallest way to encode
60// this |new_extents| for the diff. It stores necessary data in |out_data| and
61// fills in |out_op|. If there's no change in old and new files, it creates a
62// MOVE operation. If there is a change, the smallest of REPLACE, REPLACE_BZ,
63// or BSDIFF wins. |new_extents| must not be empty.
64// If |src_ops_allowed| is true, it will emit SOURCE_COPY and SOURCE_BSDIFF
65// operations instead of MOVE and BSDIFF, respectively.
66// Returns true on success.
67bool ReadExtentsToDiff(const std::string& old_part,
68                       const std::string& new_part,
69                       const std::vector<Extent>& old_extents,
70                       const std::vector<Extent>& new_extents,
71                       bool bsdiff_allowed,
72                       chromeos::Blob* out_data,
73                       DeltaArchiveManifest_InstallOperation* out_op,
74                       bool src_ops_allowed);
75
76// Delta compresses a kernel partition |new_kernel_part| with knowledge of the
77// old kernel partition |old_kernel_part|. If |old_kernel_part| is an empty
78// string, generates a full update of the partition. The size of the old and
79// new kernel is passed in |old_kernel_size| and |new_kernel_size|. The
80// operations used to generate the new kernel are stored in the |aops|
81// vector, and the blob associated to those operations is written at the end
82// of the |blobs_fd| file, adding to the value pointed by |blobs_length| the
83// bytes written to |blobs_fd|.
84bool DeltaCompressKernelPartition(
85    const std::string& old_kernel_part,
86    const std::string& new_kernel_part,
87    uint64_t old_kernel_size,
88    uint64_t new_kernel_size,
89    uint64_t block_size,
90    std::vector<AnnotatedOperation>* aops,
91    int blobs_fd,
92    off_t* blobs_length,
93    bool src_ops_allowed);
94
95// Runs the bsdiff tool on two files and returns the resulting delta in
96// |out|. Returns true on success.
97bool BsdiffFiles(const std::string& old_file,
98                 const std::string& new_file,
99                 chromeos::Blob* out);
100
101// Returns true if |op| is a no-op operation that doesn't do any useful work
102// (e.g., a move operation that copies blocks onto themselves).
103bool IsNoopOperation(const DeltaArchiveManifest_InstallOperation& op);
104
105// Filters all the operations that are no-op, maintaining the relative order
106// of the rest of the operations.
107void FilterNoopOperations(std::vector<AnnotatedOperation>* ops);
108
109bool InitializePartitionInfo(const PartitionConfig& partition,
110                             PartitionInfo* info);
111
112}  // namespace diff_utils
113
114}  // namespace chromeos_update_engine
115
116#endif  // UPDATE_ENGINE_PAYLOAD_GENERATOR_DELTA_DIFF_UTILS_H_
117