Merge changes from topic "revert-16575908-dont_abandon_child_qt_dev-VVMFNIYZZO" into qt-dev

* changes:
  [RESTRICT AUTOMERGE] Revert "Revert "Revert "[pm] remove old stage dirs on low storage"""
  [RESTRICT AUTOMERGE] Revert "Don't abandon child sessions (1/n)"
  [RESTRICT AUTOMERGE] Revert "Fix NPE"
This commit is contained in:
Songchun Fan
2022-06-28 20:37:57 +00:00
committed by Android (Google) Code Review
3 changed files with 7 additions and 72 deletions

View File

@@ -129,9 +129,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
private static final long MAX_ACTIVE_SESSIONS = 1024; private static final long MAX_ACTIVE_SESSIONS = 1024;
/** Upper bound on number of historical sessions for a UID */ /** Upper bound on number of historical sessions for a UID */
private static final long MAX_HISTORICAL_SESSIONS = 1048576; private static final long MAX_HISTORICAL_SESSIONS = 1048576;
/** Destroy sessions older than this on storage free request */
private static final long MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS = 8 * DateUtils.HOUR_IN_MILLIS;
private final Context mContext; private final Context mContext;
private final PackageManagerService mPm; private final PackageManagerService mPm;
@@ -278,28 +275,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
@GuardedBy("mSessions") @GuardedBy("mSessions")
private void reconcileStagesLocked(String volumeUuid) { private void reconcileStagesLocked(String volumeUuid) {
final ArraySet<File> unclaimedStages = getStagingDirsOnVolume(volumeUuid); final File stagingDir = getTmpSessionDir(volumeUuid);
final ArraySet<File> unclaimedStages = newArraySet(
stagingDir.listFiles(sStageFilter));
// Ignore stages claimed by active sessions // Ignore stages claimed by active sessions
for (int i = 0; i < mSessions.size(); i++) { for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i); final PackageInstallerSession session = mSessions.valueAt(i);
unclaimedStages.remove(session.stageDir); unclaimedStages.remove(session.stageDir);
} }
removeStagingDirs(unclaimedStages);
}
private ArraySet<File> getStagingDirsOnVolume(String volumeUuid) {
final File stagingDir = getTmpSessionDir(volumeUuid);
final ArraySet<File> stagingDirs = newArraySet(stagingDir.listFiles(sStageFilter));
// We also need to clean up orphaned staging directory for staged sessions
final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid);
stagingDirs.addAll(newArraySet(stagedSessionStagingDir.listFiles()));
return stagingDirs;
}
private void removeStagingDirs(ArraySet<File> stagingDirsToRemove) {
// Clean up orphaned staging directories // Clean up orphaned staging directories
for (File stage : stagingDirsToRemove) { for (File stage : unclaimedStages) {
Slog.w(TAG, "Deleting orphan stage " + stage); Slog.w(TAG, "Deleting orphan stage " + stage);
synchronized (mPm.mInstallLock) { synchronized (mPm.mInstallLock) {
mPm.removeCodePathLI(stage); mPm.removeCodePathLI(stage);
@@ -313,42 +300,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
} }
} }
/**
* Called to free up some storage space from obsolete installation files
*/
public void freeStageDirs(String volumeUuid) {
final ArraySet<File> unclaimedStagingDirsOnVolume = getStagingDirsOnVolume(volumeUuid);
final long currentTimeMillis = System.currentTimeMillis();
synchronized (mSessions) {
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
if (!unclaimedStagingDirsOnVolume.contains(session.stageDir)) {
// Only handles sessions stored on the target volume
continue;
}
final long age = currentTimeMillis - session.createdMillis;
if (age >= MAX_SESSION_AGE_ON_LOW_STORAGE_MILLIS) {
// Aggressively close old sessions because we are running low on storage
// Their staging dirs will be removed too
PackageInstallerSession root = !session.hasParentSessionId()
? session : mSessions.get(session.getParentSessionId());
if (root == null) {
Slog.e(TAG, "freeStageDirs: found an orphaned session: "
+ session.sessionId + " parent=" + session.getParentSessionId());
} else if (!root.isDestroyed() &&
(!root.isStaged() || (root.isStaged() && root.isStagedSessionReady())))
{
root.abandon();
}
} else {
// Session is new enough, so it deserves to be kept even on low storage
unclaimedStagingDirsOnVolume.remove(session.stageDir);
}
}
}
removeStagingDirs(unclaimedStagingDirsOnVolume);
}
public static boolean isStageName(String name) { public static boolean isStageName(String name) {
final boolean isFile = name.startsWith("vmdl") && name.endsWith(".tmp"); final boolean isFile = name.startsWith("vmdl") && name.endsWith(".tmp");
final boolean isContainer = name.startsWith("smdl") && name.endsWith(".tmp"); final boolean isContainer = name.startsWith("smdl") && name.endsWith(".tmp");

View File

@@ -2088,7 +2088,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
+ mParentSessionId + " and may not be abandoned directly."); + mParentSessionId + " and may not be abandoned directly.");
} }
synchronized (mLock) { synchronized (mLock) {
assertCallerIsOwnerOrRootOrSystemLocked(); assertCallerIsOwnerOrRootLocked();
if (isStagedAndInTerminalState()) { if (isStagedAndInTerminalState()) {
// We keep the session in the database if it's in a finalized state. It will be // We keep the session in the database if it's in a finalized state. It will be
// removed by PackageInstallerService when the last update time is old enough. // removed by PackageInstallerService when the last update time is old enough.
@@ -2115,20 +2116,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
} }
/**
* Check if the caller is the owner of this session. Otherwise throw a
* {@link SecurityException}.
*/
@GuardedBy("mLock")
private void assertCallerIsOwnerOrRootOrSystemLocked() {
final int callingUid = Binder.getCallingUid();
if (callingUid != Process.ROOT_UID && callingUid != mInstallerUid
&& callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Session does not belong to uid " + callingUid);
}
}
@Override @Override
public boolean isMultiPackage() { public boolean isMultiPackage() {
return params.isMultiPackage; return params.isMultiPackage;

View File

@@ -4875,9 +4875,6 @@ public class PackageManagerService extends IPackageManager.Stub
InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) { InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
return; return;
} }
// 12. Clear temp install session files
mInstallerService.freeStageDirs(volumeUuid);
} else { } else {
try { try {
mInstaller.freeCache(volumeUuid, bytes, 0, 0); mInstaller.freeCache(volumeUuid, bytes, 0, 0);