Commit 842b0fa9 authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

If DriveFS fails to mount while offline, retry when online again.

If DriveFS is first launched while offline, it'll fail to launch, retry
a few times and then give up until the user logs out and in again or
toggles drive off and on again. Reduce the likelihood of this by
delaying retries until online if DriveFS mount fails while offline.

Bug: 880720
Change-Id: Id1e851d81dd693284374fb4d32ce250958de41e2
Reviewed-on: https://chromium-review.googlesource.com/1208996
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: default avatarSergei Datsenko <dats@chromium.org>
Cr-Commit-Position: refs/heads/master@{#589115}
parent aa5e19bb
......@@ -325,6 +325,16 @@ class DriveIntegrationService::PreferenceWatcher
// net::NetworkChangeNotifier::NetworkChangeObserver
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override {
// Check for a pending remount first. In this case, DriveFS will not be
// mounted and thus its interface will be null.
if (integration_service_->drivefs_holder_ &&
integration_service_->remount_when_online_ &&
!net::NetworkChangeNotifier::IsOffline()) {
integration_service_->remount_when_online_ = false;
integration_service_->AddDriveMountPoint();
return;
}
if (!integration_service_->GetDriveFsInterface())
return;
......@@ -345,12 +355,13 @@ class DriveIntegrationService::PreferenceWatcher
class DriveIntegrationService::DriveFsHolder
: public drivefs::DriveFsHost::Delegate {
public:
DriveFsHolder(Profile* profile,
base::RepeatingClosure on_drivefs_mounted,
base::RepeatingCallback<void(base::Optional<base::TimeDelta>)>
on_drivefs_unmounted,
DriveFsMojoConnectionDelegateFactory
test_drivefs_mojo_connection_delegate_factory)
DriveFsHolder(
Profile* profile,
base::RepeatingClosure on_drivefs_mounted,
base::RepeatingCallback<void(base::Optional<base::TimeDelta>,
bool failed_to_mount)> on_drivefs_unmounted,
DriveFsMojoConnectionDelegateFactory
test_drivefs_mojo_connection_delegate_factory)
: profile_(profile),
on_drivefs_mounted_(std::move(on_drivefs_mounted)),
on_drivefs_unmounted_(std::move(on_drivefs_unmounted)),
......@@ -385,7 +396,7 @@ class DriveIntegrationService::DriveFsHolder
}
void OnMountFailed(base::Optional<base::TimeDelta> remount_delay) override {
on_drivefs_unmounted_.Run(std::move(remount_delay));
on_drivefs_unmounted_.Run(std::move(remount_delay), true);
}
void OnMounted(const base::FilePath& path) override {
......@@ -393,7 +404,7 @@ class DriveIntegrationService::DriveFsHolder
}
void OnUnmounted(base::Optional<base::TimeDelta> remount_delay) override {
on_drivefs_unmounted_.Run(std::move(remount_delay));
on_drivefs_unmounted_.Run(std::move(remount_delay), false);
}
const std::string& GetProfileSalt() {
......@@ -420,7 +431,8 @@ class DriveIntegrationService::DriveFsHolder
// Invoked when DriveFS mounting is completed.
const base::RepeatingClosure on_drivefs_mounted_;
const base::RepeatingCallback<void(base::Optional<base::TimeDelta>)>
const base::RepeatingCallback<void(base::Optional<base::TimeDelta>,
bool failed_to_mount)>
on_drivefs_unmounted_;
const DriveFsMojoConnectionDelegateFactory
......@@ -820,6 +832,7 @@ void DriveIntegrationService::RemoveDriveMountPoint() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
weak_ptr_factory_.InvalidateWeakPtrs();
remount_when_online_ = false;
if (!mount_point_name_.empty()) {
if (!drivefs_holder_)
......@@ -838,12 +851,19 @@ void DriveIntegrationService::RemoveDriveMountPoint() {
}
void DriveIntegrationService::MaybeRemountFileSystem(
base::Optional<base::TimeDelta> remount_delay) {
base::Optional<base::TimeDelta> remount_delay,
bool failed_to_mount) {
DCHECK_EQ(INITIALIZED, state_);
RemoveDriveMountPoint();
if (!remount_delay) {
if (failed_to_mount && net::NetworkChangeNotifier::IsOffline()) {
logger_->Log(logging::LOG_WARNING,
"DriveFs failed to start, will retry when online.");
remount_when_online_ = true;
return;
}
// If DriveFs didn't specify retry time it's likely unexpected error, e.g.
// crash. Use limited exponential backoff for retry.
++drivefs_consecutive_failures_count_;
......
......@@ -193,8 +193,11 @@ class DriveIntegrationService : public KeyedService,
FileError error);
// Unregisters drive mount point, and if |remount_delay| is specified
// then tries to add it back after that delay.
void MaybeRemountFileSystem(base::Optional<base::TimeDelta> remount_delay);
// then tries to add it back after that delay. If |remount_delay| isn't
// specified, |failed_to_mount| is true and the user is offline, schedules a
// retry when the user is online.
void MaybeRemountFileSystem(base::Optional<base::TimeDelta> remount_delay,
bool failed_to_mount);
// Initializes the object. This function should be called before any
// other functions.
......@@ -251,6 +254,7 @@ class DriveIntegrationService : public KeyedService,
std::unique_ptr<NotificationManager> notification_manager_;
int drivefs_total_failures_count_ = 0;
int drivefs_consecutive_failures_count_ = 0;
bool remount_when_online_ = false;
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment