update_attempter.cc revision 052d290ce38bd67629e3f0f5d4e4b7cfa8b7c201
1// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "update_engine/update_attempter.h" 6 7#include <string> 8#include <tr1/memory> 9#include <vector> 10 11#include <base/file_util.h> 12#include <base/rand_util.h> 13#include <glib.h> 14#include <metrics/metrics_library.h> 15#include <policy/libpolicy.h> 16#include <policy/device_policy.h> 17 18#include "update_engine/certificate_checker.h" 19#include "update_engine/constants.h" 20#include "update_engine/dbus_service.h" 21#include "update_engine/download_action.h" 22#include "update_engine/filesystem_copier_action.h" 23#include "update_engine/gpio_handler.h" 24#include "update_engine/hardware_interface.h" 25#include "update_engine/libcurl_http_fetcher.h" 26#include "update_engine/multi_range_http_fetcher.h" 27#include "update_engine/omaha_request_action.h" 28#include "update_engine/omaha_request_params.h" 29#include "update_engine/omaha_response_handler_action.h" 30#include "update_engine/p2p_manager.h" 31#include "update_engine/payload_state_interface.h" 32#include "update_engine/postinstall_runner_action.h" 33#include "update_engine/prefs_interface.h" 34#include "update_engine/subprocess.h" 35#include "update_engine/system_state.h" 36#include "update_engine/update_check_scheduler.h" 37 38using base::TimeDelta; 39using base::TimeTicks; 40using google::protobuf::NewPermanentCallback; 41using std::make_pair; 42using std::tr1::shared_ptr; 43using std::set; 44using std::string; 45using std::vector; 46 47namespace chromeos_update_engine { 48 49const int UpdateAttempter::kMaxDeltaUpdateFailures = 3; 50 51// Private test server URL w/ custom port number. 52// TODO(garnold) This is a temporary hack to allow us to test the closed loop 53// automated update testing. To be replaced with an hard-coded local IP address. 54const char* const UpdateAttempter::kTestUpdateUrl( 55 "http://garnold.mtv.corp.google.com:8080/update"); 56 57namespace { 58const int kMaxConsecutiveObeyProxyRequests = 20; 59 60const char* kUpdateCompletedMarker = 61 "/var/run/update_engine_autoupdate_completed"; 62} // namespace {} 63 64const char* UpdateStatusToString(UpdateStatus status) { 65 switch (status) { 66 case UPDATE_STATUS_IDLE: 67 return "UPDATE_STATUS_IDLE"; 68 case UPDATE_STATUS_CHECKING_FOR_UPDATE: 69 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; 70 case UPDATE_STATUS_UPDATE_AVAILABLE: 71 return "UPDATE_STATUS_UPDATE_AVAILABLE"; 72 case UPDATE_STATUS_DOWNLOADING: 73 return "UPDATE_STATUS_DOWNLOADING"; 74 case UPDATE_STATUS_VERIFYING: 75 return "UPDATE_STATUS_VERIFYING"; 76 case UPDATE_STATUS_FINALIZING: 77 return "UPDATE_STATUS_FINALIZING"; 78 case UPDATE_STATUS_UPDATED_NEED_REBOOT: 79 return "UPDATE_STATUS_UPDATED_NEED_REBOOT"; 80 case UPDATE_STATUS_REPORTING_ERROR_EVENT: 81 return "UPDATE_STATUS_REPORTING_ERROR_EVENT"; 82 case UPDATE_STATUS_ATTEMPTING_ROLLBACK: 83 return "UPDATE_STATUS_ATTEMPTING_ROLLBACK"; 84 default: 85 return "unknown status"; 86 } 87} 88 89// Turns a generic kErrorCodeError to a generic error code specific 90// to |action| (e.g., kErrorCodeFilesystemCopierError). If |code| is 91// not kErrorCodeError, or the action is not matched, returns |code| 92// unchanged. 93ErrorCode GetErrorCodeForAction(AbstractAction* action, 94 ErrorCode code) { 95 if (code != kErrorCodeError) 96 return code; 97 98 const string type = action->Type(); 99 if (type == OmahaRequestAction::StaticType()) 100 return kErrorCodeOmahaRequestError; 101 if (type == OmahaResponseHandlerAction::StaticType()) 102 return kErrorCodeOmahaResponseHandlerError; 103 if (type == FilesystemCopierAction::StaticType()) 104 return kErrorCodeFilesystemCopierError; 105 if (type == PostinstallRunnerAction::StaticType()) 106 return kErrorCodePostinstallRunnerError; 107 108 return code; 109} 110 111UpdateAttempter::UpdateAttempter(SystemState* system_state, 112 DbusGlibInterface* dbus_iface) 113 : chrome_proxy_resolver_(dbus_iface) { 114 Init(system_state, kUpdateCompletedMarker); 115} 116 117UpdateAttempter::UpdateAttempter(SystemState* system_state, 118 DbusGlibInterface* dbus_iface, 119 const std::string& update_completed_marker) 120 : chrome_proxy_resolver_(dbus_iface) { 121 Init(system_state, update_completed_marker); 122} 123 124 125void UpdateAttempter::Init(SystemState* system_state, 126 const std::string& update_completed_marker) { 127 // Initialite data members. 128 processor_.reset(new ActionProcessor()); 129 system_state_ = system_state; 130 dbus_service_ = NULL; 131 update_check_scheduler_ = NULL; 132 fake_update_success_ = false; 133 http_response_code_ = 0; 134 shares_ = utils::kCpuSharesNormal; 135 manage_shares_source_ = NULL; 136 download_active_ = false; 137 download_progress_ = 0.0; 138 last_checked_time_ = 0; 139 new_version_ = "0.0.0.0"; 140 new_payload_size_ = 0; 141 proxy_manual_checks_ = 0; 142 obeying_proxies_ = true; 143 updated_boot_flags_ = false; 144 update_boot_flags_running_ = false; 145 start_action_processor_ = false; 146 is_using_test_url_ = false; 147 is_test_mode_ = false; 148 is_test_update_attempted_ = false; 149 update_completed_marker_ = update_completed_marker; 150 151 prefs_ = system_state->prefs(); 152 omaha_request_params_ = system_state->request_params(); 153 154 if (!update_completed_marker_.empty() && 155 utils::FileExists(update_completed_marker_.c_str())) 156 status_ = UPDATE_STATUS_UPDATED_NEED_REBOOT; 157 else 158 status_ = UPDATE_STATUS_IDLE; 159} 160 161UpdateAttempter::~UpdateAttempter() { 162 CleanupCpuSharesManagement(); 163} 164 165void UpdateAttempter::Update(const string& app_version, 166 const string& omaha_url, 167 bool obey_proxies, 168 bool interactive, 169 bool is_test_mode) { 170 chrome_proxy_resolver_.Init(); 171 fake_update_success_ = false; 172 if (status_ == UPDATE_STATUS_UPDATED_NEED_REBOOT) { 173 // Although we have applied an update, we still want to ping Omaha 174 // to ensure the number of active statistics is accurate. 175 LOG(INFO) << "Not updating b/c we already updated and we're waiting for " 176 << "reboot, we'll ping Omaha instead"; 177 PingOmaha(); 178 return; 179 } 180 if (status_ != UPDATE_STATUS_IDLE) { 181 // Update in progress. Do nothing 182 return; 183 } 184 185 if (!CalculateUpdateParams(app_version, 186 omaha_url, 187 obey_proxies, 188 interactive, 189 is_test_mode)) { 190 return; 191 } 192 193 BuildUpdateActions(interactive); 194 195 SetStatusAndNotify(UPDATE_STATUS_CHECKING_FOR_UPDATE, 196 kUpdateNoticeUnspecified); 197 198 // Just in case we didn't update boot flags yet, make sure they're updated 199 // before any update processing starts. 200 start_action_processor_ = true; 201 UpdateBootFlags(); 202} 203 204void UpdateAttempter::RefreshDevicePolicy() { 205 // Lazy initialize the policy provider, or reload the latest policy data. 206 if (!policy_provider_.get()) 207 policy_provider_.reset(new policy::PolicyProvider()); 208 policy_provider_->Reload(); 209 210 const policy::DevicePolicy* device_policy = NULL; 211 if (policy_provider_->device_policy_is_loaded()) 212 device_policy = &policy_provider_->GetDevicePolicy(); 213 214 if (device_policy) 215 LOG(INFO) << "Device policies/settings present"; 216 else 217 LOG(INFO) << "No device policies/settings present."; 218 219 system_state_->set_device_policy(device_policy); 220} 221 222void UpdateAttempter::CalculateP2PParams(bool interactive) { 223 bool use_p2p_for_downloading = false; 224 bool use_p2p_for_sharing = false; 225 226 // Never use p2p for downloading in interactive checks unless the 227 // developer has opted in for it via a marker file. 228 // 229 // (Why would a developer want to opt in? If he's working on the 230 // update_engine or p2p codebases so he can actually test his 231 // code.). 232 233 if (system_state_ != NULL) { 234 if (!system_state_->p2p_manager()->IsP2PEnabled()) { 235 LOG(INFO) << "p2p is not enabled - disallowing p2p for both" 236 << " downloading and sharing."; 237 } else { 238 // Allow p2p for sharing, even in interactive checks. 239 use_p2p_for_sharing = true; 240 if (!interactive) { 241 LOG(INFO) << "Non-interactive check - allowing p2p for downloading"; 242 use_p2p_for_downloading = true; 243 } else { 244 LOG(INFO) << "Forcibly disabling use of p2p for downloading " 245 << "since this update attempt is interactive."; 246 } 247 } 248 } 249 250 omaha_request_params_->set_use_p2p_for_downloading(use_p2p_for_downloading); 251 omaha_request_params_->set_use_p2p_for_sharing(use_p2p_for_sharing); 252} 253 254bool UpdateAttempter::CalculateUpdateParams(const string& app_version, 255 const string& omaha_url, 256 bool obey_proxies, 257 bool interactive, 258 bool is_test_mode) { 259 http_response_code_ = 0; 260 261 // Set the test mode flag for the current update attempt. 262 is_test_mode_ = is_test_mode; 263 RefreshDevicePolicy(); 264 const policy::DevicePolicy* device_policy = system_state_->device_policy(); 265 if (device_policy) { 266 bool update_disabled = false; 267 if (device_policy->GetUpdateDisabled(&update_disabled)) 268 omaha_request_params_->set_update_disabled(update_disabled); 269 270 string target_version_prefix; 271 if (device_policy->GetTargetVersionPrefix(&target_version_prefix)) 272 omaha_request_params_->set_target_version_prefix(target_version_prefix); 273 274 set<string> allowed_types; 275 string allowed_types_str; 276 if (device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) { 277 set<string>::const_iterator iter; 278 for (iter = allowed_types.begin(); iter != allowed_types.end(); ++iter) 279 allowed_types_str += *iter + " "; 280 } 281 282 LOG(INFO) << "Networks over which updates are allowed per policy : " 283 << (allowed_types_str.empty() ? "all" : allowed_types_str); 284 } 285 286 CalculateScatteringParams(interactive); 287 288 CalculateP2PParams(interactive); 289 if (omaha_request_params_->use_p2p_for_downloading() || 290 omaha_request_params_->use_p2p_for_sharing()) { 291 // OK, p2p is to be used - start it and perform housekeeping. 292 if (!StartP2PAndPerformHousekeeping()) { 293 // If this fails, disable p2p for this attempt 294 LOG(INFO) << "Forcibly disabling use of p2p since starting p2p or " 295 << "performing housekeeping failed."; 296 omaha_request_params_->set_use_p2p_for_downloading(false); 297 omaha_request_params_->set_use_p2p_for_sharing(false); 298 } 299 } 300 301 // Determine whether an alternative test address should be used. 302 string omaha_url_to_use = omaha_url; 303 if ((is_using_test_url_ = (omaha_url_to_use.empty() && is_test_mode_))) { 304 omaha_url_to_use = kTestUpdateUrl; 305 LOG(INFO) << "using alternative server address: " << omaha_url_to_use; 306 } 307 308 if (!omaha_request_params_->Init(app_version, 309 omaha_url_to_use, 310 interactive)) { 311 LOG(ERROR) << "Unable to initialize Omaha request params."; 312 return false; 313 } 314 315 // Set the target channel iff ReleaseChannelDelegated policy is set to 316 // false and a non-empty ReleaseChannel policy is present. If delegated 317 // is true, we'll ignore ReleaseChannel policy value. 318 if (device_policy) { 319 bool delegated = false; 320 if (!device_policy->GetReleaseChannelDelegated(&delegated) || delegated) { 321 LOG(INFO) << "Channel settings are delegated to user by policy. " 322 "Ignoring ReleaseChannel policy value"; 323 } 324 else { 325 LOG(INFO) << "Channel settings are not delegated to the user by policy"; 326 string target_channel; 327 if (device_policy->GetReleaseChannel(&target_channel) && 328 !target_channel.empty()) { 329 // Pass in false for powerwash_allowed until we add it to the policy 330 // protobuf. 331 LOG(INFO) << "Setting target channel from ReleaseChannel policy value"; 332 omaha_request_params_->SetTargetChannel(target_channel, false); 333 334 // Since this is the beginning of a new attempt, update the download 335 // channel. The download channel won't be updated until the next 336 // attempt, even if target channel changes meanwhile, so that how we'll 337 // know if we should cancel the current download attempt if there's 338 // such a change in target channel. 339 omaha_request_params_->UpdateDownloadChannel(); 340 } else { 341 LOG(INFO) << "No ReleaseChannel specified in policy"; 342 } 343 } 344 } 345 346 LOG(INFO) << "update_disabled = " 347 << utils::ToString(omaha_request_params_->update_disabled()) 348 << ", target_version_prefix = " 349 << omaha_request_params_->target_version_prefix() 350 << ", scatter_factor_in_seconds = " 351 << utils::FormatSecs(scatter_factor_.InSeconds()); 352 353 LOG(INFO) << "Wall Clock Based Wait Enabled = " 354 << omaha_request_params_->wall_clock_based_wait_enabled() 355 << ", Update Check Count Wait Enabled = " 356 << omaha_request_params_->update_check_count_wait_enabled() 357 << ", Waiting Period = " << utils::FormatSecs( 358 omaha_request_params_->waiting_period().InSeconds()); 359 360 LOG(INFO) << "Use p2p For Downloading = " 361 << omaha_request_params_->use_p2p_for_downloading() 362 << ", Use p2p For Sharing = " 363 << omaha_request_params_->use_p2p_for_sharing(); 364 365 obeying_proxies_ = true; 366 if (obey_proxies || proxy_manual_checks_ == 0) { 367 LOG(INFO) << "forced to obey proxies"; 368 // If forced to obey proxies, every 20th request will not use proxies 369 proxy_manual_checks_++; 370 LOG(INFO) << "proxy manual checks: " << proxy_manual_checks_; 371 if (proxy_manual_checks_ >= kMaxConsecutiveObeyProxyRequests) { 372 proxy_manual_checks_ = 0; 373 obeying_proxies_ = false; 374 } 375 } else if (base::RandInt(0, 4) == 0) { 376 obeying_proxies_ = false; 377 } 378 LOG_IF(INFO, !obeying_proxies_) << "To help ensure updates work, this update " 379 "check we are ignoring the proxy settings and using " 380 "direct connections."; 381 382 DisableDeltaUpdateIfNeeded(); 383 return true; 384} 385 386void UpdateAttempter::CalculateScatteringParams(bool interactive) { 387 // Take a copy of the old scatter value before we update it, as 388 // we need to update the waiting period if this value changes. 389 TimeDelta old_scatter_factor = scatter_factor_; 390 const policy::DevicePolicy* device_policy = system_state_->device_policy(); 391 if (device_policy) { 392 int64 new_scatter_factor_in_secs = 0; 393 device_policy->GetScatterFactorInSeconds(&new_scatter_factor_in_secs); 394 if (new_scatter_factor_in_secs < 0) // sanitize input, just in case. 395 new_scatter_factor_in_secs = 0; 396 scatter_factor_ = TimeDelta::FromSeconds(new_scatter_factor_in_secs); 397 } 398 399 bool is_scatter_enabled = false; 400 if (scatter_factor_.InSeconds() == 0) { 401 LOG(INFO) << "Scattering disabled since scatter factor is set to 0"; 402 } else if (interactive) { 403 LOG(INFO) << "Scattering disabled as this is an interactive update check"; 404 } else if (!system_state_->IsOOBEComplete()) { 405 LOG(INFO) << "Scattering disabled since OOBE is not complete yet"; 406 } else { 407 is_scatter_enabled = true; 408 LOG(INFO) << "Scattering is enabled"; 409 } 410 411 if (is_scatter_enabled) { 412 // This means the scattering policy is turned on. 413 // Now check if we need to update the waiting period. The two cases 414 // in which we'd need to update the waiting period are: 415 // 1. First time in process or a scheduled check after a user-initiated one. 416 // (omaha_request_params_->waiting_period will be zero in this case). 417 // 2. Admin has changed the scattering policy value. 418 // (new scattering value will be different from old one in this case). 419 int64 wait_period_in_secs = 0; 420 if (omaha_request_params_->waiting_period().InSeconds() == 0) { 421 // First case. Check if we have a suitable value to set for 422 // the waiting period. 423 if (prefs_->GetInt64(kPrefsWallClockWaitPeriod, &wait_period_in_secs) && 424 wait_period_in_secs > 0 && 425 wait_period_in_secs <= scatter_factor_.InSeconds()) { 426 // This means: 427 // 1. There's a persisted value for the waiting period available. 428 // 2. And that persisted value is still valid. 429 // So, in this case, we should reuse the persisted value instead of 430 // generating a new random value to improve the chances of a good 431 // distribution for scattering. 432 omaha_request_params_->set_waiting_period( 433 TimeDelta::FromSeconds(wait_period_in_secs)); 434 LOG(INFO) << "Using persisted wall-clock waiting period: " << 435 utils::FormatSecs( 436 omaha_request_params_->waiting_period().InSeconds()); 437 } 438 else { 439 // This means there's no persisted value for the waiting period 440 // available or its value is invalid given the new scatter_factor value. 441 // So, we should go ahead and regenerate a new value for the 442 // waiting period. 443 LOG(INFO) << "Persisted value not present or not valid (" 444 << utils::FormatSecs(wait_period_in_secs) 445 << ") for wall-clock waiting period."; 446 GenerateNewWaitingPeriod(); 447 } 448 } else if (scatter_factor_ != old_scatter_factor) { 449 // This means there's already a waiting period value, but we detected 450 // a change in the scattering policy value. So, we should regenerate the 451 // waiting period to make sure it's within the bounds of the new scatter 452 // factor value. 453 GenerateNewWaitingPeriod(); 454 } else { 455 // Neither the first time scattering is enabled nor the scattering value 456 // changed. Nothing to do. 457 LOG(INFO) << "Keeping current wall-clock waiting period: " << 458 utils::FormatSecs( 459 omaha_request_params_->waiting_period().InSeconds()); 460 } 461 462 // The invariant at this point is that omaha_request_params_->waiting_period 463 // is non-zero no matter which path we took above. 464 LOG_IF(ERROR, omaha_request_params_->waiting_period().InSeconds() == 0) 465 << "Waiting Period should NOT be zero at this point!!!"; 466 467 // Since scattering is enabled, wall clock based wait will always be 468 // enabled. 469 omaha_request_params_->set_wall_clock_based_wait_enabled(true); 470 471 // If we don't have any issues in accessing the file system to update 472 // the update check count value, we'll turn that on as well. 473 bool decrement_succeeded = DecrementUpdateCheckCount(); 474 omaha_request_params_->set_update_check_count_wait_enabled( 475 decrement_succeeded); 476 } else { 477 // This means the scattering feature is turned off or disabled for 478 // this particular update check. Make sure to disable 479 // all the knobs and artifacts so that we don't invoke any scattering 480 // related code. 481 omaha_request_params_->set_wall_clock_based_wait_enabled(false); 482 omaha_request_params_->set_update_check_count_wait_enabled(false); 483 omaha_request_params_->set_waiting_period(TimeDelta::FromSeconds(0)); 484 prefs_->Delete(kPrefsWallClockWaitPeriod); 485 prefs_->Delete(kPrefsUpdateCheckCount); 486 // Don't delete the UpdateFirstSeenAt file as we don't want manual checks 487 // that result in no-updates (e.g. due to server side throttling) to 488 // cause update starvation by having the client generate a new 489 // UpdateFirstSeenAt for each scheduled check that follows a manual check. 490 } 491} 492 493void UpdateAttempter::GenerateNewWaitingPeriod() { 494 omaha_request_params_->set_waiting_period(TimeDelta::FromSeconds( 495 base::RandInt(1, scatter_factor_.InSeconds()))); 496 497 LOG(INFO) << "Generated new wall-clock waiting period: " << utils::FormatSecs( 498 omaha_request_params_->waiting_period().InSeconds()); 499 500 // Do a best-effort to persist this in all cases. Even if the persistence 501 // fails, we'll still be able to scatter based on our in-memory value. 502 // The persistence only helps in ensuring a good overall distribution 503 // across multiple devices if they tend to reboot too often. 504 prefs_->SetInt64(kPrefsWallClockWaitPeriod, 505 omaha_request_params_->waiting_period().InSeconds()); 506} 507 508void UpdateAttempter::BuildPostInstallActions( 509 InstallPlanAction* previous_action) { 510 shared_ptr<PostinstallRunnerAction> postinstall_runner_action( 511 new PostinstallRunnerAction()); 512 actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action)); 513 BondActions(previous_action, 514 postinstall_runner_action.get()); 515} 516 517void UpdateAttempter::BuildUpdateActions(bool interactive) { 518 CHECK(!processor_->IsRunning()); 519 processor_->set_delegate(this); 520 521 // Actions: 522 LibcurlHttpFetcher* update_check_fetcher = 523 new LibcurlHttpFetcher(GetProxyResolver(), system_state_, is_test_mode_); 524 // Try harder to connect to the network, esp when not interactive. 525 // See comment in libcurl_http_fetcher.cc. 526 update_check_fetcher->set_no_network_max_retries(interactive ? 1 : 3); 527 update_check_fetcher->set_check_certificate(CertificateChecker::kUpdate); 528 shared_ptr<OmahaRequestAction> update_check_action( 529 new OmahaRequestAction(system_state_, 530 NULL, 531 update_check_fetcher, // passes ownership 532 false)); 533 shared_ptr<OmahaResponseHandlerAction> response_handler_action( 534 new OmahaResponseHandlerAction(system_state_)); 535 shared_ptr<FilesystemCopierAction> filesystem_copier_action( 536 new FilesystemCopierAction(system_state_, false, false)); 537 shared_ptr<FilesystemCopierAction> kernel_filesystem_copier_action( 538 new FilesystemCopierAction(system_state_, true, false)); 539 shared_ptr<OmahaRequestAction> download_started_action( 540 new OmahaRequestAction(system_state_, 541 new OmahaEvent( 542 OmahaEvent::kTypeUpdateDownloadStarted), 543 new LibcurlHttpFetcher(GetProxyResolver(), 544 system_state_, 545 is_test_mode_), 546 false)); 547 LibcurlHttpFetcher* download_fetcher = 548 new LibcurlHttpFetcher(GetProxyResolver(), system_state_, is_test_mode_); 549 download_fetcher->set_check_certificate(CertificateChecker::kDownload); 550 shared_ptr<DownloadAction> download_action( 551 new DownloadAction(prefs_, 552 system_state_, 553 new MultiRangeHttpFetcher( 554 download_fetcher))); // passes ownership 555 shared_ptr<OmahaRequestAction> download_finished_action( 556 new OmahaRequestAction(system_state_, 557 new OmahaEvent( 558 OmahaEvent::kTypeUpdateDownloadFinished), 559 new LibcurlHttpFetcher(GetProxyResolver(), 560 system_state_, 561 is_test_mode_), 562 false)); 563 shared_ptr<FilesystemCopierAction> filesystem_verifier_action( 564 new FilesystemCopierAction(system_state_, false, true)); 565 shared_ptr<FilesystemCopierAction> kernel_filesystem_verifier_action( 566 new FilesystemCopierAction(system_state_, true, true)); 567 shared_ptr<OmahaRequestAction> update_complete_action( 568 new OmahaRequestAction(system_state_, 569 new OmahaEvent(OmahaEvent::kTypeUpdateComplete), 570 new LibcurlHttpFetcher(GetProxyResolver(), 571 system_state_, 572 is_test_mode_), 573 false)); 574 575 download_action->set_delegate(this); 576 response_handler_action_ = response_handler_action; 577 download_action_ = download_action; 578 579 actions_.push_back(shared_ptr<AbstractAction>(update_check_action)); 580 actions_.push_back(shared_ptr<AbstractAction>(response_handler_action)); 581 actions_.push_back(shared_ptr<AbstractAction>(filesystem_copier_action)); 582 actions_.push_back(shared_ptr<AbstractAction>( 583 kernel_filesystem_copier_action)); 584 actions_.push_back(shared_ptr<AbstractAction>(download_started_action)); 585 actions_.push_back(shared_ptr<AbstractAction>(download_action)); 586 actions_.push_back(shared_ptr<AbstractAction>(download_finished_action)); 587 actions_.push_back(shared_ptr<AbstractAction>(filesystem_verifier_action)); 588 actions_.push_back(shared_ptr<AbstractAction>( 589 kernel_filesystem_verifier_action)); 590 591 // Bond them together. We have to use the leaf-types when calling 592 // BondActions(). 593 BondActions(update_check_action.get(), 594 response_handler_action.get()); 595 BondActions(response_handler_action.get(), 596 filesystem_copier_action.get()); 597 BondActions(filesystem_copier_action.get(), 598 kernel_filesystem_copier_action.get()); 599 BondActions(kernel_filesystem_copier_action.get(), 600 download_action.get()); 601 BondActions(download_action.get(), 602 filesystem_verifier_action.get()); 603 BondActions(filesystem_verifier_action.get(), 604 kernel_filesystem_verifier_action.get()); 605 606 BuildPostInstallActions(kernel_filesystem_verifier_action.get()); 607 608 actions_.push_back(shared_ptr<AbstractAction>(update_complete_action)); 609 610 // Enqueue the actions 611 for (vector<shared_ptr<AbstractAction> >::iterator it = actions_.begin(); 612 it != actions_.end(); ++it) { 613 processor_->EnqueueAction(it->get()); 614 } 615} 616 617bool UpdateAttempter::Rollback(bool powerwash, string *install_path) { 618 CHECK(!processor_->IsRunning()); 619 processor_->set_delegate(this); 620 621 // TODO(sosa): crbug.com/252539 -- refactor channel into system_state and 622 // check for != stable-channel here. 623 RefreshDevicePolicy(); 624 625 // Initialize the default request params. 626 if (!omaha_request_params_->Init("", "", true)) { 627 LOG(ERROR) << "Unable to initialize Omaha request params."; 628 return false; 629 } 630 631 if (omaha_request_params_->current_channel() == "stable-channel") { 632 LOG(ERROR) << "Rollback is not supported while on the stable-channel."; 633 return false; 634 } 635 636 LOG(INFO) << "Setting rollback options."; 637 InstallPlan install_plan; 638 if (install_path == NULL) { 639 TEST_AND_RETURN_FALSE(utils::GetInstallDev( 640 system_state_->hardware()->BootDevice(), 641 &install_plan.install_path)); 642 } 643 else { 644 install_plan.install_path = *install_path; 645 } 646 647 install_plan.kernel_install_path = 648 system_state_->hardware()->KernelDeviceOfBootDevice( 649 install_plan.install_path); 650 install_plan.powerwash_required = powerwash; 651 if (powerwash) { 652 // Enterprise-enrolled devices have an empty owner in their device policy. 653 string owner; 654 const policy::DevicePolicy* device_policy = system_state_->device_policy(); 655 if (!device_policy->GetOwner(&owner) || owner.empty()) { 656 LOG(ERROR) << "Enterprise device detected. " 657 << "Cannot perform a powerwash for enterprise devices."; 658 return false; 659 } 660 } 661 662 LOG(INFO) << "Using this install plan:"; 663 install_plan.Dump(); 664 665 shared_ptr<InstallPlanAction> install_plan_action( 666 new InstallPlanAction(install_plan)); 667 actions_.push_back(shared_ptr<AbstractAction>(install_plan_action)); 668 669 BuildPostInstallActions(install_plan_action.get()); 670 671 // Enqueue the actions 672 for (vector<shared_ptr<AbstractAction> >::iterator it = actions_.begin(); 673 it != actions_.end(); ++it) { 674 processor_->EnqueueAction(it->get()); 675 } 676 677 // Update the payload state for Rollback. 678 system_state_->payload_state()->Rollback(); 679 680 SetStatusAndNotify(UPDATE_STATUS_ATTEMPTING_ROLLBACK, 681 kUpdateNoticeUnspecified); 682 683 // Just in case we didn't update boot flags yet, make sure they're updated 684 // before any update processing starts. This also schedules the start of the 685 // actions we just posted. 686 start_action_processor_ = true; 687 UpdateBootFlags(); 688 return true; 689} 690 691void UpdateAttempter::CheckForUpdate(const string& app_version, 692 const string& omaha_url, 693 bool interactive) { 694 LOG(INFO) << "New update check requested"; 695 696 if (status_ != UPDATE_STATUS_IDLE) { 697 LOG(INFO) << "Skipping update check because current status is " 698 << UpdateStatusToString(status_); 699 return; 700 } 701 702 // Read GPIO signals and determine whether this is an automated test scenario. 703 // For safety, we only allow a test update to be performed once; subsequent 704 // update requests will be carried out normally. 705 bool is_test_mode = (!is_test_update_attempted_ && 706 system_state_->gpio_handler()->IsTestModeSignaled()); 707 if (is_test_mode) { 708 LOG(WARNING) << "this is a test mode update attempt!"; 709 is_test_update_attempted_ = true; 710 } 711 712 // Pass through the interactive flag, in case we want to simulate a scheduled 713 // test. 714 Update(app_version, omaha_url, true, interactive, is_test_mode); 715} 716 717bool UpdateAttempter::RebootIfNeeded() { 718 if (status_ != UPDATE_STATUS_UPDATED_NEED_REBOOT) { 719 LOG(INFO) << "Reboot requested, but status is " 720 << UpdateStatusToString(status_) << ", so not rebooting."; 721 return false; 722 } 723 TEST_AND_RETURN_FALSE(utils::Reboot()); 724 return true; 725} 726 727// Delegate methods: 728void UpdateAttempter::ProcessingDone(const ActionProcessor* processor, 729 ErrorCode code) { 730 LOG(INFO) << "Processing Done."; 731 actions_.clear(); 732 733 // Reset cpu shares back to normal. 734 CleanupCpuSharesManagement(); 735 736 if (status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { 737 LOG(INFO) << "Error event sent."; 738 739 // Inform scheduler of new status; also specifically inform about a failed 740 // update attempt with a test address. 741 SetStatusAndNotify(UPDATE_STATUS_IDLE, 742 (is_using_test_url_ ? kUpdateNoticeTestAddrFailed : 743 kUpdateNoticeUnspecified)); 744 745 if (!fake_update_success_) { 746 return; 747 } 748 LOG(INFO) << "Booted from FW B and tried to install new firmware, " 749 "so requesting reboot from user."; 750 } 751 752 if (code == kErrorCodeSuccess) { 753 if (!update_completed_marker_.empty()) 754 utils::WriteFile(update_completed_marker_.c_str(), "", 0); 755 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); 756 prefs_->SetString(kPrefsPreviousVersion, 757 omaha_request_params_->app_version()); 758 DeltaPerformer::ResetUpdateProgress(prefs_, false); 759 760 system_state_->payload_state()->UpdateSucceeded(); 761 762 // Since we're done with scattering fully at this point, this is the 763 // safest point delete the state files, as we're sure that the status is 764 // set to reboot (which means no more updates will be applied until reboot) 765 // This deletion is required for correctness as we want the next update 766 // check to re-create a new random number for the update check count. 767 // Similarly, we also delete the wall-clock-wait period that was persisted 768 // so that we start with a new random value for the next update check 769 // after reboot so that the same device is not favored or punished in any 770 // way. 771 prefs_->Delete(kPrefsUpdateCheckCount); 772 prefs_->Delete(kPrefsWallClockWaitPeriod); 773 prefs_->Delete(kPrefsUpdateFirstSeenAt); 774 775 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT, 776 kUpdateNoticeUnspecified); 777 LOG(INFO) << "Update successfully applied, waiting to reboot."; 778 779 const InstallPlan& install_plan = response_handler_action_->install_plan(); 780 781 // Generate an unique payload identifier. 782 const string target_version_uid = 783 install_plan.payload_hash + ":" + install_plan.metadata_signature; 784 785 // Expect to reboot into the new version to send the proper metric during 786 // next boot. 787 system_state_->payload_state()->ExpectRebootInNewVersion( 788 target_version_uid); 789 790 // Also report the success code so that the percentiles can be 791 // interpreted properly for the remaining error codes in UMA. 792 utils::SendErrorCodeToUma(system_state_, code); 793 return; 794 } 795 796 if (ScheduleErrorEventAction()) { 797 return; 798 } 799 LOG(INFO) << "No update."; 800 SetStatusAndNotify(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified); 801} 802 803void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) { 804 // Reset cpu shares back to normal. 805 CleanupCpuSharesManagement(); 806 download_progress_ = 0.0; 807 SetStatusAndNotify(UPDATE_STATUS_IDLE, kUpdateNoticeUnspecified); 808 actions_.clear(); 809 error_event_.reset(NULL); 810} 811 812// Called whenever an action has finished processing, either successfully 813// or otherwise. 814void UpdateAttempter::ActionCompleted(ActionProcessor* processor, 815 AbstractAction* action, 816 ErrorCode code) { 817 // Reset download progress regardless of whether or not the download 818 // action succeeded. Also, get the response code from HTTP request 819 // actions (update download as well as the initial update check 820 // actions). 821 const string type = action->Type(); 822 if (type == DownloadAction::StaticType()) { 823 download_progress_ = 0.0; 824 DownloadAction* download_action = dynamic_cast<DownloadAction*>(action); 825 http_response_code_ = download_action->GetHTTPResponseCode(); 826 } else if (type == OmahaRequestAction::StaticType()) { 827 OmahaRequestAction* omaha_request_action = 828 dynamic_cast<OmahaRequestAction*>(action); 829 // If the request is not an event, then it's the update-check. 830 if (!omaha_request_action->IsEvent()) { 831 http_response_code_ = omaha_request_action->GetHTTPResponseCode(); 832 // Forward the server-dictated poll interval to the update check 833 // scheduler, if any. 834 if (update_check_scheduler_) { 835 update_check_scheduler_->set_poll_interval( 836 omaha_request_action->GetOutputObject().poll_interval); 837 } 838 } 839 } 840 if (code != kErrorCodeSuccess) { 841 // If the current state is at or past the download phase, count the failure 842 // in case a switch to full update becomes necessary. Ignore network 843 // transfer timeouts and failures. 844 if (status_ >= UPDATE_STATUS_DOWNLOADING && 845 code != kErrorCodeDownloadTransferError) { 846 MarkDeltaUpdateFailure(); 847 } 848 // On failure, schedule an error event to be sent to Omaha. 849 CreatePendingErrorEvent(action, code); 850 return; 851 } 852 // Find out which action completed. 853 if (type == OmahaResponseHandlerAction::StaticType()) { 854 // Note that the status will be updated to DOWNLOADING when some bytes get 855 // actually downloaded from the server and the BytesReceived callback is 856 // invoked. This avoids notifying the user that a download has started in 857 // cases when the server and the client are unable to initiate the download. 858 CHECK(action == response_handler_action_.get()); 859 const InstallPlan& plan = response_handler_action_->install_plan(); 860 last_checked_time_ = time(NULL); 861 new_version_ = plan.version; 862 new_payload_size_ = plan.payload_size; 863 SetupDownload(); 864 SetupCpuSharesManagement(); 865 SetStatusAndNotify(UPDATE_STATUS_UPDATE_AVAILABLE, 866 kUpdateNoticeUnspecified); 867 } else if (type == DownloadAction::StaticType()) { 868 SetStatusAndNotify(UPDATE_STATUS_FINALIZING, kUpdateNoticeUnspecified); 869 } 870} 871 872// Stop updating. An attempt will be made to record status to the disk 873// so that updates can be resumed later. 874void UpdateAttempter::Terminate() { 875 // TODO(adlr): implement this method. 876 NOTIMPLEMENTED(); 877} 878 879// Try to resume from a previously Terminate()d update. 880void UpdateAttempter::ResumeUpdating() { 881 // TODO(adlr): implement this method. 882 NOTIMPLEMENTED(); 883} 884 885void UpdateAttempter::SetDownloadStatus(bool active) { 886 download_active_ = active; 887 LOG(INFO) << "Download status: " << (active ? "active" : "inactive"); 888} 889 890void UpdateAttempter::BytesReceived(uint64_t bytes_received, uint64_t total) { 891 if (!download_active_) { 892 LOG(ERROR) << "BytesReceived called while not downloading."; 893 return; 894 } 895 double progress = static_cast<double>(bytes_received) / 896 static_cast<double>(total); 897 // Self throttle based on progress. Also send notifications if 898 // progress is too slow. 899 const double kDeltaPercent = 0.01; // 1% 900 if (status_ != UPDATE_STATUS_DOWNLOADING || 901 bytes_received == total || 902 progress - download_progress_ >= kDeltaPercent || 903 TimeTicks::Now() - last_notify_time_ >= TimeDelta::FromSeconds(10)) { 904 download_progress_ = progress; 905 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING, kUpdateNoticeUnspecified); 906 } 907} 908 909bool UpdateAttempter::ResetStatus() { 910 LOG(INFO) << "Attempting to reset state from " 911 << UpdateStatusToString(status_) << " to UPDATE_STATUS_IDLE"; 912 913 switch (status_) { 914 case UPDATE_STATUS_IDLE: 915 // no-op. 916 return true; 917 918 case UPDATE_STATUS_UPDATED_NEED_REBOOT: { 919 bool ret_value = true; 920 status_ = UPDATE_STATUS_IDLE; 921 LOG(INFO) << "Reset Successful"; 922 923 // Remove the reboot marker so that if the machine is rebooted 924 // after resetting to idle state, it doesn't go back to 925 // UPDATE_STATUS_UPDATED_NEED_REBOOT state. 926 if (!update_completed_marker_.empty()) { 927 const FilePath update_completed_marker_path(update_completed_marker_); 928 if (!file_util::Delete(update_completed_marker_path, false)) 929 ret_value = false; 930 } 931 932 // Notify the PayloadState that the successful payload was canceled. 933 system_state_->payload_state()->ResetUpdateStatus(); 934 935 return ret_value; 936 } 937 938 default: 939 LOG(ERROR) << "Reset not allowed in this state."; 940 return false; 941 } 942} 943 944bool UpdateAttempter::GetStatus(int64_t* last_checked_time, 945 double* progress, 946 string* current_operation, 947 string* new_version, 948 int64_t* new_payload_size) { 949 *last_checked_time = last_checked_time_; 950 *progress = download_progress_; 951 *current_operation = UpdateStatusToString(status_); 952 *new_version = new_version_; 953 *new_payload_size = new_payload_size_; 954 return true; 955} 956 957void UpdateAttempter::UpdateBootFlags() { 958 if (update_boot_flags_running_) { 959 LOG(INFO) << "Update boot flags running, nothing to do."; 960 return; 961 } 962 if (updated_boot_flags_) { 963 LOG(INFO) << "Already updated boot flags. Skipping."; 964 if (start_action_processor_) { 965 ScheduleProcessingStart(); 966 } 967 return; 968 } 969 // This is purely best effort. Failures should be logged by Subprocess. Run 970 // the script asynchronously to avoid blocking the event loop regardless of 971 // the script runtime. 972 update_boot_flags_running_ = true; 973 LOG(INFO) << "Updating boot flags..."; 974 vector<string> cmd(1, "/usr/sbin/chromeos-setgoodkernel"); 975 if (!Subprocess::Get().Exec(cmd, StaticCompleteUpdateBootFlags, this)) { 976 CompleteUpdateBootFlags(1); 977 } 978} 979 980void UpdateAttempter::CompleteUpdateBootFlags(int return_code) { 981 update_boot_flags_running_ = false; 982 updated_boot_flags_ = true; 983 if (start_action_processor_) { 984 ScheduleProcessingStart(); 985 } 986} 987 988void UpdateAttempter::StaticCompleteUpdateBootFlags( 989 int return_code, 990 const string& output, 991 void* p) { 992 reinterpret_cast<UpdateAttempter*>(p)->CompleteUpdateBootFlags(return_code); 993} 994 995void UpdateAttempter::BroadcastStatus() { 996 if (!dbus_service_) { 997 return; 998 } 999 last_notify_time_ = TimeTicks::Now(); 1000 update_engine_service_emit_status_update( 1001 dbus_service_, 1002 last_checked_time_, 1003 download_progress_, 1004 UpdateStatusToString(status_), 1005 new_version_.c_str(), 1006 new_payload_size_); 1007} 1008 1009uint32_t UpdateAttempter::GetErrorCodeFlags() { 1010 uint32_t flags = 0; 1011 1012 if (!utils::IsNormalBootMode()) 1013 flags |= kErrorCodeDevModeFlag; 1014 1015 if (response_handler_action_.get() && 1016 response_handler_action_->install_plan().is_resume) 1017 flags |= kErrorCodeResumedFlag; 1018 1019 if (!utils::IsOfficialBuild()) 1020 flags |= kErrorCodeTestImageFlag; 1021 1022 if (omaha_request_params_->update_url() != kProductionOmahaUrl) 1023 flags |= kErrorCodeTestOmahaUrlFlag; 1024 1025 return flags; 1026} 1027 1028bool UpdateAttempter::ShouldCancel(ErrorCode* cancel_reason) { 1029 // Check if the channel we're attempting to update to is the same as the 1030 // target channel currently chosen by the user. 1031 OmahaRequestParams* params = system_state_->request_params(); 1032 if (params->download_channel() != params->target_channel()) { 1033 LOG(ERROR) << "Aborting download as target channel: " 1034 << params->target_channel() 1035 << " is different from the download channel: " 1036 << params->download_channel(); 1037 *cancel_reason = kErrorCodeUpdateCanceledByChannelChange; 1038 return true; 1039 } 1040 1041 return false; 1042} 1043 1044void UpdateAttempter::SetStatusAndNotify(UpdateStatus status, 1045 UpdateNotice notice) { 1046 status_ = status; 1047 if (update_check_scheduler_) { 1048 update_check_scheduler_->SetUpdateStatus(status_, notice); 1049 } 1050 BroadcastStatus(); 1051} 1052 1053void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action, 1054 ErrorCode code) { 1055 if (error_event_.get()) { 1056 // This shouldn't really happen. 1057 LOG(WARNING) << "There's already an existing pending error event."; 1058 return; 1059 } 1060 1061 // For now assume that a generic Omaha response action failure means that 1062 // there's no update so don't send an event. Also, double check that the 1063 // failure has not occurred while sending an error event -- in which case 1064 // don't schedule another. This shouldn't really happen but just in case... 1065 if ((action->Type() == OmahaResponseHandlerAction::StaticType() && 1066 code == kErrorCodeError) || 1067 status_ == UPDATE_STATUS_REPORTING_ERROR_EVENT) { 1068 return; 1069 } 1070 1071 // Classify the code to generate the appropriate result so that 1072 // the Borgmon charts show up the results correctly. 1073 // Do this before calling GetErrorCodeForAction which could potentially 1074 // augment the bit representation of code and thus cause no matches for 1075 // the switch cases below. 1076 OmahaEvent::Result event_result; 1077 switch (code) { 1078 case kErrorCodeOmahaUpdateIgnoredPerPolicy: 1079 case kErrorCodeOmahaUpdateDeferredPerPolicy: 1080 case kErrorCodeOmahaUpdateDeferredForBackoff: 1081 event_result = OmahaEvent::kResultUpdateDeferred; 1082 break; 1083 default: 1084 event_result = OmahaEvent::kResultError; 1085 break; 1086 } 1087 1088 code = GetErrorCodeForAction(action, code); 1089 fake_update_success_ = code == kErrorCodePostinstallBootedFromFirmwareB; 1090 1091 // Compute the final error code with all the bit flags to be sent to Omaha. 1092 code = static_cast<ErrorCode>(code | GetErrorCodeFlags()); 1093 error_event_.reset(new OmahaEvent(OmahaEvent::kTypeUpdateComplete, 1094 event_result, 1095 code)); 1096} 1097 1098bool UpdateAttempter::ScheduleErrorEventAction() { 1099 if (error_event_.get() == NULL) 1100 return false; 1101 1102 LOG(ERROR) << "Update failed."; 1103 system_state_->payload_state()->UpdateFailed(error_event_->error_code); 1104 1105 // Send it to Uma. 1106 LOG(INFO) << "Reporting the error event"; 1107 utils::SendErrorCodeToUma(system_state_, error_event_->error_code); 1108 1109 // Send it to Omaha. 1110 shared_ptr<OmahaRequestAction> error_event_action( 1111 new OmahaRequestAction(system_state_, 1112 error_event_.release(), // Pass ownership. 1113 new LibcurlHttpFetcher(GetProxyResolver(), 1114 system_state_, 1115 is_test_mode_), 1116 false)); 1117 actions_.push_back(shared_ptr<AbstractAction>(error_event_action)); 1118 processor_->EnqueueAction(error_event_action.get()); 1119 SetStatusAndNotify(UPDATE_STATUS_REPORTING_ERROR_EVENT, 1120 kUpdateNoticeUnspecified); 1121 processor_->StartProcessing(); 1122 return true; 1123} 1124 1125void UpdateAttempter::SetCpuShares(utils::CpuShares shares) { 1126 if (shares_ == shares) { 1127 return; 1128 } 1129 if (utils::SetCpuShares(shares)) { 1130 shares_ = shares; 1131 LOG(INFO) << "CPU shares = " << shares_; 1132 } 1133} 1134 1135void UpdateAttempter::SetupCpuSharesManagement() { 1136 if (manage_shares_source_) { 1137 LOG(ERROR) << "Cpu shares timeout source hasn't been destroyed."; 1138 CleanupCpuSharesManagement(); 1139 } 1140 const int kCpuSharesTimeout = 2 * 60 * 60; // 2 hours 1141 manage_shares_source_ = g_timeout_source_new_seconds(kCpuSharesTimeout); 1142 g_source_set_callback(manage_shares_source_, 1143 StaticManageCpuSharesCallback, 1144 this, 1145 NULL); 1146 g_source_attach(manage_shares_source_, NULL); 1147 SetCpuShares(utils::kCpuSharesLow); 1148} 1149 1150void UpdateAttempter::CleanupCpuSharesManagement() { 1151 if (manage_shares_source_) { 1152 g_source_destroy(manage_shares_source_); 1153 manage_shares_source_ = NULL; 1154 } 1155 SetCpuShares(utils::kCpuSharesNormal); 1156} 1157 1158gboolean UpdateAttempter::StaticManageCpuSharesCallback(gpointer data) { 1159 return reinterpret_cast<UpdateAttempter*>(data)->ManageCpuSharesCallback(); 1160} 1161 1162gboolean UpdateAttempter::StaticStartProcessing(gpointer data) { 1163 reinterpret_cast<UpdateAttempter*>(data)->processor_->StartProcessing(); 1164 return FALSE; // Don't call this callback again. 1165} 1166 1167void UpdateAttempter::ScheduleProcessingStart() { 1168 LOG(INFO) << "Scheduling an action processor start."; 1169 start_action_processor_ = false; 1170 g_idle_add(&StaticStartProcessing, this); 1171} 1172 1173bool UpdateAttempter::ManageCpuSharesCallback() { 1174 SetCpuShares(utils::kCpuSharesNormal); 1175 manage_shares_source_ = NULL; 1176 return false; // Destroy the timeout source. 1177} 1178 1179void UpdateAttempter::DisableDeltaUpdateIfNeeded() { 1180 int64_t delta_failures; 1181 if (omaha_request_params_->delta_okay() && 1182 prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) && 1183 delta_failures >= kMaxDeltaUpdateFailures) { 1184 LOG(WARNING) << "Too many delta update failures, forcing full update."; 1185 omaha_request_params_->set_delta_okay(false); 1186 } 1187} 1188 1189void UpdateAttempter::MarkDeltaUpdateFailure() { 1190 // Don't try to resume a failed delta update. 1191 DeltaPerformer::ResetUpdateProgress(prefs_, false); 1192 int64_t delta_failures; 1193 if (!prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) || 1194 delta_failures < 0) { 1195 delta_failures = 0; 1196 } 1197 prefs_->SetInt64(kPrefsDeltaUpdateFailures, ++delta_failures); 1198} 1199 1200void UpdateAttempter::SetupDownload() { 1201 MultiRangeHttpFetcher* fetcher = 1202 dynamic_cast<MultiRangeHttpFetcher*>(download_action_->http_fetcher()); 1203 fetcher->ClearRanges(); 1204 if (response_handler_action_->install_plan().is_resume) { 1205 // Resuming an update so fetch the update manifest metadata first. 1206 int64_t manifest_metadata_size = 0; 1207 prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size); 1208 fetcher->AddRange(0, manifest_metadata_size); 1209 // If there're remaining unprocessed data blobs, fetch them. Be careful not 1210 // to request data beyond the end of the payload to avoid 416 HTTP response 1211 // error codes. 1212 int64_t next_data_offset = 0; 1213 prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset); 1214 uint64_t resume_offset = manifest_metadata_size + next_data_offset; 1215 if (resume_offset < response_handler_action_->install_plan().payload_size) { 1216 fetcher->AddRange(resume_offset); 1217 } 1218 } else { 1219 fetcher->AddRange(0); 1220 } 1221} 1222 1223void UpdateAttempter::PingOmaha() { 1224 if (!processor_->IsRunning()) { 1225 shared_ptr<OmahaRequestAction> ping_action( 1226 new OmahaRequestAction(system_state_, 1227 NULL, 1228 new LibcurlHttpFetcher(GetProxyResolver(), 1229 system_state_, 1230 is_test_mode_), 1231 true)); 1232 actions_.push_back(shared_ptr<OmahaRequestAction>(ping_action)); 1233 processor_->set_delegate(NULL); 1234 processor_->EnqueueAction(ping_action.get()); 1235 // Call StartProcessing() synchronously here to avoid any race conditions 1236 // caused by multiple outstanding ping Omaha requests. If we call 1237 // StartProcessing() asynchronously, the device can be suspended before we 1238 // get a chance to callback to StartProcessing(). When the device resumes 1239 // (assuming the device sleeps longer than the next update check period), 1240 // StartProcessing() is called back and at the same time, the next update 1241 // check is fired which eventually invokes StartProcessing(). A crash 1242 // can occur because StartProcessing() checks to make sure that the 1243 // processor is idle which it isn't due to the two concurrent ping Omaha 1244 // requests. 1245 processor_->StartProcessing(); 1246 } else { 1247 LOG(WARNING) << "Action processor running, Omaha ping suppressed."; 1248 } 1249 1250 // Update the status which will schedule the next update check 1251 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT, 1252 kUpdateNoticeUnspecified); 1253} 1254 1255 1256bool UpdateAttempter::DecrementUpdateCheckCount() { 1257 int64 update_check_count_value; 1258 1259 if (!prefs_->Exists(kPrefsUpdateCheckCount)) { 1260 // This file does not exist. This means we haven't started our update 1261 // check count down yet, so nothing more to do. This file will be created 1262 // later when we first satisfy the wall-clock-based-wait period. 1263 LOG(INFO) << "No existing update check count. That's normal."; 1264 return true; 1265 } 1266 1267 if (prefs_->GetInt64(kPrefsUpdateCheckCount, &update_check_count_value)) { 1268 // Only if we're able to read a proper integer value, then go ahead 1269 // and decrement and write back the result in the same file, if needed. 1270 LOG(INFO) << "Update check count = " << update_check_count_value; 1271 1272 if (update_check_count_value == 0) { 1273 // It could be 0, if, for some reason, the file didn't get deleted 1274 // when we set our status to waiting for reboot. so we just leave it 1275 // as is so that we can prevent another update_check wait for this client. 1276 LOG(INFO) << "Not decrementing update check count as it's already 0."; 1277 return true; 1278 } 1279 1280 if (update_check_count_value > 0) 1281 update_check_count_value--; 1282 else 1283 update_check_count_value = 0; 1284 1285 // Write out the new value of update_check_count_value. 1286 if (prefs_->SetInt64(kPrefsUpdateCheckCount, update_check_count_value)) { 1287 // We successfully wrote out te new value, so enable the 1288 // update check based wait. 1289 LOG(INFO) << "New update check count = " << update_check_count_value; 1290 return true; 1291 } 1292 } 1293 1294 LOG(INFO) << "Deleting update check count state due to read/write errors."; 1295 1296 // We cannot read/write to the file, so disable the update check based wait 1297 // so that we don't get stuck in this OS version by any chance (which could 1298 // happen if there's some bug that causes to read/write incorrectly). 1299 // Also attempt to delete the file to do our best effort to cleanup. 1300 prefs_->Delete(kPrefsUpdateCheckCount); 1301 return false; 1302} 1303 1304 1305void UpdateAttempter::UpdateEngineStarted() { 1306 system_state_->payload_state()->UpdateEngineStarted(); 1307 StartP2PAtStartup(); 1308} 1309 1310bool UpdateAttempter::StartP2PAtStartup() { 1311 if (system_state_ == NULL || 1312 !system_state_->p2p_manager()->IsP2PEnabled()) { 1313 LOG(INFO) << "Not starting p2p at startup since it's not enabled."; 1314 return false; 1315 } 1316 1317 if (system_state_->p2p_manager()->CountSharedFiles() < 1) { 1318 LOG(INFO) << "Not starting p2p at startup since our application " 1319 << "is not sharing any files."; 1320 return false; 1321 } 1322 1323 return StartP2PAndPerformHousekeeping(); 1324} 1325 1326bool UpdateAttempter::StartP2PAndPerformHousekeeping() { 1327 if (system_state_ == NULL) 1328 return false; 1329 1330 if (!system_state_->p2p_manager()->IsP2PEnabled()) { 1331 LOG(INFO) << "Not starting p2p since it's not enabled."; 1332 return false; 1333 } 1334 1335 LOG(INFO) << "Ensuring that p2p is running."; 1336 if (!system_state_->p2p_manager()->EnsureP2PRunning()) { 1337 LOG(ERROR) << "Error starting p2p."; 1338 return false; 1339 } 1340 1341 LOG(INFO) << "Performing p2p housekeeping."; 1342 if (!system_state_->p2p_manager()->PerformHousekeeping()) { 1343 LOG(ERROR) << "Error performing housekeeping for p2p."; 1344 return false; 1345 } 1346 1347 LOG(INFO) << "Done performing p2p housekeeping."; 1348 return true; 1349} 1350 1351} // namespace chromeos_update_engine 1352