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