Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1333)

Unified Diff: remoting/host/remoting_me2me_host.cc

Issue 910403002: Suspend (rather than shut down) the host upon policy errors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mistyped-policies
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: remoting/host/remoting_me2me_host.cc
diff --git a/remoting/host/remoting_me2me_host.cc b/remoting/host/remoting_me2me_host.cc
index b66f8376f791bea52a9ff8cc57ce6339324331d2..ec742e5d2d5fcb90cb5e3c440b1e151d1fa7862a 100644
--- a/remoting/host/remoting_me2me_host.cc
+++ b/remoting/host/remoting_me2me_host.cc
@@ -213,6 +213,21 @@ class HostProcess : public ConfigWatcher::Delegate,
// nullptr in all other states.
};
+ enum PolicyState {
+ // Cannot start the host, because a valid policy has not been read yet.
+ POLICY_INITIALIZING,
+
+ // Policy was loaded successfully.
+ POLICY_LOADED,
+
+ // Policy error was detected, and we haven't yet sent out a
+ // host-offline-reason (i.e. because we haven't yet read the config).
+ POLICY_ERROR_REPORT_PENDING,
+
+ // Policy error was detected, and we have sent out a host-offline-reason.
+ POLICY_ERROR_REPORTED,
+ };
+
friend class base::RefCountedThreadSafe<HostProcess>;
~HostProcess() override;
@@ -245,6 +260,7 @@ class HostProcess : public ConfigWatcher::Delegate,
// Handles policy updates, by calling On*PolicyUpdate methods.
void OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies);
void OnPolicyError();
+ void ReportPolicyErrorAndRestartHost();
void ApplyHostDomainPolicy();
void ApplyUsernamePolicy();
bool OnHostDomainPolicyUpdate(base::DictionaryValue* policies);
@@ -273,11 +289,10 @@ class HostProcess : public ConfigWatcher::Delegate,
// Stops the host and shuts down the process with the specified |exit_code|.
void ShutdownHost(HostExitCodes exit_code);
- // Private helper used by ShutdownHost method to initiate sending of
- // host-offline-reason before continuing shutdown.
- void SendOfflineReasonAndShutdownOnNetworkThread(HostExitCodes exit_code);
-
- void ShutdownOnNetworkThread();
+ // Starts host shut down with an optional |host_offline_reason|.
+ void ShutdownOnNetworkThread(const std::string* host_offline_reason);
Wez 2015/02/12 02:51:25 Do we need to express "no reason" via nullptr - co
Łukasz Anforowicz 2015/02/12 18:08:01 We can use an empty string. Thanks for bringing t
Wez 2015/02/12 21:07:07 Acknowledged.
+ void ContinueShutdownOnNetworkThread();
+ void OnHostOfflineReasonAck(bool success);
#if defined(OS_WIN)
// Initializes the pairing registry on Windows. This should be invoked on the
@@ -325,7 +340,7 @@ class HostProcess : public ConfigWatcher::Delegate,
int64_t frame_recorder_buffer_size_;
scoped_ptr<PolicyWatcher> policy_watcher_;
- bool policies_loaded_;
+ PolicyState policy_state_;
std::string host_domain_;
bool host_username_match_required_;
bool allow_nat_traversal_;
@@ -381,7 +396,7 @@ HostProcess::HostProcess(scoped_ptr<ChromotingHostContext> context,
use_service_account_(false),
enable_vp9_(false),
frame_recorder_buffer_size_(0),
- policies_loaded_(false),
+ policy_state_(POLICY_INITIALIZING),
host_username_match_required_(false),
allow_nat_traversal_(true),
allow_relay_(true),
@@ -551,12 +566,11 @@ void HostProcess::OnConfigUpdated(
return;
}
- if (state_ == HOST_INITIALIZING) {
+ if (state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART) {
StartHostIfReady();
} else if (state_ == HOST_STARTED) {
- DCHECK(policies_loaded_);
-
// Reapply policies that could be affected by a new config.
+ DCHECK(policy_state_ == POLICY_LOADED);
ApplyHostDomainPolicy();
ApplyUsernamePolicy();
@@ -981,9 +995,9 @@ void HostProcess::OnPolicyUpdate(scoped_ptr<base::DictionaryValue> policies) {
restart_required |= OnPairingPolicyUpdate(policies.get());
restart_required |= OnGnubbyAuthPolicyUpdate(policies.get());
- policies_loaded_ = true;
+ policy_state_ = POLICY_LOADED;
- if (state_ == HOST_INITIALIZING) {
+ if (state_ == HOST_INITIALIZING || state_ == HOST_STOPPING_TO_RESTART) {
StartHostIfReady();
} else if (state_ == HOST_STARTED) {
if (restart_required)
@@ -998,7 +1012,24 @@ void HostProcess::OnPolicyError() {
return;
}
- ShutdownHost(kInvalidHostConfigurationExitCode);
+ if (policy_state_ != POLICY_ERROR_REPORTED) {
+ policy_state_ = POLICY_ERROR_REPORT_PENDING;
+ if (state_ == HOST_INITIALIZING) {
+ StartHostIfReady();
+ } else if (state_ == HOST_STARTED) {
+ ReportPolicyErrorAndRestartHost();
+ }
+ }
+}
+
+void HostProcess::ReportPolicyErrorAndRestartHost() {
Wez 2015/02/12 02:51:25 Please put some blank lines in this function to br
Łukasz Anforowicz 2015/02/12 18:08:01 Done.
+ DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
+ DCHECK_EQ(policy_state_, POLICY_ERROR_REPORT_PENDING);
+ LOG(INFO) << "Restarting the host due to policy errors.";
+ state_ = HOST_STOPPING_TO_RESTART;
+ policy_state_ = POLICY_ERROR_REPORTED;
+ std::string host_offline_reason = "POLICY_READ_ERROR";
+ ShutdownOnNetworkThread(&host_offline_reason);
}
void HostProcess::ApplyHostDomainPolicy() {
@@ -1300,20 +1331,24 @@ scoped_ptr<HostSignalingManager> HostProcess::CreateHostSignalingManager() {
oauth_refresh_token_,
use_service_account_));
- return HostSignalingManager::Create(this, context_->network_task_runner(),
- context_->url_request_context_getter(),
- xmpp_server_config_, talkgadget_prefix_,
- host_id_, key_pair_, directory_bot_jid_,
- oauth_credentials.Pass());
+ return HostSignalingManager::Create(
+ this, context_->url_request_context_getter(), xmpp_server_config_,
+ talkgadget_prefix_, host_id_, key_pair_, directory_bot_jid_,
+ oauth_credentials.Pass());
}
void HostProcess::StartHostIfReady() {
DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
- DCHECK_EQ(state_, HOST_INITIALIZING);
+ DCHECK((state_ == HOST_INITIALIZING) || (state_ == HOST_STOPPING_TO_RESTART));
// Start the host if both the config and the policies are loaded.
- if (!serialized_config_.empty() && policies_loaded_)
- StartHost();
+ if (!serialized_config_.empty()) {
+ if (policy_state_ == POLICY_LOADED) {
+ StartHost();
+ } else if (policy_state_ == POLICY_ERROR_REPORT_PENDING) {
+ ReportPolicyErrorAndRestartHost();
+ }
+ }
}
void HostProcess::StartHost() {
@@ -1414,35 +1449,20 @@ void HostProcess::RestartHost() {
DCHECK_EQ(state_, HOST_STARTED);
state_ = HOST_STOPPING_TO_RESTART;
- ShutdownOnNetworkThread();
-}
-
-void HostProcess::SendOfflineReasonAndShutdownOnNetworkThread(
- HostExitCodes exit_code) {
- DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
- DCHECK(host_signaling_manager_);
- host_signaling_manager_.release()->SendHostOfflineReasonAndDelete(
- ExitCodeToString(exit_code),
- base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds));
- ShutdownOnNetworkThread();
+ ShutdownOnNetworkThread(nullptr);
Wez 2015/02/12 02:51:25 Is "no reason" the right thing to report here? Why
Łukasz Anforowicz 2015/02/12 18:08:01 Good point. Done. I was also struggling with a d
}
void HostProcess::ShutdownHost(HostExitCodes exit_code) {
DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
*exit_code_out_ = exit_code;
+ std::string host_offline_reason = ExitCodeToString(exit_code);
switch (state_) {
case HOST_INITIALIZING:
- state_ = HOST_STOPPING;
- DCHECK(!host_signaling_manager_);
- host_signaling_manager_ = CreateHostSignalingManager();
- SendOfflineReasonAndShutdownOnNetworkThread(exit_code);
- break;
-
case HOST_STARTED:
state_ = HOST_STOPPING;
- SendOfflineReasonAndShutdownOnNetworkThread(exit_code);
+ ShutdownOnNetworkThread(&host_offline_reason);
break;
case HOST_STOPPING_TO_RESTART:
@@ -1456,17 +1476,41 @@ void HostProcess::ShutdownHost(HostExitCodes exit_code) {
}
}
-void HostProcess::ShutdownOnNetworkThread() {
+void HostProcess::ShutdownOnNetworkThread(
+ const std::string* host_offline_reason) {
DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
host_.reset();
host_event_logger_.reset();
host_status_logger_.reset();
- host_signaling_manager_.reset();
host_change_notification_listener_.reset();
+ if (host_offline_reason == nullptr) {
Wez 2015/02/12 02:51:25 nit: Please add some comments to these two blocks
Łukasz Anforowicz 2015/02/12 18:08:01 Done (at least I tried to add sensible comments).
Wez 2015/02/12 21:07:07 These look good in terms of content, but instead o
Łukasz Anforowicz 2015/02/12 22:51:13 Done.
+ ContinueShutdownOnNetworkThread();
+ return;
+ }
+ if (serialized_config_.empty()) {
+ HOST_LOG << "SendHostOfflineReason( " << host_offline_reason << ") "
+ << "not possible without a config...";
+ ContinueShutdownOnNetworkThread();
+ return;
+ }
+
+ if (!host_signaling_manager_) {
+ host_signaling_manager_ = CreateHostSignalingManager();
+ }
+ host_signaling_manager_->SendHostOfflineReason(
+ *host_offline_reason,
+ base::TimeDelta::FromSeconds(kHostOfflineReasonTimeoutSeconds),
+ base::Bind(&HostProcess::OnHostOfflineReasonAck, base::Unretained(this)));
Wez 2015/02/12 02:51:25 With things structured as they are, with a nullptr
Łukasz Anforowicz 2015/02/12 18:08:01 Done. I think things look better now. - I didn't
+}
+
+void HostProcess::ContinueShutdownOnNetworkThread() {
Wez 2015/02/12 02:51:25 If you prefer to keep this as-is then I'd suggest
Łukasz Anforowicz 2015/02/12 18:08:01 N/A (I went with one function as you suggested abo
+ DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
+ host_signaling_manager_.reset();
+
if (state_ == HOST_STOPPING_TO_RESTART) {
- StartHost();
+ StartHostIfReady();
} else if (state_ == HOST_STOPPING) {
state_ = HOST_STOPPED;
@@ -1484,6 +1528,17 @@ void HostProcess::ShutdownOnNetworkThread() {
}
}
+void HostProcess::OnHostOfflineReasonAck(bool success) {
+ DCHECK(context_->network_task_runner()->BelongsToCurrentThread());
Wez 2015/02/12 02:51:25 As above, suggest blank line between the pre-condi
Łukasz Anforowicz 2015/02/12 18:08:01 Done.
+ if (success) {
+ HOST_LOG << "SendHostOfflineReason: succeeded";
+ } else {
+ HOST_LOG << "SendHostOfflineReason: timed out";
+ }
+
+ ContinueShutdownOnNetworkThread();
+}
+
void HostProcess::OnCrash(const std::string& function_name,
const std::string& file_name,
const int& line_number) {

Powered by Google App Engine
This is Rietveld 408576698