update_attempter_android.cc revision 5990bf33b50beec0caf55a97f5ca87608ccbc694
1// 2// Copyright (C) 2016 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "update_engine/update_attempter_android.h" 18 19#include <algorithm> 20#include <map> 21#include <utility> 22 23#include <base/bind.h> 24#include <base/logging.h> 25#include <base/strings/string_number_conversions.h> 26#include <brillo/bind_lambda.h> 27#include <brillo/message_loops/message_loop.h> 28#include <brillo/strings/string_utils.h> 29 30#include "update_engine/common/constants.h" 31#include "update_engine/common/file_fetcher.h" 32#include "update_engine/common/libcurl_http_fetcher.h" 33#include "update_engine/common/multi_range_http_fetcher.h" 34#include "update_engine/common/utils.h" 35#include "update_engine/daemon_state_android.h" 36#include "update_engine/payload_consumer/download_action.h" 37#include "update_engine/payload_consumer/filesystem_verifier_action.h" 38#include "update_engine/payload_consumer/postinstall_runner_action.h" 39#include "update_engine/update_status_utils.h" 40 41using base::Bind; 42using base::TimeDelta; 43using base::TimeTicks; 44using std::shared_ptr; 45using std::string; 46using std::vector; 47 48namespace chromeos_update_engine { 49 50namespace { 51 52// Minimum threshold to broadcast an status update in progress and time. 53const double kBroadcastThresholdProgress = 0.01; // 1% 54const int kBroadcastThresholdSeconds = 10; 55 56const char* const kErrorDomain = "update_engine"; 57// TODO(deymo): Convert the different errors to a numeric value to report them 58// back on the service error. 59const char* const kGenericError = "generic_error"; 60 61// Log and set the error on the passed ErrorPtr. 62bool LogAndSetError(brillo::ErrorPtr* error, 63 const tracked_objects::Location& location, 64 const string& reason) { 65 brillo::Error::AddTo(error, location, kErrorDomain, kGenericError, reason); 66 LOG(ERROR) << "Replying with failure: " << location.ToString() << ": " 67 << reason; 68 return false; 69} 70 71} // namespace 72 73UpdateAttempterAndroid::UpdateAttempterAndroid( 74 DaemonStateAndroid* daemon_state, 75 PrefsInterface* prefs, 76 BootControlInterface* boot_control, 77 HardwareInterface* hardware) 78 : daemon_state_(daemon_state), 79 prefs_(prefs), 80 boot_control_(boot_control), 81 hardware_(hardware), 82 processor_(new ActionProcessor()) { 83} 84 85UpdateAttempterAndroid::~UpdateAttempterAndroid() { 86 // Release ourselves as the ActionProcessor's delegate to prevent 87 // re-scheduling the updates due to the processing stopped. 88 processor_->set_delegate(nullptr); 89} 90 91void UpdateAttempterAndroid::Init() { 92 // In case of update_engine restart without a reboot we need to restore the 93 // reboot needed state. 94 if (UpdateCompletedOnThisBoot()) 95 SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT); 96 else 97 SetStatusAndNotify(UpdateStatus::IDLE); 98} 99 100bool UpdateAttempterAndroid::ApplyPayload( 101 const string& payload_url, 102 int64_t payload_offset, 103 int64_t payload_size, 104 const vector<string>& key_value_pair_headers, 105 brillo::ErrorPtr* error) { 106 if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) { 107 return LogAndSetError( 108 error, FROM_HERE, "An update already applied, waiting for reboot"); 109 } 110 if (ongoing_update_) { 111 return LogAndSetError( 112 error, FROM_HERE, "Already processing an update, cancel it first."); 113 } 114 DCHECK(status_ == UpdateStatus::IDLE); 115 116 std::map<string, string> headers; 117 for (const string& key_value_pair : key_value_pair_headers) { 118 string key; 119 string value; 120 if (!brillo::string_utils::SplitAtFirst( 121 key_value_pair, "=", &key, &value, false)) { 122 return LogAndSetError( 123 error, FROM_HERE, "Passed invalid header: " + key_value_pair); 124 } 125 if (!headers.emplace(key, value).second) 126 return LogAndSetError(error, FROM_HERE, "Passed repeated key: " + key); 127 } 128 129 // Unique identifier for the payload. An empty string means that the payload 130 // can't be resumed. 131 string payload_id = (headers[kPayloadPropertyFileHash] + 132 headers[kPayloadPropertyMetadataHash]); 133 134 // Setup the InstallPlan based on the request. 135 install_plan_ = InstallPlan(); 136 137 install_plan_.download_url = payload_url; 138 install_plan_.version = ""; 139 base_offset_ = payload_offset; 140 install_plan_.payload_size = payload_size; 141 if (!install_plan_.payload_size) { 142 if (!base::StringToUint64(headers[kPayloadPropertyFileSize], 143 &install_plan_.payload_size)) { 144 install_plan_.payload_size = 0; 145 } 146 } 147 install_plan_.payload_hash = headers[kPayloadPropertyFileHash]; 148 if (!base::StringToUint64(headers[kPayloadPropertyMetadataSize], 149 &install_plan_.metadata_size)) { 150 install_plan_.metadata_size = 0; 151 } 152 install_plan_.metadata_signature = ""; 153 // The |public_key_rsa| key would override the public key stored on disk. 154 install_plan_.public_key_rsa = ""; 155 156 install_plan_.hash_checks_mandatory = hardware_->IsOfficialBuild(); 157 install_plan_.is_resume = !payload_id.empty() && 158 DeltaPerformer::CanResumeUpdate(prefs_, payload_id); 159 if (!install_plan_.is_resume) { 160 if (!DeltaPerformer::ResetUpdateProgress(prefs_, false)) { 161 LOG(WARNING) << "Unable to reset the update progress."; 162 } 163 if (!prefs_->SetString(kPrefsUpdateCheckResponseHash, payload_id)) { 164 LOG(WARNING) << "Unable to save the update check response hash."; 165 } 166 } 167 // The |payload_type| is not used anymore since minor_version 3. 168 install_plan_.payload_type = InstallPayloadType::kUnknown; 169 170 install_plan_.source_slot = boot_control_->GetCurrentSlot(); 171 install_plan_.target_slot = install_plan_.source_slot == 0 ? 1 : 0; 172 173 int data_wipe = 0; 174 install_plan_.powerwash_required = 175 base::StringToInt(headers[kPayloadPropertyPowerwash], &data_wipe) && 176 data_wipe != 0; 177 178 LOG(INFO) << "Using this install plan:"; 179 install_plan_.Dump(); 180 181 BuildUpdateActions(payload_url); 182 SetupDownload(); 183 // Setup extra headers. 184 HttpFetcher* fetcher = download_action_->http_fetcher(); 185 if (!headers[kPayloadPropertyAuthorization].empty()) 186 fetcher->SetHeader("Authorization", headers[kPayloadPropertyAuthorization]); 187 if (!headers[kPayloadPropertyUserAgent].empty()) 188 fetcher->SetHeader("User-Agent", headers[kPayloadPropertyUserAgent]); 189 190 cpu_limiter_.StartLimiter(); 191 SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE); 192 ongoing_update_ = true; 193 194 // Just in case we didn't update boot flags yet, make sure they're updated 195 // before any update processing starts. This will start the update process. 196 UpdateBootFlags(); 197 return true; 198} 199 200bool UpdateAttempterAndroid::SuspendUpdate(brillo::ErrorPtr* error) { 201 if (!ongoing_update_) 202 return LogAndSetError(error, FROM_HERE, "No ongoing update to suspend."); 203 processor_->SuspendProcessing(); 204 return true; 205} 206 207bool UpdateAttempterAndroid::ResumeUpdate(brillo::ErrorPtr* error) { 208 if (!ongoing_update_) 209 return LogAndSetError(error, FROM_HERE, "No ongoing update to resume."); 210 processor_->ResumeProcessing(); 211 return true; 212} 213 214bool UpdateAttempterAndroid::CancelUpdate(brillo::ErrorPtr* error) { 215 if (!ongoing_update_) 216 return LogAndSetError(error, FROM_HERE, "No ongoing update to cancel."); 217 processor_->StopProcessing(); 218 return true; 219} 220 221bool UpdateAttempterAndroid::ResetStatus(brillo::ErrorPtr* error) { 222 LOG(INFO) << "Attempting to reset state from " 223 << UpdateStatusToString(status_) << " to UpdateStatus::IDLE"; 224 225 switch (status_) { 226 case UpdateStatus::IDLE: 227 return true; 228 229 case UpdateStatus::UPDATED_NEED_REBOOT: { 230 // Remove the reboot marker so that if the machine is rebooted 231 // after resetting to idle state, it doesn't go back to 232 // UpdateStatus::UPDATED_NEED_REBOOT state. 233 bool ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId); 234 235 // Update the boot flags so the current slot has higher priority. 236 if (!boot_control_->SetActiveBootSlot(boot_control_->GetCurrentSlot())) 237 ret_value = false; 238 239 if (!ret_value) { 240 return LogAndSetError( 241 error, 242 FROM_HERE, 243 "Failed to reset the status to "); 244 } 245 246 SetStatusAndNotify(UpdateStatus::IDLE); 247 LOG(INFO) << "Reset status successful"; 248 return true; 249 } 250 251 default: 252 return LogAndSetError( 253 error, 254 FROM_HERE, 255 "Reset not allowed in this state. Cancel the ongoing update first"); 256 } 257} 258 259void UpdateAttempterAndroid::ProcessingDone(const ActionProcessor* processor, 260 ErrorCode code) { 261 LOG(INFO) << "Processing Done."; 262 263 switch (code) { 264 case ErrorCode::kSuccess: 265 // Update succeeded. 266 WriteUpdateCompletedMarker(); 267 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0); 268 DeltaPerformer::ResetUpdateProgress(prefs_, false); 269 270 LOG(INFO) << "Update successfully applied, waiting to reboot."; 271 break; 272 273 case ErrorCode::kFilesystemCopierError: 274 case ErrorCode::kNewRootfsVerificationError: 275 case ErrorCode::kNewKernelVerificationError: 276 case ErrorCode::kFilesystemVerifierError: 277 case ErrorCode::kDownloadStateInitializationError: 278 // Reset the ongoing update for these errors so it starts from the 279 // beginning next time. 280 DeltaPerformer::ResetUpdateProgress(prefs_, false); 281 LOG(INFO) << "Resetting update progress."; 282 break; 283 284 default: 285 // Ignore all other error codes. 286 break; 287 } 288 289 TerminateUpdateAndNotify(code); 290} 291 292void UpdateAttempterAndroid::ProcessingStopped( 293 const ActionProcessor* processor) { 294 TerminateUpdateAndNotify(ErrorCode::kUserCanceled); 295} 296 297void UpdateAttempterAndroid::ActionCompleted(ActionProcessor* processor, 298 AbstractAction* action, 299 ErrorCode code) { 300 // Reset download progress regardless of whether or not the download 301 // action succeeded. 302 const string type = action->Type(); 303 if (type == DownloadAction::StaticType()) { 304 download_progress_ = 0; 305 } 306 if (code != ErrorCode::kSuccess) { 307 // If an action failed, the ActionProcessor will cancel the whole thing. 308 return; 309 } 310 if (type == DownloadAction::StaticType()) { 311 SetStatusAndNotify(UpdateStatus::FINALIZING); 312 } 313} 314 315void UpdateAttempterAndroid::BytesReceived(uint64_t bytes_progressed, 316 uint64_t bytes_received, 317 uint64_t total) { 318 double progress = 0; 319 if (total) 320 progress = static_cast<double>(bytes_received) / static_cast<double>(total); 321 if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) { 322 download_progress_ = progress; 323 SetStatusAndNotify(UpdateStatus::DOWNLOADING); 324 } else { 325 ProgressUpdate(progress); 326 } 327} 328 329bool UpdateAttempterAndroid::ShouldCancel(ErrorCode* cancel_reason) { 330 // TODO(deymo): Notify the DownloadAction that it should cancel the update 331 // download. 332 return false; 333} 334 335void UpdateAttempterAndroid::DownloadComplete() { 336 // Nothing needs to be done when the download completes. 337} 338 339void UpdateAttempterAndroid::ProgressUpdate(double progress) { 340 // Self throttle based on progress. Also send notifications if progress is 341 // too slow. 342 if (progress == 1.0 || 343 progress - download_progress_ >= kBroadcastThresholdProgress || 344 TimeTicks::Now() - last_notify_time_ >= 345 TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) { 346 download_progress_ = progress; 347 SetStatusAndNotify(status_); 348 } 349} 350 351void UpdateAttempterAndroid::UpdateBootFlags() { 352 if (updated_boot_flags_) { 353 LOG(INFO) << "Already updated boot flags. Skipping."; 354 CompleteUpdateBootFlags(true); 355 return; 356 } 357 // This is purely best effort. 358 LOG(INFO) << "Marking booted slot as good."; 359 if (!boot_control_->MarkBootSuccessfulAsync( 360 Bind(&UpdateAttempterAndroid::CompleteUpdateBootFlags, 361 base::Unretained(this)))) { 362 LOG(ERROR) << "Failed to mark current boot as successful."; 363 CompleteUpdateBootFlags(false); 364 } 365} 366 367void UpdateAttempterAndroid::CompleteUpdateBootFlags(bool successful) { 368 updated_boot_flags_ = true; 369 ScheduleProcessingStart(); 370} 371 372void UpdateAttempterAndroid::ScheduleProcessingStart() { 373 LOG(INFO) << "Scheduling an action processor start."; 374 brillo::MessageLoop::current()->PostTask( 375 FROM_HERE, Bind([this] { this->processor_->StartProcessing(); })); 376} 377 378void UpdateAttempterAndroid::TerminateUpdateAndNotify(ErrorCode error_code) { 379 if (status_ == UpdateStatus::IDLE) { 380 LOG(ERROR) << "No ongoing update, but TerminatedUpdate() called."; 381 return; 382 } 383 384 // Reset cpu shares back to normal. 385 cpu_limiter_.StopLimiter(); 386 download_progress_ = 0; 387 actions_.clear(); 388 UpdateStatus new_status = 389 (error_code == ErrorCode::kSuccess ? UpdateStatus::UPDATED_NEED_REBOOT 390 : UpdateStatus::IDLE); 391 SetStatusAndNotify(new_status); 392 ongoing_update_ = false; 393 394 for (auto observer : daemon_state_->service_observers()) 395 observer->SendPayloadApplicationComplete(error_code); 396} 397 398void UpdateAttempterAndroid::SetStatusAndNotify(UpdateStatus status) { 399 status_ = status; 400 for (auto observer : daemon_state_->service_observers()) { 401 observer->SendStatusUpdate( 402 0, download_progress_, status_, "", install_plan_.payload_size); 403 } 404 last_notify_time_ = TimeTicks::Now(); 405} 406 407void UpdateAttempterAndroid::BuildUpdateActions(const string& url) { 408 CHECK(!processor_->IsRunning()); 409 processor_->set_delegate(this); 410 411 // Actions: 412 shared_ptr<InstallPlanAction> install_plan_action( 413 new InstallPlanAction(install_plan_)); 414 415 HttpFetcher* download_fetcher = nullptr; 416 if (FileFetcher::SupportedUrl(url)) { 417 DLOG(INFO) << "Using FileFetcher for file URL."; 418 download_fetcher = new FileFetcher(); 419 } else { 420 LibcurlHttpFetcher* libcurl_fetcher = 421 new LibcurlHttpFetcher(&proxy_resolver_, hardware_); 422 libcurl_fetcher->set_server_to_check(ServerToCheck::kDownload); 423 download_fetcher = libcurl_fetcher; 424 } 425 shared_ptr<DownloadAction> download_action(new DownloadAction( 426 prefs_, 427 boot_control_, 428 hardware_, 429 nullptr, // system_state, not used. 430 new MultiRangeHttpFetcher(download_fetcher))); // passes ownership 431 shared_ptr<FilesystemVerifierAction> filesystem_verifier_action( 432 new FilesystemVerifierAction()); 433 434 shared_ptr<PostinstallRunnerAction> postinstall_runner_action( 435 new PostinstallRunnerAction(boot_control_, hardware_)); 436 437 download_action->set_delegate(this); 438 download_action_ = download_action; 439 postinstall_runner_action->set_delegate(this); 440 441 actions_.push_back(shared_ptr<AbstractAction>(install_plan_action)); 442 actions_.push_back(shared_ptr<AbstractAction>(download_action)); 443 actions_.push_back(shared_ptr<AbstractAction>(filesystem_verifier_action)); 444 actions_.push_back(shared_ptr<AbstractAction>(postinstall_runner_action)); 445 446 // Bond them together. We have to use the leaf-types when calling 447 // BondActions(). 448 BondActions(install_plan_action.get(), download_action.get()); 449 BondActions(download_action.get(), filesystem_verifier_action.get()); 450 BondActions(filesystem_verifier_action.get(), 451 postinstall_runner_action.get()); 452 453 // Enqueue the actions. 454 for (const shared_ptr<AbstractAction>& action : actions_) 455 processor_->EnqueueAction(action.get()); 456} 457 458void UpdateAttempterAndroid::SetupDownload() { 459 MultiRangeHttpFetcher* fetcher = 460 static_cast<MultiRangeHttpFetcher*>(download_action_->http_fetcher()); 461 fetcher->ClearRanges(); 462 if (install_plan_.is_resume) { 463 // Resuming an update so fetch the update manifest metadata first. 464 int64_t manifest_metadata_size = 0; 465 int64_t manifest_signature_size = 0; 466 prefs_->GetInt64(kPrefsManifestMetadataSize, &manifest_metadata_size); 467 prefs_->GetInt64(kPrefsManifestSignatureSize, &manifest_signature_size); 468 fetcher->AddRange(base_offset_, 469 manifest_metadata_size + manifest_signature_size); 470 // If there're remaining unprocessed data blobs, fetch them. Be careful not 471 // to request data beyond the end of the payload to avoid 416 HTTP response 472 // error codes. 473 int64_t next_data_offset = 0; 474 prefs_->GetInt64(kPrefsUpdateStateNextDataOffset, &next_data_offset); 475 uint64_t resume_offset = 476 manifest_metadata_size + manifest_signature_size + next_data_offset; 477 if (!install_plan_.payload_size) { 478 fetcher->AddRange(base_offset_ + resume_offset); 479 } else if (resume_offset < install_plan_.payload_size) { 480 fetcher->AddRange(base_offset_ + resume_offset, 481 install_plan_.payload_size - resume_offset); 482 } 483 } else { 484 if (install_plan_.payload_size) { 485 fetcher->AddRange(base_offset_, install_plan_.payload_size); 486 } else { 487 // If no payload size is passed we assume we read until the end of the 488 // stream. 489 fetcher->AddRange(base_offset_); 490 } 491 } 492} 493 494bool UpdateAttempterAndroid::WriteUpdateCompletedMarker() { 495 string boot_id; 496 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 497 prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id); 498 return true; 499} 500 501bool UpdateAttempterAndroid::UpdateCompletedOnThisBoot() { 502 // In case of an update_engine restart without a reboot, we stored the boot_id 503 // when the update was completed by setting a pref, so we can check whether 504 // the last update was on this boot or a previous one. 505 string boot_id; 506 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id)); 507 508 string update_completed_on_boot_id; 509 return (prefs_->Exists(kPrefsUpdateCompletedOnBootId) && 510 prefs_->GetString(kPrefsUpdateCompletedOnBootId, 511 &update_completed_on_boot_id) && 512 update_completed_on_boot_id == boot_id); 513} 514 515} // namespace chromeos_update_engine 516