| 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 |