Merge changes from topic "cow_pdb"

* changes:
  Support copy-on-write persistent data block when running a DSU
  Support PersistentDataBlockService in DSU
This commit is contained in:
Howard Chen
2021-03-17 02:07:03 +00:00
committed by Gerrit Code Review
2 changed files with 44 additions and 16 deletions

View File

@@ -23,6 +23,7 @@ import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Binder; import android.os.Binder;
import android.os.FileUtils;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.SystemProperties; import android.os.SystemProperties;
@@ -103,6 +104,9 @@ import java.util.concurrent.TimeUnit;
public class PersistentDataBlockService extends SystemService { public class PersistentDataBlockService extends SystemService {
private static final String TAG = PersistentDataBlockService.class.getSimpleName(); private static final String TAG = PersistentDataBlockService.class.getSimpleName();
private static final String GSI_SANDBOX = "/data/gsi_persistent_data";
private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";
private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst"; private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
private static final int HEADER_SIZE = 8; private static final int HEADER_SIZE = 8;
// Magic number to mark block device as adhering to the format consumed by this service // Magic number to mark block device as adhering to the format consumed by this service
@@ -127,12 +131,13 @@ public class PersistentDataBlockService extends SystemService {
private static final String FLASH_LOCK_UNLOCKED = "0"; private static final String FLASH_LOCK_UNLOCKED = "0";
private final Context mContext; private final Context mContext;
private final String mDataBlockFile; private final boolean mIsRunningDSU;
private final Object mLock = new Object(); private final Object mLock = new Object();
private final CountDownLatch mInitDoneSignal = new CountDownLatch(1); private final CountDownLatch mInitDoneSignal = new CountDownLatch(1);
private int mAllowedUid = -1; private int mAllowedUid = -1;
private long mBlockDeviceSize; private long mBlockDeviceSize;
private String mDataBlockFile;
@GuardedBy("mLock") @GuardedBy("mLock")
private boolean mIsWritable = true; private boolean mIsWritable = true;
@@ -141,6 +146,7 @@ public class PersistentDataBlockService extends SystemService {
super(context); super(context);
mContext = context; mContext = context;
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false);
mBlockDeviceSize = -1; // Load lazily mBlockDeviceSize = -1; // Load lazily
} }
@@ -284,14 +290,28 @@ public class PersistentDataBlockService extends SystemService {
return true; return true;
} }
private FileOutputStream getBlockOutputStream() throws IOException {
if (!mIsRunningDSU) {
return new FileOutputStream(new File(mDataBlockFile));
} else {
File sandbox = new File(GSI_SANDBOX);
File realpdb = new File(SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP));
if (!sandbox.exists()) {
FileUtils.copy(realpdb, sandbox);
mDataBlockFile = GSI_SANDBOX;
}
Slog.i(TAG, "PersistentDataBlock copy-on-write");
return new FileOutputStream(sandbox);
}
}
private boolean computeAndWriteDigestLocked() { private boolean computeAndWriteDigestLocked() {
byte[] digest = computeDigestLocked(null); byte[] digest = computeDigestLocked(null);
if (digest != null) { if (digest != null) {
DataOutputStream outputStream; DataOutputStream outputStream;
try { try {
outputStream = new DataOutputStream( outputStream = new DataOutputStream(getBlockOutputStream());
new FileOutputStream(new File(mDataBlockFile))); } catch (IOException e) {
} catch (FileNotFoundException e) {
Slog.e(TAG, "partition not available?", e); Slog.e(TAG, "partition not available?", e);
return false; return false;
} }
@@ -356,8 +376,8 @@ public class PersistentDataBlockService extends SystemService {
private void formatPartitionLocked(boolean setOemUnlockEnabled) { private void formatPartitionLocked(boolean setOemUnlockEnabled) {
DataOutputStream outputStream; DataOutputStream outputStream;
try { try {
outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile))); outputStream = new DataOutputStream(getBlockOutputStream());
} catch (FileNotFoundException e) { } catch (IOException e) {
Slog.e(TAG, "partition not available?", e); Slog.e(TAG, "partition not available?", e);
return; return;
} }
@@ -382,8 +402,8 @@ public class PersistentDataBlockService extends SystemService {
private void doSetOemUnlockEnabledLocked(boolean enabled) { private void doSetOemUnlockEnabledLocked(boolean enabled) {
FileOutputStream outputStream; FileOutputStream outputStream;
try { try {
outputStream = new FileOutputStream(new File(mDataBlockFile)); outputStream = getBlockOutputStream();
} catch (FileNotFoundException e) { } catch (IOException e) {
Slog.e(TAG, "partition not available", e); Slog.e(TAG, "partition not available", e);
return; return;
} }
@@ -459,8 +479,8 @@ public class PersistentDataBlockService extends SystemService {
DataOutputStream outputStream; DataOutputStream outputStream;
try { try {
outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile))); outputStream = new DataOutputStream(getBlockOutputStream());
} catch (FileNotFoundException e) { } catch (IOException e) {
Slog.e(TAG, "partition not available?", e); Slog.e(TAG, "partition not available?", e);
return -1; return -1;
} }
@@ -545,6 +565,17 @@ public class PersistentDataBlockService extends SystemService {
public void wipe() { public void wipe() {
enforceOemUnlockWritePermission(); enforceOemUnlockWritePermission();
if (mIsRunningDSU) {
File sandbox = new File(GSI_SANDBOX);
if (sandbox.exists()) {
if (sandbox.delete()) {
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
} else {
Slog.e(TAG, "Failed to wipe sandbox persistent data block");
}
}
return;
}
synchronized (mLock) { synchronized (mLock) {
int ret = nativeWipe(mDataBlockFile); int ret = nativeWipe(mDataBlockFile);
@@ -704,8 +735,8 @@ public class PersistentDataBlockService extends SystemService {
private void writeDataBuffer(long offset, ByteBuffer dataBuffer) { private void writeDataBuffer(long offset, ByteBuffer dataBuffer) {
FileOutputStream outputStream; FileOutputStream outputStream;
try { try {
outputStream = new FileOutputStream(new File(mDataBlockFile)); outputStream = getBlockOutputStream();
} catch (FileNotFoundException e) { } catch (IOException e) {
Slog.e(TAG, "partition not available", e); Slog.e(TAG, "partition not available", e);
return; return;
} }

View File

@@ -332,8 +332,6 @@ public final class SystemServer {
private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file"; private static final String UNCRYPT_PACKAGE_FILE = "/cache/recovery/uncrypt_file";
private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map"; private static final String BLOCK_MAP_FILE = "/cache/recovery/block.map";
private static final String GSI_RUNNING_PROP = "ro.gsid.image_running";
// maximum number of binder threads used for system_server // maximum number of binder threads used for system_server
// will be higher than the system default // will be higher than the system default
private static final int sMaxBinderThreads = 31; private static final int sMaxBinderThreads = 31;
@@ -1443,8 +1441,7 @@ public final class SystemServer {
t.traceEnd(); t.traceEnd();
final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals(""); final boolean hasPdb = !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
final boolean hasGsi = SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0; if (hasPdb) {
if (hasPdb && !hasGsi) {
t.traceBegin("StartPersistentDataBlock"); t.traceBegin("StartPersistentDataBlock");
mSystemServiceManager.startService(PersistentDataBlockService.class); mSystemServiceManager.startService(PersistentDataBlockService.class);
t.traceEnd(); t.traceEnd();