Skip to content

Commit 336a649

Browse files
author
Christopher Tate
committed
Prevent concurrent backup operations
We've seen cases (bug 5417779) where the transport kicked off an immediate backup operation but then was perfectly content to allow the periodic timer to start *another* pass concurrently while the first was still in progress. This wound up with the backup manager getting mightily confused and leaking wakelock acquisitions, which is Very Bad(tm). This patch adds a little bookkeeping so that the backup manager is aware of backups in flight, and refuses to kick off a new one until the ongoing one has finished. Change-Id: If12b54f4db3effc8af36d31c58d8f9b415ddc01e
1 parent 63d8b0c commit 336a649

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

services/java/com/android/server/BackupManagerService.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ public String toString() {
228228
// completed.
229229
final Object mAgentConnectLock = new Object();
230230
IBackupAgent mConnectedAgent;
231+
volatile boolean mBackupRunning;
231232
volatile boolean mConnecting;
232233
volatile long mLastBackupPass;
233234
volatile long mNextBackupPass;
@@ -434,6 +435,9 @@ public void handleMessage(Message msg) {
434435
IBackupTransport transport = getTransport(mCurrentTransport);
435436
if (transport == null) {
436437
Slog.v(TAG, "Backup requested but no transport available");
438+
synchronized (mQueueLock) {
439+
mBackupRunning = false;
440+
}
437441
mWakelock.release();
438442
break;
439443
}
@@ -470,6 +474,9 @@ public void handleMessage(Message msg) {
470474
sendMessage(pbtMessage);
471475
} else {
472476
Slog.v(TAG, "Backup requested but nothing pending");
477+
synchronized (mQueueLock) {
478+
mBackupRunning = false;
479+
}
473480
mWakelock.release();
474481
}
475482
break;
@@ -804,14 +811,19 @@ public void onReceive(Context context, Intent intent) {
804811
// Don't run backups now if we're disabled or not yet
805812
// fully set up.
806813
if (mEnabled && mProvisioned) {
807-
if (DEBUG) Slog.v(TAG, "Running a backup pass");
814+
if (!mBackupRunning) {
815+
if (DEBUG) Slog.v(TAG, "Running a backup pass");
808816

809-
// Acquire the wakelock and pass it to the backup thread. it will
810-
// be released once backup concludes.
811-
mWakelock.acquire();
817+
// Acquire the wakelock and pass it to the backup thread. it will
818+
// be released once backup concludes.
819+
mBackupRunning = true;
820+
mWakelock.acquire();
812821

813-
Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
814-
mBackupHandler.sendMessage(msg);
822+
Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
823+
mBackupHandler.sendMessage(msg);
824+
} else {
825+
Slog.i(TAG, "Backup time but one already running");
826+
}
815827
} else {
816828
Slog.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned);
817829
}
@@ -1948,9 +1960,14 @@ void finalizeBackup() {
19481960
writeRestoreTokens();
19491961
}
19501962

1951-
// Set up the next backup pass
1952-
if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
1953-
backupNow();
1963+
// Set up the next backup pass - at this point we can set mBackupRunning
1964+
// to false to allow another pass to fire, because we're done with the
1965+
// state machine sequence and the wakelock is refcounted.
1966+
synchronized (mQueueLock) {
1967+
mBackupRunning = false;
1968+
if (mStatus == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
1969+
backupNow();
1970+
}
19541971
}
19551972

19561973
// Only once we're entirely finished do we release the wakelock
@@ -2400,8 +2417,8 @@ public void run() {
24002417
mLatchObject.notifyAll();
24012418
}
24022419
sendEndBackup();
2403-
mWakelock.release();
24042420
if (DEBUG) Slog.d(TAG, "Full backup pass complete.");
2421+
mWakelock.release();
24052422
}
24062423
}
24072424

@@ -2908,8 +2925,8 @@ public void run() {
29082925
mLatchObject.notifyAll();
29092926
}
29102927
sendEndRestore();
2911-
mWakelock.release();
29122928
Slog.d(TAG, "Full restore pass complete.");
2929+
mWakelock.release();
29132930
}
29142931
}
29152932

@@ -5630,7 +5647,8 @@ private void dumpInternal(PrintWriter pw) {
56305647
+ " / " + (!mProvisioned ? "not " : "") + "provisioned / "
56315648
+ (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
56325649
pw.println("Auto-restore is " + (mAutoRestore ? "enabled" : "disabled"));
5633-
pw.println("Last backup pass: " + mLastBackupPass
5650+
if (mBackupRunning) pw.println("Backup currently running");
5651+
pw.println("Last backup pass started: " + mLastBackupPass
56345652
+ " (now = " + System.currentTimeMillis() + ')');
56355653
pw.println(" next scheduled: " + mNextBackupPass);
56365654

0 commit comments

Comments
 (0)