| 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/update_attempter.h" | 5 #include "update_engine/update_attempter.h" |
| 6 | 6 |
| 7 // From 'man clock_gettime': feature test macro: _POSIX_C_SOURCE >= 199309L | 7 // From 'man clock_gettime': feature test macro: _POSIX_C_SOURCE >= 199309L |
| 8 #ifndef _POSIX_C_SOURCE | 8 #ifndef _POSIX_C_SOURCE |
| 9 #define _POSIX_C_SOURCE 199309L | 9 #define _POSIX_C_SOURCE 199309L |
| 10 #endif // _POSIX_C_SOURCE | 10 #endif // _POSIX_C_SOURCE |
| 11 #include <time.h> | 11 #include <time.h> |
| 12 | 12 |
| 13 #include <tr1/memory> | 13 #include <tr1/memory> |
| 14 #include <string> | 14 #include <string> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include <glib.h> | 17 #include <glib.h> |
| 18 #include <metrics/metrics_library.h> | 18 #include <metrics/metrics_library.h> |
| 19 | 19 |
| 20 #include "update_engine/dbus_service.h" | 20 #include "update_engine/dbus_service.h" |
| 21 #include "update_engine/download_action.h" | 21 #include "update_engine/download_action.h" |
| 22 #include "update_engine/filesystem_copier_action.h" | 22 #include "update_engine/filesystem_copier_action.h" |
| 23 #include "update_engine/libcurl_http_fetcher.h" | 23 #include "update_engine/libcurl_http_fetcher.h" |
| 24 #include "update_engine/omaha_request_action.h" | 24 #include "update_engine/omaha_request_action.h" |
| 25 #include "update_engine/omaha_request_params.h" | 25 #include "update_engine/omaha_request_params.h" |
| 26 #include "update_engine/omaha_response_handler_action.h" | 26 #include "update_engine/omaha_response_handler_action.h" |
| 27 #include "update_engine/postinstall_runner_action.h" | 27 #include "update_engine/postinstall_runner_action.h" |
| 28 #include "update_engine/prefs_interface.h" |
| 28 #include "update_engine/set_bootable_flag_action.h" | 29 #include "update_engine/set_bootable_flag_action.h" |
| 29 #include "update_engine/update_check_scheduler.h" | 30 #include "update_engine/update_check_scheduler.h" |
| 30 | 31 |
| 31 using base::TimeDelta; | 32 using base::TimeDelta; |
| 32 using base::TimeTicks; | 33 using base::TimeTicks; |
| 33 using std::tr1::shared_ptr; | 34 using std::tr1::shared_ptr; |
| 34 using std::string; | 35 using std::string; |
| 35 using std::vector; | 36 using std::vector; |
| 36 | 37 |
| 37 namespace chromeos_update_engine { | 38 namespace chromeos_update_engine { |
| 38 | 39 |
| 40 const int UpdateAttempter::kMaxDeltaUpdateFailures = 3; |
| 41 |
| 39 const char* kUpdateCompletedMarker = | 42 const char* kUpdateCompletedMarker = |
| 40 "/var/run/update_engine_autoupdate_completed"; | 43 "/var/run/update_engine_autoupdate_completed"; |
| 41 | 44 |
| 42 const char* UpdateStatusToString(UpdateStatus status) { | 45 const char* UpdateStatusToString(UpdateStatus status) { |
| 43 switch (status) { | 46 switch (status) { |
| 44 case UPDATE_STATUS_IDLE: | 47 case UPDATE_STATUS_IDLE: |
| 45 return "UPDATE_STATUS_IDLE"; | 48 return "UPDATE_STATUS_IDLE"; |
| 46 case UPDATE_STATUS_CHECKING_FOR_UPDATE: | 49 case UPDATE_STATUS_CHECKING_FOR_UPDATE: |
| 47 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; | 50 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; |
| 48 case UPDATE_STATUS_UPDATE_AVAILABLE: | 51 case UPDATE_STATUS_UPDATE_AVAILABLE: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 metrics_lib_(metrics_lib), | 97 metrics_lib_(metrics_lib), |
| 95 update_check_scheduler_(NULL), | 98 update_check_scheduler_(NULL), |
| 96 http_response_code_(0), | 99 http_response_code_(0), |
| 97 priority_(utils::kProcessPriorityNormal), | 100 priority_(utils::kProcessPriorityNormal), |
| 98 manage_priority_source_(NULL), | 101 manage_priority_source_(NULL), |
| 99 download_active_(false), | 102 download_active_(false), |
| 100 status_(UPDATE_STATUS_IDLE), | 103 status_(UPDATE_STATUS_IDLE), |
| 101 download_progress_(0.0), | 104 download_progress_(0.0), |
| 102 last_checked_time_(0), | 105 last_checked_time_(0), |
| 103 new_version_("0.0.0.0"), | 106 new_version_("0.0.0.0"), |
| 104 new_size_(0) { | 107 new_size_(0), |
| 108 is_full_update_(false) { |
| 105 if (utils::FileExists(kUpdateCompletedMarker)) | 109 if (utils::FileExists(kUpdateCompletedMarker)) |
| 106 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; | 110 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; |
| 107 } | 111 } |
| 108 | 112 |
| 109 UpdateAttempter::~UpdateAttempter() { | 113 UpdateAttempter::~UpdateAttempter() { |
| 110 CleanupPriorityManagement(); | 114 CleanupPriorityManagement(); |
| 111 } | 115 } |
| 112 | 116 |
| 113 void UpdateAttempter::Update(const std::string& app_version, | 117 void UpdateAttempter::Update(const std::string& app_version, |
| 114 const std::string& omaha_url) { | 118 const std::string& omaha_url) { |
| 115 if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) { | 119 if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) { |
| 116 LOG(INFO) << "Not updating b/c we already updated and we're waiting for " | 120 LOG(INFO) << "Not updating b/c we already updated and we're waiting for " |
| 117 << "reboot"; | 121 << "reboot"; |
| 118 return; | 122 return; |
| 119 } | 123 } |
| 120 if (status_ != UPDATE_STATUS_IDLE) { | 124 if (status_ != UPDATE_STATUS_IDLE) { |
| 121 // Update in progress. Do nothing | 125 // Update in progress. Do nothing |
| 122 return; | 126 return; |
| 123 } | 127 } |
| 124 http_response_code_ = 0; | 128 http_response_code_ = 0; |
| 125 if (!omaha_request_params_.Init(app_version, omaha_url)) { | 129 if (!omaha_request_params_.Init(app_version, omaha_url)) { |
| 126 LOG(ERROR) << "Unable to initialize Omaha request device params."; | 130 LOG(ERROR) << "Unable to initialize Omaha request device params."; |
| 127 return; | 131 return; |
| 128 } | 132 } |
| 133 DisableDeltaUpdateIfNeeded(); |
| 129 CHECK(!processor_->IsRunning()); | 134 CHECK(!processor_->IsRunning()); |
| 130 processor_->set_delegate(this); | 135 processor_->set_delegate(this); |
| 131 | 136 |
| 132 // Actions: | 137 // Actions: |
| 133 shared_ptr<OmahaRequestAction> update_check_action( | 138 shared_ptr<OmahaRequestAction> update_check_action( |
| 134 new OmahaRequestAction(prefs_, | 139 new OmahaRequestAction(prefs_, |
| 135 omaha_request_params_, | 140 omaha_request_params_, |
| 136 NULL, | 141 NULL, |
| 137 new LibcurlHttpFetcher)); | 142 new LibcurlHttpFetcher)); |
| 138 shared_ptr<OmahaResponseHandlerAction> response_handler_action( | 143 shared_ptr<OmahaResponseHandlerAction> response_handler_action( |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 249 |
| 245 if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { | 250 if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { |
| 246 LOG(INFO) << "Error event sent."; | 251 LOG(INFO) << "Error event sent."; |
| 247 SetStatusAndNotify(UPDATE_STATUS_IDLE); | 252 SetStatusAndNotify(UPDATE_STATUS_IDLE); |
| 248 return; | 253 return; |
| 249 } | 254 } |
| 250 | 255 |
| 251 if (code == kActionCodeSuccess) { | 256 if (code == kActionCodeSuccess) { |
| 252 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT); | 257 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT); |
| 253 utils::WriteFile(kUpdateCompletedMarker, "", 0); | 258 utils::WriteFile(kUpdateCompletedMarker, "", 0); |
| 259 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); |
| 254 | 260 |
| 255 // Report the time it took to update the system. | 261 // Report the time it took to update the system. |
| 256 int64_t update_time = time(NULL) - last_checked_time_; | 262 int64_t update_time = time(NULL) - last_checked_time_; |
| 257 metrics_lib_->SendToUMA("Installer.UpdateTime", | 263 metrics_lib_->SendToUMA("Installer.UpdateTime", |
| 258 static_cast<int>(update_time), // sample | 264 static_cast<int>(update_time), // sample |
| 259 1, // min = 1 second | 265 1, // min = 1 second |
| 260 20 * 60, // max = 20 minutes | 266 20 * 60, // max = 20 minutes |
| 261 50); // buckets | 267 50); // buckets |
| 262 return; | 268 return; |
| 263 } | 269 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 http_response_code_ = omaha_request_action->GetHTTPResponseCode(); | 306 http_response_code_ = omaha_request_action->GetHTTPResponseCode(); |
| 301 // Forward the server-dictated poll interval to the update check | 307 // Forward the server-dictated poll interval to the update check |
| 302 // scheduler, if any. | 308 // scheduler, if any. |
| 303 if (update_check_scheduler_) { | 309 if (update_check_scheduler_) { |
| 304 update_check_scheduler_->set_poll_interval( | 310 update_check_scheduler_->set_poll_interval( |
| 305 omaha_request_action->GetOutputObject().poll_interval); | 311 omaha_request_action->GetOutputObject().poll_interval); |
| 306 } | 312 } |
| 307 } | 313 } |
| 308 } | 314 } |
| 309 if (code != kActionCodeSuccess) { | 315 if (code != kActionCodeSuccess) { |
| 316 // If this was a delta update attempt and the current state is at or past |
| 317 // the download phase, count the failure in case a switch to full update |
| 318 // becomes necessary. Ignore network transfer timeouts and failures. |
| 319 if (status_ >= UPDATE_STATUS_DOWNLOADING && |
| 320 !is_full_update_ && |
| 321 code != kActionCodeDownloadTransferError) { |
| 322 MarkDeltaUpdateFailure(); |
| 323 } |
| 310 // On failure, schedule an error event to be sent to Omaha. | 324 // On failure, schedule an error event to be sent to Omaha. |
| 311 CreatePendingErrorEvent(action, code); | 325 CreatePendingErrorEvent(action, code); |
| 312 return; | 326 return; |
| 313 } | 327 } |
| 314 // Find out which action completed. | 328 // Find out which action completed. |
| 315 if (type == OmahaResponseHandlerAction::StaticType()) { | 329 if (type == OmahaResponseHandlerAction::StaticType()) { |
| 316 // Note that the status will be updated to DOWNLOADING when some | 330 // Note that the status will be updated to DOWNLOADING when some |
| 317 // bytes get actually downloaded from the server and the | 331 // bytes get actually downloaded from the server and the |
| 318 // BytesReceived callback is invoked. This avoids notifying the | 332 // BytesReceived callback is invoked. This avoids notifying the |
| 319 // user that a download has started in cases when the server and | 333 // user that a download has started in cases when the server and |
| 320 // the client are unable to initiate the download. | 334 // the client are unable to initiate the download. |
| 321 OmahaResponseHandlerAction* omaha_response_handler_action = | 335 OmahaResponseHandlerAction* omaha_response_handler_action = |
| 322 dynamic_cast<OmahaResponseHandlerAction*>(action); | 336 dynamic_cast<OmahaResponseHandlerAction*>(action); |
| 323 CHECK(omaha_response_handler_action); | 337 CHECK(omaha_response_handler_action); |
| 324 const InstallPlan& plan = omaha_response_handler_action->install_plan(); | 338 const InstallPlan& plan = omaha_response_handler_action->install_plan(); |
| 325 last_checked_time_ = time(NULL); | 339 last_checked_time_ = time(NULL); |
| 326 // TODO(adlr): put version in InstallPlan | 340 // TODO(adlr): put version in InstallPlan |
| 327 new_version_ = "0.0.0.0"; | 341 new_version_ = "0.0.0.0"; |
| 328 new_size_ = plan.size; | 342 new_size_ = plan.size; |
| 343 is_full_update_ = plan.is_full_update; |
| 329 SetupPriorityManagement(); | 344 SetupPriorityManagement(); |
| 330 } else if (type == DownloadAction::StaticType()) { | 345 } else if (type == DownloadAction::StaticType()) { |
| 331 SetStatusAndNotify(UPDATE_STATUS_FINALIZING); | 346 SetStatusAndNotify(UPDATE_STATUS_FINALIZING); |
| 332 } | 347 } |
| 333 } | 348 } |
| 334 | 349 |
| 335 // Stop updating. An attempt will be made to record status to the disk | 350 // Stop updating. An attempt will be made to record status to the disk |
| 336 // so that updates can be resumed later. | 351 // so that updates can be resumed later. |
| 337 void UpdateAttempter::Terminate() { | 352 void UpdateAttempter::Terminate() { |
| 338 // TODO(adlr): implement this method. | 353 // TODO(adlr): implement this method. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 if (utils::ComparePriorities(priority_, utils::kProcessPriorityNormal) < 0) { | 498 if (utils::ComparePriorities(priority_, utils::kProcessPriorityNormal) < 0) { |
| 484 SetPriority(utils::kProcessPriorityNormal); | 499 SetPriority(utils::kProcessPriorityNormal); |
| 485 return true; | 500 return true; |
| 486 } | 501 } |
| 487 // Set the priority to high and let GLib destroy the timeout source. | 502 // Set the priority to high and let GLib destroy the timeout source. |
| 488 SetPriority(utils::kProcessPriorityHigh); | 503 SetPriority(utils::kProcessPriorityHigh); |
| 489 manage_priority_source_ = NULL; | 504 manage_priority_source_ = NULL; |
| 490 return false; | 505 return false; |
| 491 } | 506 } |
| 492 | 507 |
| 508 void UpdateAttempter::DisableDeltaUpdateIfNeeded() { |
| 509 int64_t delta_failures; |
| 510 if (omaha_request_params_.delta_okay && |
| 511 prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) && |
| 512 delta_failures >= kMaxDeltaUpdateFailures) { |
| 513 LOG(WARNING) << "Too many delta update failures, forcing full update."; |
| 514 omaha_request_params_.delta_okay = false; |
| 515 } |
| 516 } |
| 517 |
| 518 void UpdateAttempter::MarkDeltaUpdateFailure() { |
| 519 CHECK(!is_full_update_); |
| 520 int64_t delta_failures; |
| 521 if (!prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) || |
| 522 delta_failures < 0) { |
| 523 delta_failures = 0; |
| 524 } |
| 525 prefs_->SetInt64(kPrefsDeltaUpdateFailures, ++delta_failures); |
| 526 } |
| 527 |
| 493 } // namespace chromeos_update_engine | 528 } // namespace chromeos_update_engine |
| OLD | NEW |