Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: delta_diff_generator.cc

Issue 6528006: AU: tolerate files that are symlinks in src image, yet not in new image. (Closed) Base URL: http://git.chromium.org/git/update_engine.git@master
Patch Set: fixes for review Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | delta_performer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "update_engine/delta_diff_generator.h" 5 #include "update_engine/delta_diff_generator.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <inttypes.h> 9 #include <inttypes.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 using std::vector; 48 using std::vector;
49 49
50 namespace chromeos_update_engine { 50 namespace chromeos_update_engine {
51 51
52 typedef DeltaDiffGenerator::Block Block; 52 typedef DeltaDiffGenerator::Block Block;
53 typedef map<const DeltaArchiveManifest_InstallOperation*, 53 typedef map<const DeltaArchiveManifest_InstallOperation*,
54 const string*> OperationNameMap; 54 const string*> OperationNameMap;
55 55
56 namespace { 56 namespace {
57 const size_t kBlockSize = 4096; // bytes 57 const size_t kBlockSize = 4096; // bytes
58 const string kNonexistentPath = "";
58 59
59 // TODO(adlr): switch from 1GiB to 2GiB when we no longer care about old 60 // TODO(adlr): switch from 1GiB to 2GiB when we no longer care about old
60 // clients: 61 // clients:
61 const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // bytes 62 const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // bytes
62 const uint64_t kVersionNumber = 1; 63 const uint64_t kVersionNumber = 1;
63 const uint64_t kFullUpdateChunkSize = 1024 * 1024; // bytes 64 const uint64_t kFullUpdateChunkSize = 1024 * 1024; // bytes
64 65
65 static const char* kInstallOperationTypes[] = { 66 static const char* kInstallOperationTypes[] = {
66 "REPLACE", 67 "REPLACE",
67 "REPLACE_BZ", 68 "REPLACE_BZ",
(...skipping 22 matching lines...) Expand all
90 Vertex::Index existing_vertex, 91 Vertex::Index existing_vertex,
91 vector<Block>* blocks, 92 vector<Block>* blocks,
92 const string& old_root, 93 const string& old_root,
93 const string& new_root, 94 const string& new_root,
94 const string& path, // within new_root 95 const string& path, // within new_root
95 int data_fd, 96 int data_fd,
96 off_t* data_file_size) { 97 off_t* data_file_size) {
97 vector<char> data; 98 vector<char> data;
98 DeltaArchiveManifest_InstallOperation operation; 99 DeltaArchiveManifest_InstallOperation operation;
99 100
100 TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ReadFileToDiff(old_root + path, 101 string old_path = (old_root == kNonexistentPath) ? kNonexistentPath :
102 old_root + path;
103
104 TEST_AND_RETURN_FALSE(DeltaDiffGenerator::ReadFileToDiff(old_path,
101 new_root + path, 105 new_root + path,
102 &data, 106 &data,
103 &operation, 107 &operation,
104 true)); 108 true));
105 109
106 // Write the data 110 // Write the data
107 if (operation.type() != DeltaArchiveManifest_InstallOperation_Type_MOVE) { 111 if (operation.type() != DeltaArchiveManifest_InstallOperation_Type_MOVE) {
108 operation.set_data_offset(*data_file_size); 112 operation.set_data_offset(*data_file_size);
109 operation.set_data_length(data.size()); 113 operation.set_data_length(data.size());
110 } 114 }
(...skipping 23 matching lines...) Expand all
134 // For each regular file within new_root, creates a node in the graph, 138 // For each regular file within new_root, creates a node in the graph,
135 // determines the best way to compress it (REPLACE, REPLACE_BZ, COPY, BSDIFF), 139 // determines the best way to compress it (REPLACE, REPLACE_BZ, COPY, BSDIFF),
136 // and writes any necessary data to the end of data_fd. 140 // and writes any necessary data to the end of data_fd.
137 bool DeltaReadFiles(Graph* graph, 141 bool DeltaReadFiles(Graph* graph,
138 vector<Block>* blocks, 142 vector<Block>* blocks,
139 const string& old_root, 143 const string& old_root,
140 const string& new_root, 144 const string& new_root,
141 int data_fd, 145 int data_fd,
142 off_t* data_file_size) { 146 off_t* data_file_size) {
143 set<ino_t> visited_inodes; 147 set<ino_t> visited_inodes;
148 set<ino_t> visited_src_inodes;
144 for (FilesystemIterator fs_iter(new_root, 149 for (FilesystemIterator fs_iter(new_root,
145 utils::SetWithValue<string>("/lost+found")); 150 utils::SetWithValue<string>("/lost+found"));
146 !fs_iter.IsEnd(); fs_iter.Increment()) { 151 !fs_iter.IsEnd(); fs_iter.Increment()) {
147 if (!S_ISREG(fs_iter.GetStat().st_mode)) 152 if (!S_ISREG(fs_iter.GetStat().st_mode))
148 continue; 153 continue;
149 154
150 // Make sure we visit each inode only once. 155 // Make sure we visit each inode only once.
151 if (utils::SetContainsKey(visited_inodes, fs_iter.GetStat().st_ino)) 156 if (utils::SetContainsKey(visited_inodes, fs_iter.GetStat().st_ino))
152 continue; 157 continue;
153 visited_inodes.insert(fs_iter.GetStat().st_ino); 158 visited_inodes.insert(fs_iter.GetStat().st_ino);
154 if (fs_iter.GetStat().st_size == 0) 159 if (fs_iter.GetStat().st_size == 0)
155 continue; 160 continue;
156 161
157 LOG(INFO) << "Encoding file " << fs_iter.GetPartialPath(); 162 LOG(INFO) << "Encoding file " << fs_iter.GetPartialPath();
158 163
164 // We can't visit each dst image inode more than once, as that would
165 // duplicate work. Here, we avoid visiting each source image inode
166 // more than once. Technically, we could have multiple operations
167 // that read the same blocks from the source image for diffing, but
168 // we choose not to to avoid complexity. Eventually we will move away
169 // from using a graph/cycle detection/etc to generate diffs, and at that
170 // time, it will be easy (non-complex) to have many operations read
171 // from the same source blocks. At that time, this code can die. -adlr
172 bool should_diff_from_source = true;
173 string src_path = old_root + fs_iter.GetPartialPath();
174 if (utils::FileExists(src_path.c_str())) {
175 struct stat src_stbuf;
176 TEST_AND_RETURN_FALSE_ERRNO(0 == stat(src_path.c_str(), &src_stbuf));
177 should_diff_from_source = !utils::SetContainsKey(visited_src_inodes,
178 src_stbuf.st_ino);
179 visited_src_inodes.insert(src_stbuf.st_ino);
180 }
181
159 TEST_AND_RETURN_FALSE(DeltaReadFile(graph, 182 TEST_AND_RETURN_FALSE(DeltaReadFile(graph,
160 Vertex::kInvalidIndex, 183 Vertex::kInvalidIndex,
161 blocks, 184 blocks,
162 old_root, 185 (should_diff_from_source ?
186 old_root :
187 kNonexistentPath),
163 new_root, 188 new_root,
164 fs_iter.GetPartialPath(), 189 fs_iter.GetPartialPath(),
165 data_fd, 190 data_fd,
166 data_file_size)); 191 data_file_size));
167 } 192 }
168 return true; 193 return true;
169 } 194 }
170 195
171 // This class allocates non-existent temp blocks, starting from 196 // This class allocates non-existent temp blocks, starting from
172 // kTempBlockStart. Other code is responsible for converting these 197 // kTempBlockStart. Other code is responsible for converting these
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 if ((*graph)[cut.old_dst].op.type() != 1178 if ((*graph)[cut.old_dst].op.type() !=
1154 DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ && 1179 DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ &&
1155 (*graph)[cut.old_dst].op.type() != 1180 (*graph)[cut.old_dst].op.type() !=
1156 DeltaArchiveManifest_InstallOperation_Type_REPLACE) { 1181 DeltaArchiveManifest_InstallOperation_Type_REPLACE) {
1157 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges; 1182 Vertex::EdgeMap out_edges = (*graph)[cut.old_dst].out_edges;
1158 graph_utils::DropWriteBeforeDeps(&out_edges); 1183 graph_utils::DropWriteBeforeDeps(&out_edges);
1159 1184
1160 TEST_AND_RETURN_FALSE(DeltaReadFile(graph, 1185 TEST_AND_RETURN_FALSE(DeltaReadFile(graph,
1161 cut.old_dst, 1186 cut.old_dst,
1162 NULL, 1187 NULL,
1163 "/-!@:&*nonexistent_path", 1188 kNonexistentPath,
1164 new_root, 1189 new_root,
1165 (*graph)[cut.old_dst].file_name, 1190 (*graph)[cut.old_dst].file_name,
1166 data_fd, 1191 data_fd,
1167 data_file_size)); 1192 data_file_size));
1168 1193
1169 (*graph)[cut.old_dst].out_edges = out_edges; 1194 (*graph)[cut.old_dst].out_edges = out_edges;
1170 1195
1171 // Right now we don't have doubly-linked edges, so we have to scan 1196 // Right now we don't have doubly-linked edges, so we have to scan
1172 // the whole graph. 1197 // the whole graph.
1173 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst); 1198 graph_utils::DropIncomingEdgesTo(graph, cut.old_dst);
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 dummy_extent->set_start_block(kSparseHole); 1626 dummy_extent->set_start_block(kSparseHole);
1602 dummy_extent->set_num_blocks((signature_blob_length + kBlockSize - 1) / 1627 dummy_extent->set_num_blocks((signature_blob_length + kBlockSize - 1) /
1603 kBlockSize); 1628 kBlockSize);
1604 } 1629 }
1605 1630
1606 const char* const kBsdiffPath = "bsdiff"; 1631 const char* const kBsdiffPath = "bsdiff";
1607 const char* const kBspatchPath = "bspatch"; 1632 const char* const kBspatchPath = "bspatch";
1608 const char* const kDeltaMagic = "CrAU"; 1633 const char* const kDeltaMagic = "CrAU";
1609 1634
1610 }; // namespace chromeos_update_engine 1635 }; // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « no previous file | delta_performer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698