OLD | NEW |
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/filesystem_copier_action.h" | 5 #include "update_engine/filesystem_copier_action.h" |
6 | 6 |
7 #include <sys/stat.h> | 7 #include <sys/stat.h> |
8 #include <sys/types.h> | 8 #include <sys/types.h> |
9 #include <errno.h> | 9 #include <errno.h> |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 int dst_fd = open(destination.c_str(), | 72 int dst_fd = open(destination.c_str(), |
73 O_WRONLY | O_TRUNC | O_CREAT, | 73 O_WRONLY | O_TRUNC | O_CREAT, |
74 0644); | 74 0644); |
75 if (dst_fd < 0) { | 75 if (dst_fd < 0) { |
76 close(src_fd); | 76 close(src_fd); |
77 PLOG(ERROR) << "Unable to open " << install_plan_.install_path | 77 PLOG(ERROR) << "Unable to open " << install_plan_.install_path |
78 << " for writing:"; | 78 << " for writing:"; |
79 return; | 79 return; |
80 } | 80 } |
81 | 81 |
| 82 DetermineFilesystemSize(src_fd); |
| 83 |
82 src_stream_ = g_unix_input_stream_new(src_fd, TRUE); | 84 src_stream_ = g_unix_input_stream_new(src_fd, TRUE); |
83 dst_stream_ = g_unix_output_stream_new(dst_fd, TRUE); | 85 dst_stream_ = g_unix_output_stream_new(dst_fd, TRUE); |
84 | 86 |
85 buffer_.resize(kCopyFileBufferSize); | 87 buffer_.resize(kCopyFileBufferSize); |
86 | 88 |
87 // Set up the first read | 89 // Set up the first read |
88 canceller_ = g_cancellable_new(); | 90 canceller_ = g_cancellable_new(); |
89 | 91 |
90 g_input_stream_read_async(src_stream_, | 92 g_input_stream_read_async(src_stream_, |
91 &buffer_[0], | 93 &buffer_[0], |
92 buffer_.size(), | 94 GetBytesToRead(), |
93 G_PRIORITY_DEFAULT, | 95 G_PRIORITY_DEFAULT, |
94 canceller_, | 96 canceller_, |
95 &FilesystemCopierAction::StaticAsyncReadyCallback, | 97 &FilesystemCopierAction::StaticAsyncReadyCallback, |
96 this); | 98 this); |
97 read_in_flight_ = true; | 99 read_in_flight_ = true; |
98 | 100 |
99 abort_action_completer.set_should_complete(false); | 101 abort_action_completer.set_should_complete(false); |
100 } | 102 } |
101 | 103 |
102 void FilesystemCopierAction::TerminateProcessing() { | 104 void FilesystemCopierAction::TerminateProcessing() { |
(...skipping 27 matching lines...) Expand all Loading... |
130 if (read_in_flight_) { | 132 if (read_in_flight_) { |
131 ssize_t bytes_read = g_input_stream_read_finish(src_stream_, res, &error); | 133 ssize_t bytes_read = g_input_stream_read_finish(src_stream_, res, &error); |
132 if (bytes_read < 0) { | 134 if (bytes_read < 0) { |
133 LOG(ERROR) << "Read failed:" << utils::GetGErrorMessage(error); | 135 LOG(ERROR) << "Read failed:" << utils::GetGErrorMessage(error); |
134 Cleanup(false, was_cancelled); | 136 Cleanup(false, was_cancelled); |
135 return; | 137 return; |
136 } | 138 } |
137 | 139 |
138 if (bytes_read == 0) { | 140 if (bytes_read == 0) { |
139 // We're done! | 141 // We're done! |
| 142 if (!hasher_.Finalize()) { |
| 143 LOG(ERROR) << "Unable to finalize the hash."; |
| 144 Cleanup(false, was_cancelled); |
| 145 return; |
| 146 } |
| 147 LOG(INFO) << "hash: " << hasher_.hash(); |
| 148 if (copying_kernel_install_path_) { |
| 149 install_plan_.current_kernel_hash = hasher_.raw_hash(); |
| 150 } else { |
| 151 install_plan_.current_rootfs_hash = hasher_.raw_hash(); |
| 152 } |
140 Cleanup(true, was_cancelled); | 153 Cleanup(true, was_cancelled); |
141 return; | 154 return; |
142 } | 155 } |
| 156 if (!hasher_.Update(buffer_.data(), bytes_read)) { |
| 157 LOG(ERROR) << "Unable to update the hash."; |
| 158 Cleanup(false, was_cancelled); |
| 159 return; |
| 160 } |
| 161 filesystem_size_ -= bytes_read; |
| 162 |
143 // Kick off a write | 163 // Kick off a write |
144 read_in_flight_ = false; | 164 read_in_flight_ = false; |
145 buffer_valid_size_ = bytes_read; | 165 buffer_valid_size_ = bytes_read; |
146 canceller_ = g_cancellable_new(); | 166 canceller_ = g_cancellable_new(); |
147 g_output_stream_write_async( | 167 g_output_stream_write_async( |
148 dst_stream_, | 168 dst_stream_, |
149 &buffer_[0], | 169 &buffer_[0], |
150 bytes_read, | 170 bytes_read, |
151 G_PRIORITY_DEFAULT, | 171 G_PRIORITY_DEFAULT, |
152 canceller_, | 172 canceller_, |
(...skipping 15 matching lines...) Expand all Loading... |
168 Cleanup(false, was_cancelled); | 188 Cleanup(false, was_cancelled); |
169 return; | 189 return; |
170 } | 190 } |
171 | 191 |
172 // Kick off a read | 192 // Kick off a read |
173 read_in_flight_ = true; | 193 read_in_flight_ = true; |
174 canceller_ = g_cancellable_new(); | 194 canceller_ = g_cancellable_new(); |
175 g_input_stream_read_async( | 195 g_input_stream_read_async( |
176 src_stream_, | 196 src_stream_, |
177 &buffer_[0], | 197 &buffer_[0], |
178 buffer_.size(), | 198 GetBytesToRead(), |
179 G_PRIORITY_DEFAULT, | 199 G_PRIORITY_DEFAULT, |
180 canceller_, | 200 canceller_, |
181 &FilesystemCopierAction::StaticAsyncReadyCallback, | 201 &FilesystemCopierAction::StaticAsyncReadyCallback, |
182 this); | 202 this); |
183 } | 203 } |
184 | 204 |
| 205 void FilesystemCopierAction::DetermineFilesystemSize(int fd) { |
| 206 filesystem_size_ = kint64max; |
| 207 int block_count = 0, block_size = 0; |
| 208 if (!copying_kernel_install_path_ && |
| 209 utils::GetFilesystemSizeFromFD(fd, &block_count, &block_size)) { |
| 210 filesystem_size_ = static_cast<int64_t>(block_count) * block_size; |
| 211 LOG(INFO) << "Filesystem size: " << filesystem_size_ << " bytes (" |
| 212 << block_count << "x" << block_size << ")."; |
| 213 } |
| 214 } |
| 215 |
| 216 int64_t FilesystemCopierAction::GetBytesToRead() { |
| 217 return std::min(static_cast<int64_t>(buffer_.size()), filesystem_size_); |
| 218 } |
| 219 |
185 } // namespace chromeos_update_engine | 220 } // namespace chromeos_update_engine |
OLD | NEW |