p2p: Use p2p for updates
This is the main patch for enabling use of p2p for consuming and/or
sharing updates via p2p. Refer to the ddoc and other documentation for
how this works.
BUG=chromium:260426,chromium:273110
TEST=New unit tests + unit tests pass + manual testing
Change-Id: I6bc3bddae1e041ccc176969a651396e8e89cb3f0
Reviewed-on: https://chromium-review.googlesource.com/64829
Reviewed-by: David Zeuthen <zeuthen@chromium.org>
Commit-Queue: David Zeuthen <zeuthen@chromium.org>
Tested-by: David Zeuthen <zeuthen@chromium.org>
diff --git a/update_attempter.cc b/update_attempter.cc
index 9ed321d..72d77c9 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -27,6 +27,7 @@
#include "update_engine/omaha_request_action.h"
#include "update_engine/omaha_request_params.h"
#include "update_engine/omaha_response_handler_action.h"
+#include "update_engine/p2p_manager.h"
#include "update_engine/payload_state_interface.h"
#include "update_engine/postinstall_runner_action.h"
#include "update_engine/prefs_interface.h"
@@ -218,6 +219,48 @@
system_state_->set_device_policy(device_policy);
}
+void UpdateAttempter::CalculateP2PParams(bool interactive) {
+ bool use_p2p_for_downloading = false;
+ bool use_p2p_for_sharing = false;
+
+ // Never use p2p for downloading in interactive checks unless the
+ // developer has opted in for it via a marker file.
+ //
+ // (Why would a developer want to opt in? If he's working on the
+ // update_engine or p2p codebases so he can actually test his
+ // code.).
+
+ if (system_state_ != NULL) {
+ if (!system_state_->p2p_manager()->IsP2PEnabled()) {
+ LOG(INFO) << "p2p is not enabled - disallowing p2p for both"
+ << " downloading and sharing.";
+ } else {
+ // Allow p2p for sharing, even in interactive checks.
+ use_p2p_for_sharing = true;
+ if (!interactive) {
+ LOG(INFO) << "Non-interactive check - allowing p2p for downloading";
+ use_p2p_for_downloading = true;
+ } else {
+ // TODO(zeuthen,chromium:273251): Remove this marker once we
+ // can easily trigger non-interactive checks.
+ if (utils::IsP2PAllowedForInteractiveChecks()) {
+ LOG(INFO) << "Found marker file at "
+ << kP2PAllowInteractiveMarkerFile
+ << " - allowing p2p for downloading despite the fact"
+ << " the attempt is interactive.";
+ use_p2p_for_downloading = true;
+ } else {
+ LOG(INFO) << "Forcibly disabling use of p2p for downloading "
+ << "since this update attempt is interactive.";
+ }
+ }
+ }
+ }
+
+ omaha_request_params_->set_use_p2p_for_downloading(use_p2p_for_downloading);
+ omaha_request_params_->set_use_p2p_for_sharing(use_p2p_for_sharing);
+}
+
bool UpdateAttempter::CalculateUpdateParams(const string& app_version,
const string& omaha_url,
bool obey_proxies,
@@ -252,6 +295,19 @@
CalculateScatteringParams(interactive);
+ CalculateP2PParams(interactive);
+ if (omaha_request_params_->use_p2p_for_downloading() ||
+ omaha_request_params_->use_p2p_for_sharing()) {
+ // OK, p2p is to be used - start it and perform housekeeping.
+ if (!StartP2PAndPerformHousekeeping()) {
+ // If this fails, disable p2p for this attempt
+ LOG(INFO) << "Forcibly disabling use of p2p since starting p2p or "
+ << "performing housekeeping failed.";
+ omaha_request_params_->set_use_p2p_for_downloading(false);
+ omaha_request_params_->set_use_p2p_for_sharing(false);
+ }
+ }
+
// Determine whether an alternative test address should be used.
string omaha_url_to_use = omaha_url;
if ((is_using_test_url_ = (omaha_url_to_use.empty() && is_test_mode_))) {
@@ -311,6 +367,11 @@
<< ", Waiting Period = " << utils::FormatSecs(
omaha_request_params_->waiting_period().InSeconds());
+ LOG(INFO) << "Use p2p For Downloading = "
+ << omaha_request_params_->use_p2p_for_downloading()
+ << ", Use p2p For Sharing = "
+ << omaha_request_params_->use_p2p_for_sharing();
+
obeying_proxies_ = true;
if (obey_proxies || proxy_manual_checks_ == 0) {
LOG(INFO) << "forced to obey proxies";
@@ -1250,8 +1311,51 @@
return false;
}
+
void UpdateAttempter::UpdateEngineStarted() {
system_state_->payload_state()->UpdateEngineStarted();
+ StartP2PAtStartup();
+}
+
+bool UpdateAttempter::StartP2PAtStartup() {
+ if (system_state_ == NULL ||
+ !system_state_->p2p_manager()->IsP2PEnabled()) {
+ LOG(INFO) << "Not starting p2p at startup since it's not enabled.";
+ return false;
+ }
+
+ if (system_state_->p2p_manager()->CountSharedFiles() < 1) {
+ LOG(INFO) << "Not starting p2p at startup since our application "
+ << "is not sharing any files.";
+ return false;
+ }
+
+ return StartP2PAndPerformHousekeeping();
+}
+
+bool UpdateAttempter::StartP2PAndPerformHousekeeping() {
+ if (system_state_ == NULL)
+ return false;
+
+ if (!system_state_->p2p_manager()->IsP2PEnabled()) {
+ LOG(INFO) << "Not starting p2p since it's not enabled.";
+ return false;
+ }
+
+ LOG(INFO) << "Ensuring that p2p is running.";
+ if (!system_state_->p2p_manager()->EnsureP2PRunning()) {
+ LOG(ERROR) << "Error starting p2p.";
+ return false;
+ }
+
+ LOG(INFO) << "Performing p2p housekeeping.";
+ if (!system_state_->p2p_manager()->PerformHousekeeping()) {
+ LOG(ERROR) << "Error performing housekeeping for p2p.";
+ return false;
+ }
+
+ LOG(INFO) << "Done performing p2p housekeeping.";
+ return true;
}
} // namespace chromeos_update_engine