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