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