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/delta_performer.h" | 5 #include "update_engine/delta_performer.h" |
6 | 6 |
7 #include <endian.h> | 7 #include <endian.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 ssize_t total_operations = manifest_.install_operations_size() + | 215 ssize_t total_operations = manifest_.install_operations_size() + |
216 manifest_.kernel_install_operations_size(); | 216 manifest_.kernel_install_operations_size(); |
217 while (next_operation_num_ < total_operations) { | 217 while (next_operation_num_ < total_operations) { |
218 const DeltaArchiveManifest_InstallOperation &op = | 218 const DeltaArchiveManifest_InstallOperation &op = |
219 next_operation_num_ < manifest_.install_operations_size() ? | 219 next_operation_num_ < manifest_.install_operations_size() ? |
220 manifest_.install_operations(next_operation_num_) : | 220 manifest_.install_operations(next_operation_num_) : |
221 manifest_.kernel_install_operations( | 221 manifest_.kernel_install_operations( |
222 next_operation_num_ - manifest_.install_operations_size()); | 222 next_operation_num_ - manifest_.install_operations_size()); |
223 if (!CanPerformInstallOperation(op)) | 223 if (!CanPerformInstallOperation(op)) |
224 break; | 224 break; |
| 225 // Makes sure we unblock exit when this operation completes. |
225 ScopedTerminatorExitUnblocker exit_unblocker = | 226 ScopedTerminatorExitUnblocker exit_unblocker = |
226 ScopedTerminatorExitUnblocker(); // Avoids a compiler unused var bug. | 227 ScopedTerminatorExitUnblocker(); // Avoids a compiler unused var bug. |
227 // Log every thousandth operation, and also the first and last ones | 228 // Log every thousandth operation, and also the first and last ones |
228 if ((next_operation_num_ % 1000 == 0) || | 229 if ((next_operation_num_ % 1000 == 0) || |
229 (next_operation_num_ + 1 == total_operations)) { | 230 (next_operation_num_ + 1 == total_operations)) { |
230 LOG(INFO) << "Performing operation " << (next_operation_num_ + 1) << "/" | 231 LOG(INFO) << "Performing operation " << (next_operation_num_ + 1) << "/" |
231 << total_operations; | 232 << total_operations; |
232 } | 233 } |
233 bool is_kernel_partition = | 234 bool is_kernel_partition = |
234 (next_operation_num_ >= manifest_.install_operations_size()); | 235 (next_operation_num_ >= manifest_.install_operations_size()); |
235 // If about to start a non-idempotent operation, clear the update state so | |
236 // that if the operation gets interrupted, we don't try to resume the | |
237 // update. | |
238 if (!IsIdempotentOperation(op)) { | |
239 Terminator::set_exit_blocked(true); | |
240 ResetUpdateProgress(prefs_, true); | |
241 } | |
242 if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE || | 236 if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE || |
243 op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) { | 237 op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) { |
244 if (!PerformReplaceOperation(op, is_kernel_partition)) { | 238 if (!PerformReplaceOperation(op, is_kernel_partition)) { |
245 LOG(ERROR) << "Failed to perform replace operation " | 239 LOG(ERROR) << "Failed to perform replace operation " |
246 << next_operation_num_; | 240 << next_operation_num_; |
247 return -EINVAL; | 241 return -EINVAL; |
248 } | 242 } |
249 } else if (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE) { | 243 } else if (op.type() == DeltaArchiveManifest_InstallOperation_Type_MOVE) { |
250 if (!PerformMoveOperation(op, is_kernel_partition)) { | 244 if (!PerformMoveOperation(op, is_kernel_partition)) { |
251 LOG(ERROR) << "Failed to perform move operation " | 245 LOG(ERROR) << "Failed to perform move operation " |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 &buf[bytes_read], | 358 &buf[bytes_read], |
365 extent.num_blocks() * block_size_, | 359 extent.num_blocks() * block_size_, |
366 extent.start_block() * block_size_, | 360 extent.start_block() * block_size_, |
367 &bytes_read_this_iteration)); | 361 &bytes_read_this_iteration)); |
368 TEST_AND_RETURN_FALSE( | 362 TEST_AND_RETURN_FALSE( |
369 bytes_read_this_iteration == | 363 bytes_read_this_iteration == |
370 static_cast<ssize_t>(extent.num_blocks() * block_size_)); | 364 static_cast<ssize_t>(extent.num_blocks() * block_size_)); |
371 bytes_read += bytes_read_this_iteration; | 365 bytes_read += bytes_read_this_iteration; |
372 } | 366 } |
373 | 367 |
| 368 // If this is a non-idempotent operation, request a delayed exit and clear the |
| 369 // update state in case the operation gets interrupted. Do this as late as |
| 370 // possible. |
| 371 if (!IsIdempotentOperation(operation)) { |
| 372 Terminator::set_exit_blocked(true); |
| 373 ResetUpdateProgress(prefs_, true); |
| 374 } |
| 375 |
374 // Write bytes out. | 376 // Write bytes out. |
375 ssize_t bytes_written = 0; | 377 ssize_t bytes_written = 0; |
376 for (int i = 0; i < operation.dst_extents_size(); i++) { | 378 for (int i = 0; i < operation.dst_extents_size(); i++) { |
377 const Extent& extent = operation.dst_extents(i); | 379 const Extent& extent = operation.dst_extents(i); |
378 TEST_AND_RETURN_FALSE(utils::PWriteAll(fd, | 380 TEST_AND_RETURN_FALSE(utils::PWriteAll(fd, |
379 &buf[bytes_written], | 381 &buf[bytes_written], |
380 extent.num_blocks() * block_size_, | 382 extent.num_blocks() * block_size_, |
381 extent.start_block() * block_size_)); | 383 extent.start_block() * block_size_)); |
382 bytes_written += extent.num_blocks() * block_size_; | 384 bytes_written += extent.num_blocks() * block_size_; |
383 } | 385 } |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 { | 441 { |
440 int fd = open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644); | 442 int fd = open(temp_filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644); |
441 ScopedFdCloser fd_closer(&fd); | 443 ScopedFdCloser fd_closer(&fd); |
442 TEST_AND_RETURN_FALSE( | 444 TEST_AND_RETURN_FALSE( |
443 utils::WriteAll(fd, &buffer_[0], operation.data_length())); | 445 utils::WriteAll(fd, &buffer_[0], operation.data_length())); |
444 } | 446 } |
445 | 447 |
446 int fd = is_kernel_partition ? kernel_fd_ : fd_; | 448 int fd = is_kernel_partition ? kernel_fd_ : fd_; |
447 const string& path = is_kernel_partition ? kernel_path_ : path_; | 449 const string& path = is_kernel_partition ? kernel_path_ : path_; |
448 | 450 |
| 451 // If this is a non-idempotent operation, request a delayed exit and clear the |
| 452 // update state in case the operation gets interrupted. Do this as late as |
| 453 // possible. |
| 454 if (!IsIdempotentOperation(operation)) { |
| 455 Terminator::set_exit_blocked(true); |
| 456 ResetUpdateProgress(prefs_, true); |
| 457 } |
| 458 |
449 vector<string> cmd; | 459 vector<string> cmd; |
450 cmd.push_back(kBspatchPath); | 460 cmd.push_back(kBspatchPath); |
451 cmd.push_back(path); | 461 cmd.push_back(path); |
452 cmd.push_back(path); | 462 cmd.push_back(path); |
453 cmd.push_back(temp_filename); | 463 cmd.push_back(temp_filename); |
454 cmd.push_back(input_positions); | 464 cmd.push_back(input_positions); |
455 cmd.push_back(output_positions); | 465 cmd.push_back(output_positions); |
456 int return_code = 0; | 466 int return_code = 0; |
457 TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &return_code)); | 467 TEST_AND_RETURN_FALSE(Subprocess::SynchronousExec(cmd, &return_code)); |
458 TEST_AND_RETURN_FALSE(return_code == 0); | 468 TEST_AND_RETURN_FALSE(return_code == 0); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 if (prefs_->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures)) { | 670 if (prefs_->GetInt64(kPrefsResumedUpdateFailures, &resumed_update_failures)) { |
661 resumed_update_failures++; | 671 resumed_update_failures++; |
662 } else { | 672 } else { |
663 resumed_update_failures = 1; | 673 resumed_update_failures = 1; |
664 } | 674 } |
665 prefs_->SetInt64(kPrefsResumedUpdateFailures, resumed_update_failures); | 675 prefs_->SetInt64(kPrefsResumedUpdateFailures, resumed_update_failures); |
666 return true; | 676 return true; |
667 } | 677 } |
668 | 678 |
669 } // namespace chromeos_update_engine | 679 } // namespace chromeos_update_engine |
OLD | NEW |