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