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