Loading services/core/java/com/android/server/PersistentDataBlockService.java +41 −82 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.FileUtils; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; Loading @@ -45,6 +44,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.security.MessageDigest; Loading Loading @@ -131,13 +131,13 @@ public class PersistentDataBlockService extends SystemService { private static final String FLASH_LOCK_UNLOCKED = "0"; private final Context mContext; private final String mDataBlockFile; private final boolean mIsRunningDSU; private final Object mLock = new Object(); private final CountDownLatch mInitDoneSignal = new CountDownLatch(1); private int mAllowedUid = -1; private long mBlockDeviceSize; private String mDataBlockFile; @GuardedBy("mLock") private boolean mIsWritable = true; Loading @@ -145,8 +145,12 @@ public class PersistentDataBlockService extends SystemService { public PersistentDataBlockService(Context context) { super(context); mContext = context; mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false); if (mIsRunningDSU) { mDataBlockFile = GSI_SANDBOX; } else { mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); } mBlockDeviceSize = -1; // Load lazily } Loading Loading @@ -260,9 +264,13 @@ public class PersistentDataBlockService extends SystemService { private long getBlockDeviceSize() { synchronized (mLock) { if (mBlockDeviceSize == -1) { if (mIsRunningDSU) { mBlockDeviceSize = MAX_DATA_BLOCK_SIZE; } else { mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile); } } } return mBlockDeviceSize; } Loading Loading @@ -290,40 +298,30 @@ public class PersistentDataBlockService extends SystemService { 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 FileChannel getBlockOutputChannel() throws IOException { return new RandomAccessFile(mDataBlockFile, "rw").getChannel(); } private boolean computeAndWriteDigestLocked() { byte[] digest = computeDigestLocked(null); if (digest != null) { DataOutputStream outputStream; FileChannel channel; try { outputStream = new DataOutputStream(getBlockOutputStream()); channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); return false; } try { outputStream.write(digest, 0, DIGEST_SIZE_BYTES); outputStream.flush(); ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES); buf.put(digest); buf.flip(); channel.write(buf); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to write block checksum", e); return false; } finally { IoUtils.closeQuietly(outputStream); } return true; } else { Loading Loading @@ -374,25 +372,18 @@ public class PersistentDataBlockService extends SystemService { } 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 { outputStream.write(data, 0, DIGEST_SIZE_BYTES); outputStream.writeInt(PARTITION_TYPE_MARKER); outputStream.writeInt(0); // data size outputStream.flush(); FileChannel channel = getBlockOutputChannel(); ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES + HEADER_SIZE); buf.put(new byte[DIGEST_SIZE_BYTES]); buf.putInt(PARTITION_TYPE_MARKER); buf.putInt(0); channel.write(buf); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to format block", e); return; } finally { IoUtils.closeQuietly(outputStream); } doSetOemUnlockEnabledLocked(setOemUnlockEnabled); Loading @@ -400,16 +391,9 @@ public class PersistentDataBlockService extends SystemService { } private void doSetOemUnlockEnabledLocked(boolean enabled) { FileOutputStream outputStream; try { outputStream = getBlockOutputStream(); } catch (IOException e) { Slog.e(TAG, "partition not available", e); return; } try { FileChannel channel = outputStream.getChannel(); FileChannel channel = getBlockOutputChannel(); channel.position(getBlockDeviceSize() - 1); Loading @@ -417,13 +401,12 @@ public class PersistentDataBlockService extends SystemService { data.put(enabled ? (byte) 1 : (byte) 0); data.flip(); channel.write(data); outputStream.flush(); channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; } finally { SystemProperties.set(OEM_UNLOCK_PROP, enabled ? "1" : "0"); IoUtils.closeQuietly(outputStream); } } Loading Loading @@ -477,35 +460,32 @@ public class PersistentDataBlockService extends SystemService { return (int) -maxBlockSize; } DataOutputStream outputStream; FileChannel channel; try { outputStream = new DataOutputStream(getBlockOutputStream()); channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); 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(data.length); headerAndData.put(data); headerAndData.flip(); synchronized (mLock) { if (!mIsWritable) { IoUtils.closeQuietly(outputStream); return -1; } try { byte[] checksum = new byte[DIGEST_SIZE_BYTES]; outputStream.write(checksum, 0, DIGEST_SIZE_BYTES); outputStream.write(headerAndData.array()); outputStream.flush(); channel.write(headerAndData); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed writing to the persistent data block", e); return -1; } finally { IoUtils.closeQuietly(outputStream); } if (computeAndWriteDigestLocked()) { Loading Loading @@ -565,17 +545,6 @@ public class PersistentDataBlockService extends SystemService { public void wipe() { 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) { int ret = nativeWipe(mDataBlockFile); Loading Loading @@ -733,28 +702,18 @@ public class PersistentDataBlockService extends SystemService { } 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) { if (!mIsWritable) { IoUtils.closeQuietly(outputStream); return; } try { FileChannel channel = outputStream.getChannel(); FileChannel channel = getBlockOutputChannel(); channel.position(offset); channel.write(dataBuffer); outputStream.flush(); channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; } finally { IoUtils.closeQuietly(outputStream); } computeAndWriteDigestLocked(); Loading Loading
services/core/java/com/android/server/PersistentDataBlockService.java +41 −82 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.FileUtils; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; Loading @@ -45,6 +44,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.security.MessageDigest; Loading Loading @@ -131,13 +131,13 @@ public class PersistentDataBlockService extends SystemService { private static final String FLASH_LOCK_UNLOCKED = "0"; private final Context mContext; private final String mDataBlockFile; private final boolean mIsRunningDSU; private final Object mLock = new Object(); private final CountDownLatch mInitDoneSignal = new CountDownLatch(1); private int mAllowedUid = -1; private long mBlockDeviceSize; private String mDataBlockFile; @GuardedBy("mLock") private boolean mIsWritable = true; Loading @@ -145,8 +145,12 @@ public class PersistentDataBlockService extends SystemService { public PersistentDataBlockService(Context context) { super(context); mContext = context; mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); mIsRunningDSU = SystemProperties.getBoolean(GSI_RUNNING_PROP, false); if (mIsRunningDSU) { mDataBlockFile = GSI_SANDBOX; } else { mDataBlockFile = SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP); } mBlockDeviceSize = -1; // Load lazily } Loading Loading @@ -260,9 +264,13 @@ public class PersistentDataBlockService extends SystemService { private long getBlockDeviceSize() { synchronized (mLock) { if (mBlockDeviceSize == -1) { if (mIsRunningDSU) { mBlockDeviceSize = MAX_DATA_BLOCK_SIZE; } else { mBlockDeviceSize = nativeGetBlockDeviceSize(mDataBlockFile); } } } return mBlockDeviceSize; } Loading Loading @@ -290,40 +298,30 @@ public class PersistentDataBlockService extends SystemService { 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 FileChannel getBlockOutputChannel() throws IOException { return new RandomAccessFile(mDataBlockFile, "rw").getChannel(); } private boolean computeAndWriteDigestLocked() { byte[] digest = computeDigestLocked(null); if (digest != null) { DataOutputStream outputStream; FileChannel channel; try { outputStream = new DataOutputStream(getBlockOutputStream()); channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); return false; } try { outputStream.write(digest, 0, DIGEST_SIZE_BYTES); outputStream.flush(); ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES); buf.put(digest); buf.flip(); channel.write(buf); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to write block checksum", e); return false; } finally { IoUtils.closeQuietly(outputStream); } return true; } else { Loading Loading @@ -374,25 +372,18 @@ public class PersistentDataBlockService extends SystemService { } 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 { outputStream.write(data, 0, DIGEST_SIZE_BYTES); outputStream.writeInt(PARTITION_TYPE_MARKER); outputStream.writeInt(0); // data size outputStream.flush(); FileChannel channel = getBlockOutputChannel(); ByteBuffer buf = ByteBuffer.allocate(DIGEST_SIZE_BYTES + HEADER_SIZE); buf.put(new byte[DIGEST_SIZE_BYTES]); buf.putInt(PARTITION_TYPE_MARKER); buf.putInt(0); channel.write(buf); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed to format block", e); return; } finally { IoUtils.closeQuietly(outputStream); } doSetOemUnlockEnabledLocked(setOemUnlockEnabled); Loading @@ -400,16 +391,9 @@ public class PersistentDataBlockService extends SystemService { } private void doSetOemUnlockEnabledLocked(boolean enabled) { FileOutputStream outputStream; try { outputStream = getBlockOutputStream(); } catch (IOException e) { Slog.e(TAG, "partition not available", e); return; } try { FileChannel channel = outputStream.getChannel(); FileChannel channel = getBlockOutputChannel(); channel.position(getBlockDeviceSize() - 1); Loading @@ -417,13 +401,12 @@ public class PersistentDataBlockService extends SystemService { data.put(enabled ? (byte) 1 : (byte) 0); data.flip(); channel.write(data); outputStream.flush(); channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; } finally { SystemProperties.set(OEM_UNLOCK_PROP, enabled ? "1" : "0"); IoUtils.closeQuietly(outputStream); } } Loading Loading @@ -477,35 +460,32 @@ public class PersistentDataBlockService extends SystemService { return (int) -maxBlockSize; } DataOutputStream outputStream; FileChannel channel; try { outputStream = new DataOutputStream(getBlockOutputStream()); channel = getBlockOutputChannel(); } catch (IOException e) { Slog.e(TAG, "partition not available?", e); 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(data.length); headerAndData.put(data); headerAndData.flip(); synchronized (mLock) { if (!mIsWritable) { IoUtils.closeQuietly(outputStream); return -1; } try { byte[] checksum = new byte[DIGEST_SIZE_BYTES]; outputStream.write(checksum, 0, DIGEST_SIZE_BYTES); outputStream.write(headerAndData.array()); outputStream.flush(); channel.write(headerAndData); channel.force(true); } catch (IOException e) { Slog.e(TAG, "failed writing to the persistent data block", e); return -1; } finally { IoUtils.closeQuietly(outputStream); } if (computeAndWriteDigestLocked()) { Loading Loading @@ -565,17 +545,6 @@ public class PersistentDataBlockService extends SystemService { public void wipe() { 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) { int ret = nativeWipe(mDataBlockFile); Loading Loading @@ -733,28 +702,18 @@ public class PersistentDataBlockService extends SystemService { } 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) { if (!mIsWritable) { IoUtils.closeQuietly(outputStream); return; } try { FileChannel channel = outputStream.getChannel(); FileChannel channel = getBlockOutputChannel(); channel.position(offset); channel.write(dataBuffer); outputStream.flush(); channel.force(true); } catch (IOException e) { Slog.e(TAG, "unable to access persistent partition", e); return; } finally { IoUtils.closeQuietly(outputStream); } computeAndWriteDigestLocked(); Loading