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 |