1 // 2 // Copyright (C) 2012 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 #ifndef UPDATE_ENGINE_PAYLOAD_STATE_H_ 18 #define UPDATE_ENGINE_PAYLOAD_STATE_H_ 19 20 #include <algorithm> 21 #include <string> 22 #include <vector> 23 24 #include <base/time/time.h> 25 #include <gtest/gtest_prod.h> // for FRIEND_TEST 26 27 #include "update_engine/common/excluder_interface.h" 28 #include "update_engine/common/prefs_interface.h" 29 #include "update_engine/metrics_constants.h" 30 #include "update_engine/payload_state_interface.h" 31 32 namespace chromeos_update_engine { 33 34 class SystemState; 35 36 // Encapsulates all the payload state required for download. This includes the 37 // state necessary for handling multiple URLs in Omaha response, the backoff 38 // state, etc. All state is persisted so that we use the most recently saved 39 // value when resuming the update_engine process. All state is also cached in 40 // memory so that we ensure we always make progress based on last known good 41 // state even when there's any issue in reading/writing from the file system. 42 class PayloadState : public PayloadStateInterface { 43 public: 44 PayloadState(); ~PayloadState()45 ~PayloadState() override {} 46 47 // Initializes a payload state object using the given global system state. 48 // It performs the initial loading of all persisted state into memory and 49 // dumps the initial state for debugging purposes. Note: the other methods 50 // should be called only after calling Initialize on this object. 51 bool Initialize(SystemState* system_state); 52 53 // Implementation of PayloadStateInterface methods. 54 void SetResponse(const OmahaResponse& response) override; 55 void DownloadComplete() override; 56 void DownloadProgress(size_t count) override; 57 void UpdateResumed() override; 58 void UpdateRestarted() override; 59 void UpdateSucceeded() override; 60 void UpdateFailed(ErrorCode error) override; 61 void ResetUpdateStatus() override; 62 bool ShouldBackoffDownload() override; 63 void Rollback() override; 64 void ExpectRebootInNewVersion(const std::string& target_version_uid) override; 65 void SetUsingP2PForDownloading(bool value) override; 66 SetUsingP2PForSharing(bool value)67 void SetUsingP2PForSharing(bool value) override { 68 using_p2p_for_sharing_ = value; 69 } 70 GetResponseSignature()71 inline std::string GetResponseSignature() override { 72 return response_signature_; 73 } 74 GetFullPayloadAttemptNumber()75 inline int GetFullPayloadAttemptNumber() override { 76 return full_payload_attempt_number_; 77 } 78 GetPayloadAttemptNumber()79 inline int GetPayloadAttemptNumber() override { 80 return payload_attempt_number_; 81 } 82 GetCurrentUrl()83 inline std::string GetCurrentUrl() override { 84 return (payload_index_ < candidate_urls_.size() && 85 url_index_ < candidate_urls_[payload_index_].size()) 86 ? candidate_urls_[payload_index_][url_index_] 87 : ""; 88 } 89 GetUrlFailureCount()90 inline uint32_t GetUrlFailureCount() override { return url_failure_count_; } 91 GetUrlSwitchCount()92 inline uint32_t GetUrlSwitchCount() override { return url_switch_count_; } 93 GetNumResponsesSeen()94 inline int GetNumResponsesSeen() override { return num_responses_seen_; } 95 GetBackoffExpiryTime()96 inline base::Time GetBackoffExpiryTime() override { 97 return backoff_expiry_time_; 98 } 99 100 base::TimeDelta GetUpdateDuration() override; 101 102 base::TimeDelta GetUpdateDurationUptime() override; 103 GetCurrentBytesDownloaded(DownloadSource source)104 inline uint64_t GetCurrentBytesDownloaded(DownloadSource source) override { 105 return source < kNumDownloadSources ? current_bytes_downloaded_[source] : 0; 106 } 107 GetTotalBytesDownloaded(DownloadSource source)108 inline uint64_t GetTotalBytesDownloaded(DownloadSource source) override { 109 return source < kNumDownloadSources ? total_bytes_downloaded_[source] : 0; 110 } 111 GetNumReboots()112 inline uint32_t GetNumReboots() override { return num_reboots_; } 113 114 void UpdateEngineStarted() override; 115 GetRollbackHappened()116 inline bool GetRollbackHappened() override { return rollback_happened_; } 117 118 void SetRollbackHappened(bool rollback_happened) override; 119 GetRollbackVersion()120 inline std::string GetRollbackVersion() override { return rollback_version_; } 121 122 int GetP2PNumAttempts() override; 123 base::Time GetP2PFirstAttemptTimestamp() override; 124 void P2PNewAttempt() override; 125 bool P2PAttemptAllowed() override; 126 GetUsingP2PForDownloading()127 bool GetUsingP2PForDownloading() const override { 128 return using_p2p_for_downloading_; 129 } 130 GetUsingP2PForSharing()131 bool GetUsingP2PForSharing() const override { return using_p2p_for_sharing_; } 132 GetScatteringWaitPeriod()133 base::TimeDelta GetScatteringWaitPeriod() override { 134 return scattering_wait_period_; 135 } 136 137 void SetScatteringWaitPeriod(base::TimeDelta wait_period) override; 138 139 void SetStagingWaitPeriod(base::TimeDelta wait_period) override; 140 SetP2PUrl(const std::string & url)141 void SetP2PUrl(const std::string& url) override { p2p_url_ = url; } 142 GetP2PUrl()143 std::string GetP2PUrl() const override { return p2p_url_; } 144 145 bool NextPayload() override; 146 147 private: 148 enum class AttemptType { 149 kUpdate, 150 kRollback, 151 }; 152 153 friend class PayloadStateTest; 154 FRIEND_TEST(PayloadStateTest, RebootAfterUpdateFailedMetric); 155 FRIEND_TEST(PayloadStateTest, RebootAfterUpdateSucceed); 156 FRIEND_TEST(PayloadStateTest, RebootAfterCanceledUpdate); 157 FRIEND_TEST(PayloadStateTest, RollbackHappened); 158 FRIEND_TEST(PayloadStateTest, RollbackVersion); 159 FRIEND_TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs); 160 FRIEND_TEST(PayloadStateTest, NextPayloadResetsUrlIndex); 161 FRIEND_TEST(PayloadStateTest, ExcludeNoopForNonExcludables); 162 FRIEND_TEST(PayloadStateTest, ExcludeOnlyCanExcludables); 163 FRIEND_TEST(PayloadStateTest, IncrementFailureExclusionTest); 164 165 // Helper called when an attempt has begun, is called by 166 // UpdateResumed(), UpdateRestarted() and Rollback(). 167 void AttemptStarted(AttemptType attempt_type); 168 169 // Increments the payload attempt number used for metrics. 170 void IncrementPayloadAttemptNumber(); 171 172 // Increments the payload attempt number which governs the backoff behavior 173 // at the time of the next update check. 174 void IncrementFullPayloadAttemptNumber(); 175 176 // Advances the current URL index to the next available one. If all URLs have 177 // been exhausted during the current payload download attempt (as indicated 178 // by the payload attempt number), then it will increment the payload attempt 179 // number and wrap around again with the first URL in the list. This also 180 // updates the URL switch count, if needed. 181 void IncrementUrlIndex(); 182 183 // Increments the failure count of the current URL. If the configured max 184 // failure count is reached for this URL, it advances the current URL index 185 // to the next URL and resets the failure count for that URL. 186 void IncrementFailureCount(); 187 188 // Excludes the current payload + current candidate URL from being part of 189 // future updates/retries. Whenever |SetResponse()| or |NextPayload()| decide 190 // on the initial current URL index and the next payload respectively, it will 191 // advanced based on exclusions. 192 void ExcludeCurrentPayload(); 193 194 // Updates the backoff expiry time exponentially based on the current 195 // payload attempt number. 196 void UpdateBackoffExpiryTime(); 197 198 // Updates the value of current download source based on the current URL 199 // index. If the download source is not one of the known sources, it's set 200 // to kNumDownloadSources. 201 void UpdateCurrentDownloadSource(); 202 203 // Updates the various metrics corresponding with the given number of bytes 204 // that were downloaded recently. 205 void UpdateBytesDownloaded(size_t count); 206 207 // Calculates the PayloadType we're using. 208 PayloadType CalculatePayloadType(); 209 210 // Collects and reports the various metrics related to an update attempt. 211 void CollectAndReportAttemptMetrics(ErrorCode code); 212 213 // Persists values related to the UpdateEngine.Attempt.* metrics so 214 // we can identify later if an update attempt ends abnormally. 215 void PersistAttemptMetrics(); 216 217 // Clears persistent state previously set using AttemptMetricsPersist(). 218 void ClearPersistedAttemptMetrics(); 219 220 // Checks if persistent state previously set using AttemptMetricsPersist() 221 // exists and, if so, emits it with |attempt_result| set to 222 // metrics::AttemptResult::kAbnormalTermination. 223 void ReportAndClearPersistedAttemptMetrics(); 224 225 // Collects and reports the various metrics related to a successful update. 226 void CollectAndReportSuccessfulUpdateMetrics(); 227 228 // Checks if we were expecting to be running in the new version but the 229 // boot into the new version failed for some reason. If that's the case, an 230 // UMA metric is sent reporting the number of attempts the same applied 231 // payload was attempted to reboot. This function is called by UpdateAttempter 232 // every time the update engine starts and there's no reboot pending. 233 void ReportFailedBootIfNeeded(); 234 235 // Resets all the persisted state values which are maintained relative to the 236 // current response signature. The response signature itself is not reset. 237 void ResetPersistedState(); 238 239 // Resets the appropriate state related to download sources that need to be 240 // reset on a new update. 241 void ResetDownloadSourcesOnNewUpdate(); 242 243 // Calculates the response "signature", which is basically a string composed 244 // of the subset of the fields in the current response that affect the 245 // behavior of the PayloadState. 246 std::string CalculateResponseSignature(); 247 248 // Initializes the current response signature from the persisted state. 249 void LoadResponseSignature(); 250 251 // Sets the response signature to the given value. Also persists the value 252 // being set so that we resume from the save value in case of a process 253 // restart. 254 void SetResponseSignature(const std::string& response_signature); 255 256 // Initializes the payload attempt number from the persisted state. 257 void LoadPayloadAttemptNumber(); 258 259 // Initializes the payload attempt number for full payloads from the persisted 260 // state. 261 void LoadFullPayloadAttemptNumber(); 262 263 // Sets the payload attempt number to the given value. Also persists the 264 // value being set so that we resume from the same value in case of a process 265 // restart. 266 void SetPayloadAttemptNumber(int payload_attempt_number); 267 268 // Sets the payload attempt number for full updates to the given value. Also 269 // persists the value being set so that we resume from the same value in case 270 // of a process restart. 271 void SetFullPayloadAttemptNumber(int payload_attempt_number); 272 273 // Sets the current payload index to the given value. Also persists the value 274 // being set so that we resume from the same value in case of a process 275 // restart. 276 void SetPayloadIndex(size_t payload_index); 277 278 // Initializes the current URL index from the persisted state. 279 void LoadUrlIndex(); 280 281 // Sets the current URL index to the given value. Also persists the value 282 // being set so that we resume from the same value in case of a process 283 // restart. 284 void SetUrlIndex(uint32_t url_index); 285 286 // Initializes the current URL's failure count from the persisted stae. 287 void LoadUrlFailureCount(); 288 289 // Sets the current URL's failure count to the given value. Also persists the 290 // value being set so that we resume from the same value in case of a process 291 // restart. 292 void SetUrlFailureCount(uint32_t url_failure_count); 293 294 // Sets |url_switch_count_| to the given value and persists the value. 295 void SetUrlSwitchCount(uint32_t url_switch_count); 296 297 // Initializes |url_switch_count_| from the persisted stae. 298 void LoadUrlSwitchCount(); 299 300 // Initializes the backoff expiry time from the persisted state. 301 void LoadBackoffExpiryTime(); 302 303 // Sets the backoff expiry time to the given value. Also persists the value 304 // being set so that we resume from the same value in case of a process 305 // restart. 306 void SetBackoffExpiryTime(const base::Time& new_time); 307 308 // Initializes |update_timestamp_start_| from the persisted state. 309 void LoadUpdateTimestampStart(); 310 311 // Sets |update_timestamp_start_| to the given value and persists the value. 312 void SetUpdateTimestampStart(const base::Time& value); 313 314 // Sets |update_timestamp_end_| to the given value. This is not persisted 315 // as it happens at the end of the update process where state is deleted 316 // anyway. 317 void SetUpdateTimestampEnd(const base::Time& value); 318 319 // Initializes |update_duration_uptime_| from the persisted state. 320 void LoadUpdateDurationUptime(); 321 322 // Helper method used in SetUpdateDurationUptime() and 323 // CalculateUpdateDurationUptime(). 324 void SetUpdateDurationUptimeExtended(const base::TimeDelta& value, 325 const base::Time& timestamp, 326 bool use_logging); 327 328 // Sets |update_duration_uptime_| to the given value and persists 329 // the value and sets |update_duration_uptime_timestamp_| to the 330 // current monotonic time. 331 void SetUpdateDurationUptime(const base::TimeDelta& value); 332 333 // Adds the difference between current monotonic time and 334 // |update_duration_uptime_timestamp_| to |update_duration_uptime_| and 335 // sets |update_duration_uptime_timestamp_| to current monotonic time. 336 void CalculateUpdateDurationUptime(); 337 338 // Returns the full key for a download source given the prefix. 339 std::string GetPrefsKey(const std::string& prefix, DownloadSource source); 340 341 // Loads the number of bytes that have been currently downloaded through the 342 // previous attempts from the persisted state for the given source. It's 343 // reset to 0 every time we begin a full update and is continued from previous 344 // attempt if we're resuming the update. 345 void LoadCurrentBytesDownloaded(DownloadSource source); 346 347 // Sets the number of bytes that have been currently downloaded for the 348 // given source. This value is also persisted. 349 void SetCurrentBytesDownloaded(DownloadSource source, 350 uint64_t current_bytes_downloaded, 351 bool log); 352 353 // Loads the total number of bytes that have been downloaded (since the last 354 // successful update) from the persisted state for the given source. It's 355 // reset to 0 every time we successfully apply an update and counts the bytes 356 // downloaded for both successful and failed attempts since then. 357 void LoadTotalBytesDownloaded(DownloadSource source); 358 359 // Sets the total number of bytes that have been downloaded so far for the 360 // given source. This value is also persisted. 361 void SetTotalBytesDownloaded(DownloadSource source, 362 uint64_t total_bytes_downloaded, 363 bool log); 364 365 // Loads whether rollback has happened on this device since the last update 366 // check where policy was available. This info is preserved over powerwash. 367 void LoadRollbackHappened(); 368 369 // Loads the excluded version from our prefs file. 370 void LoadRollbackVersion(); 371 372 // Excludes this version from getting AU'd to until we receive a new update 373 // response. 374 void SetRollbackVersion(const std::string& rollback_version); 375 376 // Clears any excluded version. 377 void ResetRollbackVersion(); 378 GetUrlIndex()379 inline uint32_t GetUrlIndex() { 380 return (url_index_ != 0 && payload_index_ < candidate_urls_.size()) 381 ? std::min(candidate_urls_[payload_index_].size() - 1, 382 url_index_) 383 : 0; 384 } 385 386 // Computes the list of candidate URLs from the total list of payload URLs in 387 // the Omaha response. 388 void ComputeCandidateUrls(); 389 390 // Sets |num_responses_seen_| and persist it to disk. 391 void SetNumResponsesSeen(int num_responses_seen); 392 393 // Initializes |num_responses_seen_| from persisted state. 394 void LoadNumResponsesSeen(); 395 396 // Initializes |num_reboots_| from the persisted state. 397 void LoadNumReboots(); 398 399 // Sets |num_reboots| for the update attempt. Also persists the 400 // value being set so that we resume from the same value in case of a process 401 // restart. 402 void SetNumReboots(uint32_t num_reboots); 403 404 // Checks to see if the device rebooted since the last call and if so 405 // increments num_reboots. 406 void UpdateNumReboots(); 407 408 // Loads the |kPrefsP2PFirstAttemptTimestamp| state variable from disk 409 // into |p2p_first_attempt_timestamp_|. 410 void LoadP2PFirstAttemptTimestamp(); 411 412 // Loads the |kPrefsP2PNumAttempts| state variable into |p2p_num_attempts_|. 413 void LoadP2PNumAttempts(); 414 415 // Sets the |kPrefsP2PNumAttempts| state variable to |value|. 416 void SetP2PNumAttempts(int value); 417 418 // Sets the |kPrefsP2PFirstAttemptTimestamp| state variable to |time|. 419 void SetP2PFirstAttemptTimestamp(const base::Time& time); 420 421 // Loads the persisted scattering wallclock-based wait period. 422 void LoadScatteringWaitPeriod(); 423 424 // Loads the persisted staging wallclock-based wait period. 425 void LoadStagingWaitPeriod(); 426 427 // Get the total size of all payloads. 428 int64_t GetPayloadSize(); 429 430 // The global state of the system. 431 SystemState* system_state_; 432 433 // Interface object with which we read/write persisted state. This must 434 // be set by calling the Initialize method before calling any other method. 435 PrefsInterface* prefs_; 436 437 // Interface object with which we read/write persisted state. This must 438 // be set by calling the Initialize method before calling any other method. 439 // This object persists across powerwashes. 440 PrefsInterface* powerwash_safe_prefs_; 441 442 // Interface object with which we determine exclusion decisions for 443 // payloads/partitions during the update. This must be set by calling the 444 // Initialize method before calling any other method. 445 ExcluderInterface* excluder_; 446 447 // This is the current response object from Omaha. 448 OmahaResponse response_; 449 450 // Whether P2P is being used for downloading and sharing. 451 bool using_p2p_for_downloading_; 452 bool using_p2p_for_sharing_; 453 454 // Stores the P2P download URL, if one is used. 455 std::string p2p_url_; 456 457 // The cached value of |kPrefsP2PFirstAttemptTimestamp|. 458 base::Time p2p_first_attempt_timestamp_; 459 460 // The cached value of |kPrefsP2PNumAttempts|. 461 int p2p_num_attempts_; 462 463 // This stores a "signature" of the current response. The signature here 464 // refers to a subset of the current response from Omaha. Each update to 465 // this value is persisted so we resume from the same value in case of a 466 // process restart. 467 std::string response_signature_; 468 469 // The number of times we've tried to download the payload. This is 470 // incremented each time we download the payload successsfully or when we 471 // exhaust all failure limits for all URLs and are about to wrap around back 472 // to the first URL. Each update to this value is persisted so we resume from 473 // the same value in case of a process restart. 474 int payload_attempt_number_; 475 476 // The number of times we've tried to download the payload in full. This is 477 // incremented each time we download the payload in full successsfully or 478 // when we exhaust all failure limits for all URLs and are about to wrap 479 // around back to the first URL. Each update to this value is persisted so 480 // we resume from the same value in case of a process restart. 481 int full_payload_attempt_number_; 482 483 // The index of the current payload. 484 size_t payload_index_ = 0; 485 486 // The index of the current URL. This type is different from the one in the 487 // accessor methods because PrefsInterface supports only int64_t but we want 488 // to provide a stronger abstraction of uint32_t. Each update to this value 489 // is persisted so we resume from the same value in case of a process 490 // restart. 491 size_t url_index_; 492 493 // The count of failures encountered in the current attempt to download using 494 // the current URL (specified by url_index_). Each update to this value is 495 // persisted so we resume from the same value in case of a process restart. 496 int64_t url_failure_count_; 497 498 // The number of times we've switched URLs. 499 int32_t url_switch_count_; 500 501 // The current download source based on the current URL. This value is 502 // not persisted as it can be recomputed every time we update the URL. 503 // We're storing this so as not to recompute this on every few bytes of 504 // data we read from the socket. 505 DownloadSource current_download_source_; 506 507 // The number of different Omaha responses seen. Increases every time 508 // a new response is seen. Resets to 0 only when the system has been 509 // successfully updated. 510 int num_responses_seen_; 511 512 // The number of system reboots during an update attempt. Technically since 513 // we don't go out of our way to not update it when not attempting an update, 514 // also records the number of reboots before the next update attempt starts. 515 uint32_t num_reboots_; 516 517 // The timestamp until which we've to wait before attempting to download the 518 // payload again, so as to backoff repeated downloads. 519 base::Time backoff_expiry_time_; 520 521 // The most recently calculated value of the update duration. 522 base::TimeDelta update_duration_current_; 523 524 // The point in time (wall-clock) that the update was started. 525 base::Time update_timestamp_start_; 526 527 // The point in time (wall-clock) that the update ended. If the update 528 // is still in progress, this is set to the Epoch (e.g. 0). 529 base::Time update_timestamp_end_; 530 531 // The update duration uptime 532 base::TimeDelta update_duration_uptime_; 533 534 // The monotonic time when |update_duration_uptime_| was last set 535 base::Time update_duration_uptime_timestamp_; 536 537 // The number of bytes that have been downloaded for each source for each new 538 // update attempt. If we resume an update, we'll continue from the previous 539 // value, but if we get a new response or if the previous attempt failed, 540 // we'll reset this to 0 to start afresh. Each update to this value is 541 // persisted so we resume from the same value in case of a process restart. 542 // The extra index in the array is to no-op accidental access in case the 543 // return value from GetCurrentDownloadSource is used without validation. 544 uint64_t current_bytes_downloaded_[kNumDownloadSources + 1]; 545 546 // The number of bytes that have been downloaded for each source since the 547 // the last successful update. This is used to compute the overhead we incur. 548 // Each update to this value is persisted so we resume from the same value in 549 // case of a process restart. 550 // The extra index in the array is to no-op accidental access in case the 551 // return value from GetCurrentDownloadSource is used without validation. 552 uint64_t total_bytes_downloaded_[kNumDownloadSources + 1]; 553 554 // A small timespan used when comparing wall-clock times for coping 555 // with the fact that clocks drift and consequently are adjusted 556 // (either forwards or backwards) via NTP. 557 static const base::TimeDelta kDurationSlack; 558 559 // The ordered list of the subset of payload URL candidates which are 560 // allowed as per device policy. 561 std::vector<std::vector<std::string>> candidate_urls_; 562 563 // This stores whether rollback has happened since the last time device policy 564 // was available during update check. When this is set, we're preventing 565 // forced updates to avoid update-rollback loops. 566 bool rollback_happened_; 567 568 // This stores an excluded version set as part of rollback. When we rollback 569 // we store the version of the os from which we are rolling back from in order 570 // to guarantee that we do not re-update to it on the next au attempt after 571 // reboot. 572 std::string rollback_version_; 573 574 // The number of bytes downloaded per attempt. 575 int64_t attempt_num_bytes_downloaded_; 576 577 // The boot time when the attempt was started. 578 base::Time attempt_start_time_boot_; 579 580 // The monotonic time when the attempt was started. 581 base::Time attempt_start_time_monotonic_; 582 583 // The connection type when the attempt started. 584 metrics::ConnectionType attempt_connection_type_; 585 586 // Whether we're currently rolling back. 587 AttemptType attempt_type_; 588 589 // The current scattering wallclock-based wait period. 590 base::TimeDelta scattering_wait_period_; 591 592 // The current staging wallclock-based wait period. 593 base::TimeDelta staging_wait_period_; 594 595 DISALLOW_COPY_AND_ASSIGN(PayloadState); 596 }; 597 598 } // namespace chromeos_update_engine 599 600 #endif // UPDATE_ENGINE_PAYLOAD_STATE_H_ 601