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 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 if (type == FilesystemCopierAction::StaticType()) | 107 if (type == FilesystemCopierAction::StaticType()) |
108 return kActionCodeFilesystemCopierError; | 108 return kActionCodeFilesystemCopierError; |
109 if (type == PostinstallRunnerAction::StaticType()) | 109 if (type == PostinstallRunnerAction::StaticType()) |
110 return kActionCodePostinstallRunnerError; | 110 return kActionCodePostinstallRunnerError; |
111 if (type == SetBootableFlagAction::StaticType()) | 111 if (type == SetBootableFlagAction::StaticType()) |
112 return kActionCodeSetBootableFlagError; | 112 return kActionCodeSetBootableFlagError; |
113 | 113 |
114 return code; | 114 return code; |
115 } | 115 } |
116 | 116 |
| 117 UpdateAttempter::UpdateAttempter(PrefsInterface* prefs, |
| 118 MetricsLibraryInterface* metrics_lib) |
| 119 : dbus_service_(NULL), |
| 120 prefs_(prefs), |
| 121 metrics_lib_(metrics_lib), |
| 122 priority_(utils::kProcessPriorityNormal), |
| 123 manage_priority_source_(NULL), |
| 124 status_(UPDATE_STATUS_IDLE), |
| 125 download_progress_(0.0), |
| 126 last_checked_time_(0), |
| 127 new_version_("0.0.0.0"), |
| 128 new_size_(0) { |
| 129 last_notify_time_.tv_sec = 0; |
| 130 last_notify_time_.tv_nsec = 0; |
| 131 if (utils::FileExists(kUpdateCompletedMarker)) |
| 132 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; |
| 133 } |
| 134 |
| 135 UpdateAttempter::~UpdateAttempter() { |
| 136 CleanupPriorityManagement(); |
| 137 } |
| 138 |
117 void UpdateAttempter::Update(const std::string& app_version, | 139 void UpdateAttempter::Update(const std::string& app_version, |
118 const std::string& omaha_url) { | 140 const std::string& omaha_url) { |
119 if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) { | 141 if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) { |
120 LOG(INFO) << "Not updating b/c we already updated and we're waiting for " | 142 LOG(INFO) << "Not updating b/c we already updated and we're waiting for " |
121 << "reboot"; | 143 << "reboot"; |
122 return; | 144 return; |
123 } | 145 } |
124 if (status_ != UPDATE_STATUS_IDLE) { | 146 if (status_ != UPDATE_STATUS_IDLE) { |
125 // Update in progress. Do nothing | 147 // Update in progress. Do nothing |
126 return; | 148 return; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 return true; | 257 return true; |
236 } | 258 } |
237 | 259 |
238 // Delegate methods: | 260 // Delegate methods: |
239 void UpdateAttempter::ProcessingDone(const ActionProcessor* processor, | 261 void UpdateAttempter::ProcessingDone(const ActionProcessor* processor, |
240 ActionExitCode code) { | 262 ActionExitCode code) { |
241 CHECK(response_handler_action_); | 263 CHECK(response_handler_action_); |
242 LOG(INFO) << "Processing Done."; | 264 LOG(INFO) << "Processing Done."; |
243 actions_.clear(); | 265 actions_.clear(); |
244 | 266 |
| 267 // Reset process priority back to normal. |
| 268 CleanupPriorityManagement(); |
| 269 |
245 if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { | 270 if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { |
246 LOG(INFO) << "Error event sent."; | 271 LOG(INFO) << "Error event sent."; |
247 SetStatusAndNotify(UPDATE_STATUS_IDLE); | 272 SetStatusAndNotify(UPDATE_STATUS_IDLE); |
248 return; | 273 return; |
249 } | 274 } |
250 | 275 |
251 if (code == kActionCodeSuccess) { | 276 if (code == kActionCodeSuccess) { |
252 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT); | 277 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT); |
253 utils::WriteFile(kUpdateCompletedMarker, "", 0); | 278 utils::WriteFile(kUpdateCompletedMarker, "", 0); |
254 | 279 |
255 // Report the time it took to update the system. | 280 // Report the time it took to update the system. |
256 int64_t update_time = time(NULL) - last_checked_time_; | 281 int64_t update_time = time(NULL) - last_checked_time_; |
257 metrics_lib_->SendToUMA("Installer.UpdateTime", | 282 metrics_lib_->SendToUMA("Installer.UpdateTime", |
258 static_cast<int>(update_time), // sample | 283 static_cast<int>(update_time), // sample |
259 1, // min = 1 second | 284 1, // min = 1 second |
260 20 * 60, // max = 20 minutes | 285 20 * 60, // max = 20 minutes |
261 50); // buckets | 286 50); // buckets |
262 return; | 287 return; |
263 } | 288 } |
264 | 289 |
265 LOG(INFO) << "Update failed."; | 290 LOG(INFO) << "Update failed."; |
266 if (ScheduleErrorEventAction()) | 291 if (ScheduleErrorEventAction()) |
267 return; | 292 return; |
268 SetStatusAndNotify(UPDATE_STATUS_IDLE); | 293 SetStatusAndNotify(UPDATE_STATUS_IDLE); |
269 } | 294 } |
270 | 295 |
271 void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) { | 296 void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) { |
| 297 // Reset process priority back to normal. |
| 298 CleanupPriorityManagement(); |
272 download_progress_ = 0.0; | 299 download_progress_ = 0.0; |
273 SetStatusAndNotify(UPDATE_STATUS_IDLE); | 300 SetStatusAndNotify(UPDATE_STATUS_IDLE); |
274 actions_.clear(); | 301 actions_.clear(); |
275 error_event_.reset(NULL); | 302 error_event_.reset(NULL); |
276 } | 303 } |
277 | 304 |
278 // Called whenever an action has finished processing, either successfully | 305 // Called whenever an action has finished processing, either successfully |
279 // or otherwise. | 306 // or otherwise. |
280 void UpdateAttempter::ActionCompleted(ActionProcessor* processor, | 307 void UpdateAttempter::ActionCompleted(ActionProcessor* processor, |
281 AbstractAction* action, | 308 AbstractAction* action, |
(...skipping 12 matching lines...) Expand all Loading... |
294 if (type == OmahaResponseHandlerAction::StaticType()) { | 321 if (type == OmahaResponseHandlerAction::StaticType()) { |
295 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); | 322 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); |
296 OmahaResponseHandlerAction* omaha_response_handler_action = | 323 OmahaResponseHandlerAction* omaha_response_handler_action = |
297 dynamic_cast<OmahaResponseHandlerAction*>(action); | 324 dynamic_cast<OmahaResponseHandlerAction*>(action); |
298 CHECK(omaha_response_handler_action); | 325 CHECK(omaha_response_handler_action); |
299 const InstallPlan& plan = omaha_response_handler_action->install_plan(); | 326 const InstallPlan& plan = omaha_response_handler_action->install_plan(); |
300 last_checked_time_ = time(NULL); | 327 last_checked_time_ = time(NULL); |
301 // TODO(adlr): put version in InstallPlan | 328 // TODO(adlr): put version in InstallPlan |
302 new_version_ = "0.0.0.0"; | 329 new_version_ = "0.0.0.0"; |
303 new_size_ = plan.size; | 330 new_size_ = plan.size; |
| 331 SetupPriorityManagement(); |
304 } else if (type == DownloadAction::StaticType()) { | 332 } else if (type == DownloadAction::StaticType()) { |
305 SetStatusAndNotify(UPDATE_STATUS_FINALIZING); | 333 SetStatusAndNotify(UPDATE_STATUS_FINALIZING); |
306 } | 334 } |
307 } | 335 } |
308 | 336 |
309 // Stop updating. An attempt will be made to record status to the disk | 337 // Stop updating. An attempt will be made to record status to the disk |
310 // so that updates can be resumed later. | 338 // so that updates can be resumed later. |
311 void UpdateAttempter::Terminate() { | 339 void UpdateAttempter::Terminate() { |
312 // TODO(adlr): implement this method. | 340 // TODO(adlr): implement this method. |
313 NOTIMPLEMENTED(); | 341 NOTIMPLEMENTED(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 omaha_request_params_, | 425 omaha_request_params_, |
398 error_event_.release(), // Pass ownership. | 426 error_event_.release(), // Pass ownership. |
399 new LibcurlHttpFetcher)); | 427 new LibcurlHttpFetcher)); |
400 actions_.push_back(shared_ptr<AbstractAction>(error_event_action)); | 428 actions_.push_back(shared_ptr<AbstractAction>(error_event_action)); |
401 processor_.EnqueueAction(error_event_action.get()); | 429 processor_.EnqueueAction(error_event_action.get()); |
402 SetStatusAndNotify(UPDATE_STATUS_REPORTING_ERROR_EVENT); | 430 SetStatusAndNotify(UPDATE_STATUS_REPORTING_ERROR_EVENT); |
403 processor_.StartProcessing(); | 431 processor_.StartProcessing(); |
404 return true; | 432 return true; |
405 } | 433 } |
406 | 434 |
| 435 void UpdateAttempter::SetPriority(utils::ProcessPriority priority) { |
| 436 if (priority_ == priority) { |
| 437 return; |
| 438 } |
| 439 if (utils::SetProcessPriority(priority)) { |
| 440 priority_ = priority; |
| 441 LOG(INFO) << "Process priority = " << priority_; |
| 442 } |
| 443 } |
| 444 |
| 445 void UpdateAttempter::SetupPriorityManagement() { |
| 446 if (manage_priority_source_) { |
| 447 LOG(ERROR) << "Process priority timeout source hasn't been destroyed."; |
| 448 CleanupPriorityManagement(); |
| 449 } |
| 450 const int kPriorityTimeout = 10 * 60; // 10 minutes |
| 451 manage_priority_source_ = g_timeout_source_new_seconds(kPriorityTimeout); |
| 452 g_source_set_callback(manage_priority_source_, |
| 453 StaticManagePriorityCallback, |
| 454 this, |
| 455 NULL); |
| 456 g_source_attach(manage_priority_source_, NULL); |
| 457 SetPriority(utils::kProcessPriorityLow); |
| 458 } |
| 459 |
| 460 void UpdateAttempter::CleanupPriorityManagement() { |
| 461 if (manage_priority_source_) { |
| 462 g_source_destroy(manage_priority_source_); |
| 463 manage_priority_source_ = NULL; |
| 464 } |
| 465 SetPriority(utils::kProcessPriorityNormal); |
| 466 } |
| 467 |
| 468 gboolean UpdateAttempter::StaticManagePriorityCallback(gpointer data) { |
| 469 return reinterpret_cast<UpdateAttempter*>(data)->ManagePriorityCallback(); |
| 470 } |
| 471 |
| 472 bool UpdateAttempter::ManagePriorityCallback() { |
| 473 // If the current process priority is below normal, set it to normal |
| 474 // and let GLib invoke this callback again. |
| 475 if (utils::ComparePriorities(priority_, utils::kProcessPriorityNormal) < 0) { |
| 476 SetPriority(utils::kProcessPriorityNormal); |
| 477 return true; |
| 478 } |
| 479 // Set the priority to high and let GLib destroy the timeout source. |
| 480 SetPriority(utils::kProcessPriorityHigh); |
| 481 manage_priority_source_ = NULL; |
| 482 return false; |
| 483 } |
| 484 |
407 } // namespace chromeos_update_engine | 485 } // namespace chromeos_update_engine |
OLD | NEW |