From 9756d75ec28844f5ca30fda786a117c1a0ee88da Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 14 May 2015 21:07:42 -0700 Subject: [PATCH 1/2] Initial pass at storage benchmarks. Offer an interface for Settings to invoke benchmarks on various attached volumes. Bug: 21172095 Change-Id: I847ddc87c58285457d1324be87f70ce10507accb --- .../android/os/storage/IMountService.java | 27 +++++++++++++++++++ .../android/os/storage/StorageManager.java | 9 +++++++ .../java/com/android/server/MountService.java | 22 +++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 2b058a884f754..9c576d4005c4d 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -1004,6 +1004,22 @@ public interface IMountService extends IInterface { } } + @Override + public long benchmark(String volId) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(volId); + mRemote.transact(Stub.TRANSACTION_benchmark, _data, _reply, 0); + _reply.readException(); + return _reply.readLong(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } + @Override public void partitionPublic(String diskId) throws RemoteException { Parcel _data = Parcel.obtain(); @@ -1257,6 +1273,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57; static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58; + static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1726,6 +1744,14 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_benchmark: { + data.enforceInterface(DESCRIPTOR); + String volId = data.readString(); + long res = benchmark(volId); + reply.writeNoException(); + reply.writeLong(res); + return true; + } case TRANSACTION_partitionPublic: { data.enforceInterface(DESCRIPTOR); String diskId = data.readString(); @@ -2088,6 +2114,7 @@ public interface IMountService extends IInterface { public void mount(String volId) throws RemoteException; public void unmount(String volId) throws RemoteException; public void format(String volId) throws RemoteException; + public long benchmark(String volId) throws RemoteException; public void partitionPublic(String diskId) throws RemoteException; public void partitionPrivate(String diskId) throws RemoteException; diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 8c0bbbf11a765..3a6ff28227ba1 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -640,6 +640,15 @@ public class StorageManager { } } + /** {@hide} */ + public long benchmark(String volId) { + try { + return mMountService.benchmark(volId); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** {@hide} */ public void partitionPublic(String diskId) { try { diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 003d0e7eb8f9c..7cd5bff789466 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -39,6 +39,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Environment; import android.os.Environment.UserEnvironment; +import android.os.DropBoxManager; import android.os.FileUtils; import android.os.Handler; import android.os.HandlerThread; @@ -174,6 +175,7 @@ class MountService extends IMountService.Stub private static final boolean WATCHDOG_ENABLE = false; private static final String TAG = "MountService"; + private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark"; private static final String VOLD_TAG = "VoldConnector"; @@ -233,6 +235,7 @@ class MountService extends IMountService.Stub public static final int VOLUME_DESTROYED = 659; public static final int MOVE_STATUS = 660; + public static final int BENCHMARK_RESULT = 661; /* * 700 series - fstrim @@ -927,6 +930,12 @@ class MountService extends IMountService.Stub break; } + case VoldResponseCode.BENCHMARK_RESULT: { + final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class); + dropBox.addText(TAG_STORAGE_BENCHMARK, raw); + break; + } + case VoldResponseCode.FstrimCompleted: { EventLogTags.writeFstrimFinish(SystemClock.elapsedRealtime()); break; @@ -1405,6 +1414,19 @@ class MountService extends IMountService.Stub } } + @Override + public long benchmark(String volId) { + enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS); + waitForReady(); + + try { + final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId); + return Long.parseLong(res.getMessage()); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + @Override public void partitionPublic(String diskId) { enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS); From 4c099d0c49c8366efd3c26854465b3ceef49b627 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Fri, 15 May 2015 13:45:00 -0700 Subject: [PATCH 2/2] Command to change force adoptable state. Since user builds can't setprop, add an explicit "sm" verb to change the force adoptable state. Bug: 21191915 Change-Id: I719d9b18c1a98c97442a5ddb1cc5512e8e4d3d3f --- cmds/sm/src/com/android/commands/sm/Sm.java | 12 ++++++-- .../android/os/storage/IMountService.java | 26 +++++++++++++++++ .../android/os/storage/StorageManager.java | 3 ++ packages/Shell/AndroidManifest.xml | 2 ++ .../java/com/android/server/MountService.java | 29 +++++++++++++++++-- 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 4a8cf0818edb2..0dad4dcec892f 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -71,6 +71,8 @@ public final class Sm { runHasAdoptable(); } else if ("get-primary-storage-uuid".equals(op)) { runGetPrimaryStorageUuid(); + } else if ("set-force-adoptable".equals(op)) { + runSetForceAdoptable(); } else if ("partition".equals(op)) { runPartition(); } else if ("mount".equals(op)) { @@ -116,14 +118,19 @@ public final class Sm { } public void runHasAdoptable() { - System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false) - || SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)); + System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false)); } public void runGetPrimaryStorageUuid() throws RemoteException { System.out.println(mSm.getPrimaryStorageUuid()); } + public void runSetForceAdoptable() throws RemoteException { + final boolean forceAdoptable = Boolean.parseBoolean(nextArg()); + mSm.setDebugFlags(forceAdoptable ? StorageManager.DEBUG_FORCE_ADOPTABLE : 0, + StorageManager.DEBUG_FORCE_ADOPTABLE); + } + public void runPartition() throws RemoteException { final String diskId = nextArg(); final String type = nextArg(); @@ -177,6 +184,7 @@ public final class Sm { System.err.println(" sm list-volumes [public|private|emulated|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); + System.err.println(" sm set-force-adoptable [true|false]"); System.err.println(""); System.err.println(" sm partition DISK [public|private|mixed] [ratio]"); System.err.println(" sm mount VOLUME"); diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 9c576d4005c4d..e55ae99280426 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -1128,6 +1128,22 @@ public interface IMountService extends IInterface { } } + @Override + public void setDebugFlags(int _flags, int _mask) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeInt(_flags); + _data.writeInt(_mask); + mRemote.transact(Stub.TRANSACTION_setDebugFlags, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } + @Override public String getPrimaryStorageUuid() throws RemoteException { Parcel _data = Parcel.obtain(); @@ -1274,6 +1290,7 @@ public interface IMountService extends IInterface { static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58; static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59; + static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60; /** * Cast an IBinder object into an IMountService interface, generating a @@ -1804,6 +1821,14 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_setDebugFlags: { + data.enforceInterface(DESCRIPTOR); + int _flags = data.readInt(); + int _mask = data.readInt(); + setDebugFlags(_flags, _mask); + reply.writeNoException(); + return true; + } case TRANSACTION_getPrimaryStorageUuid: { data.enforceInterface(DESCRIPTOR); String volumeUuid = getPrimaryStorageUuid(); @@ -2124,6 +2149,7 @@ public interface IMountService extends IInterface { public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException; public void forgetVolume(String fsUuid) throws RemoteException; public void forgetAllVolumes() throws RemoteException; + public void setDebugFlags(int flags, int mask) throws RemoteException; public String getPrimaryStorageUuid() throws RemoteException; public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 3a6ff28227ba1..8ff56f8cc1397 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -82,6 +82,9 @@ public class StorageManager { /** {@hide} */ public static final String UUID_PRIMARY_PHYSICAL = "primary_physical"; + /** {@hide} */ + public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0; + private final Context mContext; private final ContentResolver mResolver; diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index dda9358a89403..fd0ba73c27b23 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -95,6 +95,8 @@ + + mRecords = new ArrayMap<>(); @GuardedBy("mLock") private String mPrimaryStorageUuid; + @GuardedBy("mLock") + private boolean mForceAdoptable; /** Map from disk ID to latches */ @GuardedBy("mLock") @@ -813,7 +818,8 @@ class MountService extends IMountService.Stub if (cooked.length != 3) break; final String id = cooked[1]; int flags = Integer.parseInt(cooked[2]); - if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)) { + if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false) + || mForceAdoptable) { flags |= DiskInfo.FLAG_ADOPTABLE; } mDisks.put(id, new DiskInfo(id, flags)); @@ -1208,6 +1214,7 @@ class MountService extends IMountService.Stub private void readSettingsLocked() { mRecords.clear(); mPrimaryStorageUuid = getDefaultPrimaryStorageUuid(); + mForceAdoptable = false; FileInputStream fis = null; try { @@ -1229,6 +1236,7 @@ class MountService extends IMountService.Stub mPrimaryStorageUuid = readStringAttribute(in, ATTR_PRIMARY_STORAGE_UUID); } + mForceAdoptable = readBooleanAttribute(in, ATTR_FORCE_ADOPTABLE, false); } else if (TAG_VOLUME.equals(tag)) { final VolumeRecord rec = readVolumeRecord(in); @@ -1258,6 +1266,7 @@ class MountService extends IMountService.Stub out.startTag(null, TAG_VOLUMES); writeIntAttribute(out, ATTR_VERSION, VERSION_FIX_PRIMARY); writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid); + writeBooleanAttribute(out, ATTR_FORCE_ADOPTABLE, mForceAdoptable); final int size = mRecords.size(); for (int i = 0; i < size; i++) { final VolumeRecord rec = mRecords.valueAt(i); @@ -1541,6 +1550,21 @@ class MountService extends IMountService.Stub } } + @Override + public void setDebugFlags(int flags, int mask) { + enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); + waitForReady(); + + synchronized (mLock) { + if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) { + mForceAdoptable = (flags & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0; + } + + writeSettingsLocked(); + resetIfReadyAndConnected(); + } + } + @Override public String getPrimaryStorageUuid() { enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); @@ -3036,6 +3060,7 @@ class MountService extends IMountService.Stub pw.println(); pw.println("Primary storage UUID: " + mPrimaryStorageUuid); + pw.println("Force adoptable: " + mForceAdoptable); } synchronized (mObbMounts) {