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