From aac009b0f5d1a6708233cc643ae38b7faca3a564 Mon Sep 17 00:00:00 2001 From: Shreyas Basarge Date: Thu, 16 Feb 2017 00:47:35 +0000 Subject: [PATCH] Disallow parallel backups If a backup operation is in progress when another backup operation is requested, the new one is skipped. We have to skip the second one because the current BackupTransport interface cannot support parallel backups. Bug: 29010684 Test: Tested manually. Work on GTS test in progress. Change-Id: I6d8f49897bb42781bafed584a4b75b3b971f75eb --- .../server/backup/BackupManagerService.java | 57 +++++++++++++++---- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 9b55c7acab3af..f4f3719531122 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -2655,19 +2655,32 @@ public class BackupManagerService { mStateDir = new File(mBaseStateDir, dirName); mCurrentOpToken = generateToken(); - mCurrentState = BackupState.INITIAL; mFinished = false; - CountDownLatch latch = new CountDownLatch(1); - String[] fullBackups = - mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]); - mFullBackupTask = - new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null, - fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, latch, - mObserver, mMonitor,mUserInitiated); + synchronized (mCurrentOpLock) { + if (isBackupOperationInProgress()) { + if (DEBUG) { + Slog.d(TAG, "Skipping backup since one is already in progress."); + } + mCancelAll = true; + mFullBackupTask = null; + mCurrentState = BackupState.FINAL; + addBackupTrace("Skipped. Backup already in progress."); + } else { + mCurrentState = BackupState.INITIAL; + CountDownLatch latch = new CountDownLatch(1); + String[] fullBackups = + mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]); + mFullBackupTask = + new PerformFullTransportBackupTask(/*fullBackupRestoreObserver*/ null, + fullBackups, /*updateSchedule*/ false, /*runningJob*/ null, + latch, + mObserver, mMonitor, mUserInitiated); - registerTask(); - addBackupTrace("STATE => INITIAL"); + registerTask(); + addBackupTrace("STATE => INITIAL"); + } + } } /** @@ -3050,7 +3063,9 @@ public class BackupManagerService { mWakelock.acquire(); (new Thread(mFullBackupTask, "full-transport-requested")).start(); } else if (mCancelAll) { - mFullBackupTask.unregisterTask(); + if (mFullBackupTask != null) { + mFullBackupTask.unregisterTask(); + } sendBackupFinished(mObserver, BackupManager.ERROR_BACKUP_CANCELLED); } else { mFullBackupTask.unregisterTask(); @@ -3531,6 +3546,18 @@ public class BackupManagerService { } } + private boolean isBackupOperationInProgress() { + synchronized (mCurrentOpLock) { + for (int i = 0; i < mCurrentOperations.size(); i++) { + Operation op = mCurrentOperations.valueAt(i); + if (op.type == OP_TYPE_BACKUP && op.state == OP_PENDING) { + return true; + } + } + } + return false; + } + // ----- Full backup/restore to a file/socket ----- @@ -4513,6 +4540,14 @@ public class BackupManagerService { mCurrentOpToken = generateToken(); mBackupRunnerOpToken = generateToken(); + if (isBackupOperationInProgress()) { + if (DEBUG) { + Slog.d(TAG, "Skipping full backup. A backup is already in progress."); + } + mCancelAll = true; + return; + } + registerTask(); for (String pkg : whichPackages) {