Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "update_engine/update_attempter.h" | 5 #include "update_engine/update_attempter.h" |
| 6 | |
| 7 // From 'man clock_gettime': feature test macro: _POSIX_C_SOURCE >= 199309L | |
| 8 #ifndef _POSIX_C_SOURCE | |
| 9 #define _POSIX_C_SOURCE 199309L | |
| 10 #endif // _POSIX_C_SOURCE | |
| 11 #include <time.h> | |
| 12 | |
| 6 #include <tr1/memory> | 13 #include <tr1/memory> |
| 7 #include <string> | 14 #include <string> |
| 8 #include <vector> | 15 #include <vector> |
| 9 #include <glib.h> | 16 #include <glib.h> |
| 17 #include "update_engine/dbus_service.h" | |
| 10 #include "update_engine/download_action.h" | 18 #include "update_engine/download_action.h" |
| 11 #include "update_engine/filesystem_copier_action.h" | 19 #include "update_engine/filesystem_copier_action.h" |
| 12 #include "update_engine/libcurl_http_fetcher.h" | 20 #include "update_engine/libcurl_http_fetcher.h" |
| 13 #include "update_engine/omaha_request_prep_action.h" | 21 #include "update_engine/omaha_request_prep_action.h" |
| 14 #include "update_engine/omaha_response_handler_action.h" | 22 #include "update_engine/omaha_response_handler_action.h" |
| 15 #include "update_engine/postinstall_runner_action.h" | 23 #include "update_engine/postinstall_runner_action.h" |
| 16 #include "update_engine/set_bootable_flag_action.h" | 24 #include "update_engine/set_bootable_flag_action.h" |
| 17 #include "update_engine/update_check_action.h" | 25 #include "update_engine/update_check_action.h" |
| 18 | 26 |
| 19 using std::tr1::shared_ptr; | 27 using std::tr1::shared_ptr; |
| 20 using std::string; | 28 using std::string; |
| 21 using std::vector; | 29 using std::vector; |
| 22 | 30 |
| 23 namespace chromeos_update_engine { | 31 namespace chromeos_update_engine { |
| 24 | 32 |
| 33 namespace { | |
| 34 // Returns true on success. | |
| 35 bool GetCPUClockTime(struct timespec* out) { | |
| 36 return clock_gettime(CLOCK_REALTIME, out) == 0; | |
| 37 } | |
| 38 // Returns stop - start. | |
| 39 struct timespec CPUClockTimeElapsed(const struct timespec& start, | |
| 40 const struct timespec& stop) { | |
| 41 CHECK(start.tv_sec >= 0); | |
| 42 CHECK(stop.tv_sec >= 0); | |
| 43 CHECK(start.tv_nsec >= 0); | |
| 44 CHECK(stop.tv_nsec >= 0); | |
| 45 | |
| 46 const int64 kOneBillion = 1000000000L; | |
|
Daniel Erat
2010/05/10 19:11:42
nit: int64_t :-)
| |
| 47 int64 start64 = start.tv_sec * kOneBillion + start.tv_nsec; | |
| 48 int64 stop64 = stop.tv_sec * kOneBillion + stop.tv_nsec; | |
| 49 | |
| 50 int64 result64 = stop64 - start64; | |
| 51 | |
| 52 struct timespec ret; | |
| 53 ret.tv_sec = result64 / kOneBillion; | |
| 54 ret.tv_nsec = result64 % kOneBillion; | |
| 55 | |
| 56 return ret; | |
| 57 } | |
| 58 bool CPUClockTimeGreaterThanHalfSecond(const struct timespec& spec) { | |
| 59 if (spec.tv_sec >= 1) | |
| 60 return true; | |
| 61 return (spec.tv_nsec > 500000000); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 const char* UpdateStatusToString(UpdateStatus status) { | |
| 66 switch (status) { | |
| 67 case UPDATE_STATUS_IDLE: | |
| 68 return "UPDATE_STATUS_IDLE"; | |
| 69 case UPDATE_STATUS_CHECKING_FOR_UPDATE: | |
| 70 return "UPDATE_STATUS_CHECKING_FOR_UPDATE"; | |
| 71 case UPDATE_STATUS_UPDATE_AVAILABLE: | |
| 72 return "UPDATE_STATUS_UPDATE_AVAILABLE"; | |
| 73 case UPDATE_STATUS_DOWNLOADING: | |
| 74 return "UPDATE_STATUS_DOWNLOADING"; | |
| 75 case UPDATE_STATUS_VERIFYING: | |
| 76 return "UPDATE_STATUS_VERIFYING"; | |
| 77 case UPDATE_STATUS_FINALIZING: | |
| 78 return "UPDATE_STATUS_FINALIZING"; | |
| 79 case UPDATE_STATUS_UPDATED_NEED_REBOOT: | |
| 80 return "UPDATE_STATUS_UPDATED_NEED_REBOOT"; | |
| 81 default: | |
| 82 return "unknown status"; | |
| 83 } | |
| 84 } | |
| 85 | |
| 25 void UpdateAttempter::Update(bool force_full_update) { | 86 void UpdateAttempter::Update(bool force_full_update) { |
| 26 full_update_ = force_full_update; | 87 full_update_ = force_full_update; |
| 27 CHECK(!processor_.IsRunning()); | 88 CHECK(!processor_.IsRunning()); |
| 28 processor_.set_delegate(this); | 89 processor_.set_delegate(this); |
| 29 | 90 |
| 30 // Actions: | 91 // Actions: |
| 31 shared_ptr<OmahaRequestPrepAction> request_prep_action( | 92 shared_ptr<OmahaRequestPrepAction> request_prep_action( |
| 32 new OmahaRequestPrepAction(force_full_update)); | 93 new OmahaRequestPrepAction(force_full_update)); |
| 33 shared_ptr<UpdateCheckAction> update_check_action( | 94 shared_ptr<UpdateCheckAction> update_check_action( |
| 34 new UpdateCheckAction(new LibcurlHttpFetcher)); | 95 new UpdateCheckAction(new LibcurlHttpFetcher)); |
| 35 shared_ptr<OmahaResponseHandlerAction> response_handler_action( | 96 shared_ptr<OmahaResponseHandlerAction> response_handler_action( |
| 36 new OmahaResponseHandlerAction); | 97 new OmahaResponseHandlerAction); |
| 37 shared_ptr<FilesystemCopierAction> filesystem_copier_action( | 98 shared_ptr<FilesystemCopierAction> filesystem_copier_action( |
| 38 new FilesystemCopierAction(false)); | 99 new FilesystemCopierAction(false)); |
| 39 shared_ptr<FilesystemCopierAction> kernel_filesystem_copier_action( | 100 shared_ptr<FilesystemCopierAction> kernel_filesystem_copier_action( |
| 40 new FilesystemCopierAction(true)); | 101 new FilesystemCopierAction(true)); |
| 41 shared_ptr<DownloadAction> download_action( | 102 shared_ptr<DownloadAction> download_action( |
| 42 new DownloadAction(new LibcurlHttpFetcher)); | 103 new DownloadAction(new LibcurlHttpFetcher)); |
| 43 shared_ptr<PostinstallRunnerAction> postinstall_runner_action_precommit( | 104 shared_ptr<PostinstallRunnerAction> postinstall_runner_action_precommit( |
| 44 new PostinstallRunnerAction(true)); | 105 new PostinstallRunnerAction(true)); |
| 45 shared_ptr<SetBootableFlagAction> set_bootable_flag_action( | 106 shared_ptr<SetBootableFlagAction> set_bootable_flag_action( |
| 46 new SetBootableFlagAction); | 107 new SetBootableFlagAction); |
| 47 shared_ptr<PostinstallRunnerAction> postinstall_runner_action_postcommit( | 108 shared_ptr<PostinstallRunnerAction> postinstall_runner_action_postcommit( |
| 48 new PostinstallRunnerAction(false)); | 109 new PostinstallRunnerAction(false)); |
| 49 | 110 |
| 111 download_action->set_delegate(this); | |
| 50 response_handler_action_ = response_handler_action; | 112 response_handler_action_ = response_handler_action; |
| 51 | 113 |
| 52 actions_.push_back(shared_ptr<AbstractAction>(request_prep_action)); | 114 actions_.push_back(shared_ptr<AbstractAction>(request_prep_action)); |
| 53 actions_.push_back(shared_ptr<AbstractAction>(update_check_action)); | 115 actions_.push_back(shared_ptr<AbstractAction>(update_check_action)); |
| 54 actions_.push_back(shared_ptr<AbstractAction>(response_handler_action)); | 116 actions_.push_back(shared_ptr<AbstractAction>(response_handler_action)); |
| 55 actions_.push_back(shared_ptr<AbstractAction>(filesystem_copier_action)); | 117 actions_.push_back(shared_ptr<AbstractAction>(filesystem_copier_action)); |
| 56 actions_.push_back(shared_ptr<AbstractAction>( | 118 actions_.push_back(shared_ptr<AbstractAction>( |
| 57 kernel_filesystem_copier_action)); | 119 kernel_filesystem_copier_action)); |
| 58 actions_.push_back(shared_ptr<AbstractAction>(download_action)); | 120 actions_.push_back(shared_ptr<AbstractAction>(download_action)); |
| 59 actions_.push_back(shared_ptr<AbstractAction>( | 121 actions_.push_back(shared_ptr<AbstractAction>( |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 80 kernel_filesystem_copier_action.get()); | 142 kernel_filesystem_copier_action.get()); |
| 81 BondActions(kernel_filesystem_copier_action.get(), | 143 BondActions(kernel_filesystem_copier_action.get(), |
| 82 download_action.get()); | 144 download_action.get()); |
| 83 BondActions(download_action.get(), | 145 BondActions(download_action.get(), |
| 84 postinstall_runner_action_precommit.get()); | 146 postinstall_runner_action_precommit.get()); |
| 85 BondActions(postinstall_runner_action_precommit.get(), | 147 BondActions(postinstall_runner_action_precommit.get(), |
| 86 set_bootable_flag_action.get()); | 148 set_bootable_flag_action.get()); |
| 87 BondActions(set_bootable_flag_action.get(), | 149 BondActions(set_bootable_flag_action.get(), |
| 88 postinstall_runner_action_postcommit.get()); | 150 postinstall_runner_action_postcommit.get()); |
| 89 | 151 |
| 152 SetStatusAndNotify(UPDATE_STATUS_CHECKING_FOR_UPDATE); | |
| 90 processor_.StartProcessing(); | 153 processor_.StartProcessing(); |
| 91 } | 154 } |
| 92 | 155 |
| 93 // Delegate method: | 156 void UpdateAttempter::CheckForUpdate() { |
| 157 if (status_ != UPDATE_STATUS_IDLE) { | |
| 158 LOG(INFO) << "Check for update requested, but status is " | |
| 159 << UpdateStatusToString(status_) << ", so not checking."; | |
| 160 return; | |
| 161 } | |
| 162 Update(false); | |
| 163 } | |
| 164 | |
| 165 // Delegate methods: | |
| 94 void UpdateAttempter::ProcessingDone(const ActionProcessor* processor, | 166 void UpdateAttempter::ProcessingDone(const ActionProcessor* processor, |
| 95 bool success) { | 167 bool success) { |
| 96 CHECK(response_handler_action_); | 168 CHECK(response_handler_action_); |
| 97 if (response_handler_action_->GotNoUpdateResponse()) { | 169 LOG(INFO) << "Processing Done."; |
| 98 // All done. | 170 if (success) { |
| 99 g_main_loop_quit(loop_); | 171 SetStatusAndNotify(UPDATE_STATUS_UPDATED_NEED_REBOOT); |
| 172 } else { | |
| 173 LOG(INFO) << "Update failed."; | |
| 174 SetStatusAndNotify(UPDATE_STATUS_IDLE); | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) { | |
| 179 download_progress_ = 0.0; | |
| 180 SetStatusAndNotify(UPDATE_STATUS_IDLE); | |
| 181 } | |
| 182 | |
| 183 // Called whenever an action has finished processing, either successfully | |
| 184 // or otherwise. | |
| 185 void UpdateAttempter::ActionCompleted(ActionProcessor* processor, | |
| 186 AbstractAction* action, | |
| 187 bool success) { | |
| 188 // Reset download progress regardless of whether or not the download action | |
| 189 // succeeded. | |
| 190 const string type = action->Type(); | |
| 191 if (type == DownloadAction::StaticType()) | |
| 192 download_progress_ = 0.0; | |
| 193 if (!success) | |
| 100 return; | 194 return; |
| 195 // Find out which action completed. | |
| 196 if (type == OmahaResponseHandlerAction::StaticType()) { | |
| 197 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); | |
| 198 OmahaResponseHandlerAction* omaha_response_handler_action = | |
| 199 dynamic_cast<OmahaResponseHandlerAction*>(action); | |
| 200 CHECK(omaha_response_handler_action); | |
| 201 const InstallPlan& plan = omaha_response_handler_action->install_plan(); | |
| 202 last_checked_time_ = time(NULL); | |
| 203 // TODO(adlr): put version in InstallPlan | |
| 204 new_version_ = "0.0.0.0"; | |
| 205 new_size_ = plan.size; | |
| 206 } else if (type == DownloadAction::StaticType()) { | |
| 207 SetStatusAndNotify(UPDATE_STATUS_FINALIZING); | |
| 101 } | 208 } |
| 102 if (!success) { | |
| 103 LOG(INFO) << "Update failed."; | |
| 104 } | |
| 105 g_main_loop_quit(loop_); | |
| 106 } | 209 } |
| 107 | 210 |
| 108 // Stop updating. An attempt will be made to record status to the disk | 211 // Stop updating. An attempt will be made to record status to the disk |
| 109 // so that updates can be resumed later. | 212 // so that updates can be resumed later. |
| 110 void UpdateAttempter::Terminate() { | 213 void UpdateAttempter::Terminate() { |
| 111 // TODO(adlr): implement this method. | 214 // TODO(adlr): implement this method. |
| 112 NOTIMPLEMENTED(); | 215 NOTIMPLEMENTED(); |
| 113 } | 216 } |
| 114 | 217 |
| 115 // Try to resume from a previously Terminate()d update. | 218 // Try to resume from a previously Terminate()d update. |
| 116 void UpdateAttempter::ResumeUpdating() { | 219 void UpdateAttempter::ResumeUpdating() { |
| 117 // TODO(adlr): implement this method. | 220 // TODO(adlr): implement this method. |
| 118 NOTIMPLEMENTED(); | 221 NOTIMPLEMENTED(); |
| 119 } | 222 } |
| 120 | 223 |
| 224 void UpdateAttempter::BytesReceived(uint64_t bytes_received, uint64_t total) { | |
| 225 if (status_ != UPDATE_STATUS_DOWNLOADING) { | |
| 226 LOG(ERROR) << "BytesReceived called while not downloading."; | |
| 227 return; | |
| 228 } | |
| 229 download_progress_ = static_cast<double>(bytes_received) / | |
| 230 static_cast<double>(total); | |
| 231 // We self throttle here | |
| 232 timespec now; | |
| 233 now.tv_sec = 0; | |
| 234 now.tv_nsec = 0; | |
| 235 if (GetCPUClockTime(&now) && | |
| 236 CPUClockTimeGreaterThanHalfSecond( | |
| 237 CPUClockTimeElapsed(last_notify_time_, now))) { | |
| 238 SetStatusAndNotify(UPDATE_STATUS_DOWNLOADING); | |
| 239 } | |
| 240 } | |
| 241 | |
| 121 bool UpdateAttempter::GetStatus(int64_t* last_checked_time, | 242 bool UpdateAttempter::GetStatus(int64_t* last_checked_time, |
| 122 double* progress, | 243 double* progress, |
| 123 std::string* current_operation, | 244 std::string* current_operation, |
| 124 std::string* new_version, | 245 std::string* new_version, |
| 125 int64_t* new_size) { | 246 int64_t* new_size) { |
| 126 // TODO(adlr): Return actual status. | 247 *last_checked_time = last_checked_time_; |
| 127 *last_checked_time = 123; | 248 *progress = download_progress_; |
| 128 *progress = 0.2223; | 249 *current_operation = UpdateStatusToString(status_); |
| 129 *current_operation = "DOWNLOADING"; | 250 *new_version = new_version_; |
| 130 *new_version = "0.2.3.8"; | 251 *new_size = new_size_; |
| 131 *new_size = 10002; | |
| 132 return true; | 252 return true; |
| 133 } | 253 } |
| 134 | 254 |
| 255 void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) { | |
| 256 status_ = status; | |
| 257 if (!dbus_service_) | |
| 258 return; | |
| 259 GetCPUClockTime(&last_notify_time_); | |
| 260 update_engine_service_emit_status_update( | |
| 261 dbus_service_, | |
| 262 last_checked_time_, | |
| 263 download_progress_, | |
| 264 UpdateStatusToString(status_), | |
| 265 new_version_.c_str(), | |
| 266 new_size_); | |
| 267 } | |
| 135 | 268 |
| 136 } // namespace chromeos_update_engine | 269 } // namespace chromeos_update_engine |
| OLD | NEW |