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