Merge "Replace copy-on-write PDB with an empty one"
This commit is contained in:
@@ -23,7 +23,6 @@ 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;
|
||||||
@@ -45,6 +44,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
@@ -131,13 +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 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;
|
||||||
@@ -145,8 +145,12 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
public PersistentDataBlockService(Context context) {
|
public PersistentDataBlockService(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
|
|
||||||
mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false);
|
mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false);
|
||||||
|
if (mIsRunningDSU) {
|
||||||
|
mDataBlockFile = GSI_SANDBOX;
|
||||||
|
} else {
|
||||||
|
mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP);
|
||||||
|
}
|
||||||
mBlockDeviceSize = -1; // Load lazily
|
mBlockDeviceSize = -1; // Load lazily
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +264,11 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
private long getBlockDeviceSize() {
|
private long getBlockDeviceSize() {
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (mBlockDeviceSize == -1) {
|
if (mBlockDeviceSize == -1) {
|
||||||
mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile);
|
if (mIsRunningDSU) {
|
||||||
|
mBlockDeviceSize = MAX_DATA_BLOCK_SIZE;
|
||||||
|
} else {
|
||||||
|
mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,40 +298,30 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FileOutputStream getBlockOutputStream() throws IOException {
|
private FileChannel getBlockOutputChannel() throws IOException {
|
||||||
if (!mIsRunningDSU) {
|
return new RandomAccessFile(mDataBlockFile, "rw").getChannel();
|
||||||
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;
|
FileChannel channel;
|
||||||
try {
|
try {
|
||||||
outputStream = new DataOutputStream(getBlockOutputStream());
|
channel = getBlockOutputChannel();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available?", e);
|
Slog.e(TAG, "partition not available?", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
outputStream.write(digest, 0, DIGEST_SIZE_BYTES);
|
ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES);
|
||||||
outputStream.flush();
|
buf.put(digest);
|
||||||
|
buf.flip();
|
||||||
|
channel.write(buf);
|
||||||
|
channel.force(true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "failed to write block checksum", e);
|
Slog.e(TAG, "failed to write block checksum", e);
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -374,25 +372,18 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void formatPartitionLocked(boolean setOemUnlockEnabled) {
|
private void formatPartitionLocked(boolean setOemUnlockEnabled) {
|
||||||
DataOutputStream outputStream;
|
|
||||||
try {
|
|
||||||
outputStream = new DataOutputStream(getBlockOutputStream());
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "partition not available?", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] data = new byte[DIGEST_SIZE_BYTES];
|
|
||||||
try {
|
try {
|
||||||
outputStream.write(data, 0, DIGEST_SIZE_BYTES);
|
FileChannel channel = getBlockOutputChannel();
|
||||||
outputStream.writeInt(PARTITION_TYPE_MARKER);
|
ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES + HEADER_SIZE);
|
||||||
outputStream.writeInt(0); // data size
|
buf.put(new byte[DIGEST_SIZE_BYTES]);
|
||||||
outputStream.flush();
|
buf.putInt(PARTITION_TYPE_MARKER);
|
||||||
|
buf.putInt(0);
|
||||||
|
channel.write(buf);
|
||||||
|
channel.force(true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "failed to format block", e);
|
Slog.e(TAG, "failed to format block", e);
|
||||||
return;
|
return;
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
doSetOemUnlockEnabledLocked(setOemUnlockEnabled);
|
doSetOemUnlockEnabledLocked(setOemUnlockEnabled);
|
||||||
@@ -400,16 +391,9 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doSetOemUnlockEnabledLocked(boolean enabled) {
|
private void doSetOemUnlockEnabledLocked(boolean enabled) {
|
||||||
FileOutputStream outputStream;
|
|
||||||
try {
|
|
||||||
outputStream = getBlockOutputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "partition not available", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FileChannel channel = outputStream.getChannel();
|
FileChannel channel = getBlockOutputChannel();
|
||||||
|
|
||||||
channel.position(getBlockDeviceSize() - 1);
|
channel.position(getBlockDeviceSize() - 1);
|
||||||
|
|
||||||
@@ -417,13 +401,12 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
data.put(enabled ? (byte) 1 : (byte) 0);
|
data.put(enabled ? (byte) 1 : (byte) 0);
|
||||||
data.flip();
|
data.flip();
|
||||||
channel.write(data);
|
channel.write(data);
|
||||||
outputStream.flush();
|
channel.force(true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "unable to access persistent partition", e);
|
Slog.e(TAG, "unable to access persistent partition", e);
|
||||||
return;
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
SystemProperties.set(OEM_UNLOCK_PROP, enabled ? "1" : "0");
|
SystemProperties.set(OEM_UNLOCK_PROP, enabled ? "1" : "0");
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,35 +460,32 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
return (int) -maxBlockSize;
|
return (int) -maxBlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataOutputStream outputStream;
|
FileChannel channel;
|
||||||
try {
|
try {
|
||||||
outputStream = new DataOutputStream(getBlockOutputStream());
|
channel = getBlockOutputChannel();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "partition not available?", e);
|
Slog.e(TAG, "partition not available?", e);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer headerAndData = ByteBuffer.allocate(data.length + HEADER_SIZE);
|
ByteBuffer headerAndData = ByteBuffer.allocate(
|
||||||
|
data.length + HEADER_SIZE + DIGEST_SIZE_BYTES);
|
||||||
|
headerAndData.put(new byte[DIGEST_SIZE_BYTES]);
|
||||||
headerAndData.putInt(PARTITION_TYPE_MARKER);
|
headerAndData.putInt(PARTITION_TYPE_MARKER);
|
||||||
headerAndData.putInt(data.length);
|
headerAndData.putInt(data.length);
|
||||||
headerAndData.put(data);
|
headerAndData.put(data);
|
||||||
|
headerAndData.flip();
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!mIsWritable) {
|
if (!mIsWritable) {
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] checksum = new byte[DIGEST_SIZE_BYTES];
|
channel.write(headerAndData);
|
||||||
outputStream.write(checksum, 0, DIGEST_SIZE_BYTES);
|
channel.force(true);
|
||||||
outputStream.write(headerAndData.array());
|
|
||||||
outputStream.flush();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "failed writing to the persistent data block", e);
|
Slog.e(TAG, "failed writing to the persistent data block", e);
|
||||||
return -1;
|
return -1;
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (computeAndWriteDigestLocked()) {
|
if (computeAndWriteDigestLocked()) {
|
||||||
@@ -565,17 +545,6 @@ 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);
|
||||||
|
|
||||||
@@ -733,28 +702,18 @@ public class PersistentDataBlockService extends SystemService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeDataBuffer(long offset, ByteBuffer dataBuffer) {
|
private void writeDataBuffer(long offset, ByteBuffer dataBuffer) {
|
||||||
FileOutputStream outputStream;
|
|
||||||
try {
|
|
||||||
outputStream = getBlockOutputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Slog.e(TAG, "partition not available", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (!mIsWritable) {
|
if (!mIsWritable) {
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
FileChannel channel = outputStream.getChannel();
|
FileChannel channel = getBlockOutputChannel();
|
||||||
channel.position(offset);
|
channel.position(offset);
|
||||||
channel.write(dataBuffer);
|
channel.write(dataBuffer);
|
||||||
outputStream.flush();
|
channel.force(true);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Slog.e(TAG, "unable to access persistent partition", e);
|
Slog.e(TAG, "unable to access persistent partition", e);
|
||||||
return;
|
return;
|
||||||
} finally {
|
|
||||||
IoUtils.closeQuietly(outputStream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
computeAndWriteDigestLocked();
|
computeAndWriteDigestLocked();
|
||||||
|
|||||||
Reference in New Issue
Block a user