OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium 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 #include <sys/stat.h> | 6 #include <sys/stat.h> |
7 #include <sys/types.h> | 7 #include <sys/types.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <set> | 11 #include <set> |
(...skipping 21 matching lines...) Expand all Loading... | |
33 using std::set; | 33 using std::set; |
34 using std::string; | 34 using std::string; |
35 using std::vector; | 35 using std::vector; |
36 | 36 |
37 namespace chromeos_update_engine { | 37 namespace chromeos_update_engine { |
38 | 38 |
39 typedef DeltaDiffGenerator::Block Block; | 39 typedef DeltaDiffGenerator::Block Block; |
40 | 40 |
41 namespace { | 41 namespace { |
42 const size_t kBlockSize = 4096; | 42 const size_t kBlockSize = 4096; |
43 const size_t kRootFSPartitionSize = 1 * 1024 * 1024 * 1024; // 1 GiB | |
Will Drewry
2010/09/29 01:10:47
Any chance you could open(tgt), ioctl(BLKGETSIZE64
petkov
2010/09/29 04:27:40
I don't think I can do this -- this is running on
Will Drewry
2010/09/29 04:33:41
Hrm the size is definitely available in the gpt ta
petkov
2010/09/29 16:17:36
$ cgpt show chromiumos_base_image.bin | fgrep ROOT
Will Drewry
2010/09/29 19:07:36
It being hard-coded in the installer means we get
petkov
2010/09/29 19:44:35
crosbug/7181 filed.
| |
43 const uint64_t kVersionNumber = 1; | 44 const uint64_t kVersionNumber = 1; |
44 | 45 |
45 // Stores all Extents for a file into 'out'. Returns true on success. | 46 // Stores all Extents for a file into 'out'. Returns true on success. |
46 bool GatherExtents(const string& path, | 47 bool GatherExtents(const string& path, |
47 google::protobuf::RepeatedPtrField<Extent>* out) { | 48 google::protobuf::RepeatedPtrField<Extent>* out) { |
48 vector<Extent> extents; | 49 vector<Extent> extents; |
49 TEST_AND_RETURN_FALSE(extent_mapper::ExtentsForFileFibmap(path, &extents)); | 50 TEST_AND_RETURN_FALSE(extent_mapper::ExtentsForFileFibmap(path, &extents)); |
50 DeltaDiffGenerator::StoreExtents(extents, out); | 51 DeltaDiffGenerator::StoreExtents(extents, out); |
51 return true; | 52 return true; |
52 } | 53 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 blocks, | 203 blocks, |
203 old_root, | 204 old_root, |
204 new_root, | 205 new_root, |
205 fs_iter.GetPartialPath(), | 206 fs_iter.GetPartialPath(), |
206 data_fd, | 207 data_fd, |
207 data_file_size)); | 208 data_file_size)); |
208 } | 209 } |
209 return true; | 210 return true; |
210 } | 211 } |
211 | 212 |
212 // Attempts to find block_count blocks to use as scratch space. | 213 // Attempts to find |block_count| blocks to use as scratch space. Returns true |
213 // Returns true on success. | 214 // on success. Right now we return exactly as many blocks as are required. |
214 // Right now we return exactly as many blocks as are required. | 215 // |
215 // TODO(adlr): consider returning all scratch blocks, | 216 // TODO(adlr): Consider returning all scratch blocks, even if there are extras, |
216 // even if there are extras, to make it easier for a scratch allocator | 217 // to make it easier for a scratch allocator to find contiguous regions for |
217 // to find contiguous regions for specific scratch writes. | 218 // specific scratch writes. |
218 bool FindScratchSpace(const vector<Block>& blocks, | 219 bool FindScratchSpace(const vector<Block>& blocks, |
219 vector<Block>::size_type block_count, | 220 vector<Block>::size_type block_count, |
220 vector<Extent>* out) { | 221 vector<Extent>* out) { |
221 // Scan blocks for blocks that are neither read nor written. | 222 // Scan |blocks| for blocks that are neither read, nor written. If we don't |
222 // If we don't find enough of those, return false. | 223 // find enough of those, look past the end of |blocks| till the end of the |
223 // TODO(adlr): return blocks that are written by | 224 // partition. If we don't find |block_count| scratch blocks, return false. |
224 // operations that don't have incoming edges (and thus, can be | 225 // |
225 // deferred until all old blocks are read by other operations). | 226 // TODO(adlr): Return blocks that are written by operations that don't have |
227 // incoming edges (and thus, can be deferred until all old blocks are read by | |
228 // other operations). | |
226 vector<Extent> ret; | 229 vector<Extent> ret; |
227 vector<Block>::size_type blocks_found = 0; | 230 vector<Block>::size_type blocks_found = 0; |
231 const size_t kPartitionBlocks = kRootFSPartitionSize / kBlockSize; | |
228 for (vector<Block>::size_type i = 0; | 232 for (vector<Block>::size_type i = 0; |
229 i < blocks.size() && blocks_found < block_count; i++) { | 233 i < kPartitionBlocks && blocks_found < block_count; i++) { |
230 if (blocks[i].reader == Vertex::kInvalidIndex && | 234 if (i >= blocks.size() || |
231 blocks[i].writer == Vertex::kInvalidIndex) { | 235 (blocks[i].reader == Vertex::kInvalidIndex && |
236 blocks[i].writer == Vertex::kInvalidIndex)) { | |
232 graph_utils::AppendBlockToExtents(&ret, i); | 237 graph_utils::AppendBlockToExtents(&ret, i); |
233 blocks_found++; | 238 blocks_found++; |
234 } | 239 } |
235 } | 240 } |
241 LOG(INFO) << "found " << blocks_found << " scratch blocks"; | |
236 if (blocks_found == block_count) { | 242 if (blocks_found == block_count) { |
237 LOG(INFO) << "returning " << blocks_found << " scratch blocks"; | |
238 out->swap(ret); | 243 out->swap(ret); |
239 return true; | 244 return true; |
240 } | 245 } |
241 return false; | 246 return false; |
242 } | 247 } |
243 | 248 |
244 // This class takes a collection of Extents and allows the client to | 249 // This class takes a collection of Extents and allows the client to |
245 // allocate space from these extents. The client must not request more | 250 // allocate space from these extents. The client must not request more |
246 // space then exists in the source extents. Space is allocated from the | 251 // space then exists in the source extents. Space is allocated from the |
247 // beginning of the source extents on; no consideration is paid to | 252 // beginning of the source extents on; no consideration is paid to |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
867 manifest.kernel_install_operations_size()); i++) { | 872 manifest.kernel_install_operations_size()); i++) { |
868 DeltaArchiveManifest_InstallOperation* op = | 873 DeltaArchiveManifest_InstallOperation* op = |
869 i < manifest.install_operations_size() ? | 874 i < manifest.install_operations_size() ? |
870 manifest.mutable_install_operations(i) : | 875 manifest.mutable_install_operations(i) : |
871 manifest.mutable_kernel_install_operations( | 876 manifest.mutable_kernel_install_operations( |
872 i - manifest.install_operations_size()); | 877 i - manifest.install_operations_size()); |
873 for (int j = 0; j < op->dst_extents_size(); j++) { | 878 for (int j = 0; j < op->dst_extents_size(); j++) { |
874 const Extent& extent = op->dst_extents(j); | 879 const Extent& extent = op->dst_extents(j); |
875 for (uint64_t block = extent.start_block(); | 880 for (uint64_t block = extent.start_block(); |
876 block < (extent.start_block() + extent.num_blocks()); block++) { | 881 block < (extent.start_block() + extent.num_blocks()); block++) { |
877 written_count[block]++; | 882 if (block < blocks.size()) |
Will Drewry
2010/09/29 01:10:47
Does this just catch if scratch blocks are written
petkov
2010/09/29 04:27:40
My understanding is that this code makes sure that
Will Drewry
2010/09/29 04:33:41
Fair enough. We can go through that with adlr@ wh
| |
883 written_count[block]++; | |
878 } | 884 } |
879 } | 885 } |
880 if (op->has_data_offset()) { | 886 if (op->has_data_offset()) { |
881 if (op->data_offset() != next_blob_offset) { | 887 if (op->data_offset() != next_blob_offset) { |
882 LOG(FATAL) << "bad blob offset! " << op->data_offset() << " != " | 888 LOG(FATAL) << "bad blob offset! " << op->data_offset() << " != " |
883 << next_blob_offset; | 889 << next_blob_offset; |
884 } | 890 } |
885 next_blob_offset += op->data_length(); | 891 next_blob_offset += op->data_length(); |
886 } | 892 } |
887 } | 893 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
980 | 986 |
981 LOG(INFO) << "All done. Successfully created delta file."; | 987 LOG(INFO) << "All done. Successfully created delta file."; |
982 return true; | 988 return true; |
983 } | 989 } |
984 | 990 |
985 const char* const kBsdiffPath = "/usr/bin/bsdiff"; | 991 const char* const kBsdiffPath = "/usr/bin/bsdiff"; |
986 const char* const kBspatchPath = "/usr/bin/bspatch"; | 992 const char* const kBspatchPath = "/usr/bin/bspatch"; |
987 const char* const kDeltaMagic = "CrAU"; | 993 const char* const kDeltaMagic = "CrAU"; |
988 | 994 |
989 }; // namespace chromeos_update_engine | 995 }; // namespace chromeos_update_engine |
OLD | NEW |