Add a new "virtual disk" feature.

It's extremely difficult to test storage related logic on devices
that don't have physical SD card slots.  So to support better
debugging and testing, add a new "virtual disk" feature which mounts
a 512MB file through loop device.

Also move ParcelFileDescriptor.open() over to using Os.open() so
that it gets StrictMode treatment.

Bug: 34903607
Test: builds, boots, virtual disk works
Change-Id: I072a3a412cfcc8a2a3472919b7273a1ed794fd98
This commit is contained in:
Jeff Sharkey
2017-03-25 23:14:06 -06:00
parent 20fd49d8c7
commit e53e2d9576
5 changed files with 73 additions and 9 deletions

View File

@@ -94,6 +94,8 @@ public final class Sm {
runGetFbeMode();
} else if ("fstrim".equals(op)) {
runFstrim();
} else if ("set-virtual-disk".equals(op)) {
runSetVirtualDisk();
} else {
throw new IllegalArgumentException();
}
@@ -225,6 +227,12 @@ public final class Sm {
mSm.fstrim(0);
}
public void runSetVirtualDisk() throws RemoteException {
final boolean virtualDisk = Boolean.parseBoolean(nextArg());
mSm.setDebugFlags(virtualDisk ? StorageManager.DEBUG_VIRTUAL_DISK : 0,
StorageManager.DEBUG_VIRTUAL_DISK);
}
private String nextArg() {
if (mNextArg >= mArgs.length) {
return null;
@@ -240,6 +248,7 @@ public final class Sm {
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(" sm set-virtual-disk [true|false]");
System.err.println("");
System.err.println(" sm partition DISK [public|private|mixed] [ratio]");
System.err.println(" sm mount VOLUME");

View File

@@ -2036,14 +2036,20 @@ public final class Parcel {
}
}
/** @deprecated use {@link android.system.Os#open(String, int, int)} */
@Deprecated
static native FileDescriptor openFileDescriptor(String file, int mode)
throws FileNotFoundException;
/*package*/ static native FileDescriptor openFileDescriptor(String file,
int mode) throws FileNotFoundException;
/*package*/ static native FileDescriptor dupFileDescriptor(FileDescriptor orig)
throws IOException;
/*package*/ static native void closeFileDescriptor(FileDescriptor desc)
throws IOException;
/*package*/ static native void clearFileDescriptor(FileDescriptor desc);
/** @deprecated use {@link android.system.Os#dup(FileDescriptor)} */
@Deprecated
static native FileDescriptor dupFileDescriptor(FileDescriptor orig) throws IOException;
/** @deprecated use {@link android.system.Os#close(FileDescriptor)} */
@Deprecated
static native void closeFileDescriptor(FileDescriptor desc) throws IOException;
static native void clearFileDescriptor(FileDescriptor desc);
/**
* Read a byte value from the parcel at the current dataPosition().

View File

@@ -17,11 +17,21 @@
package android.os;
import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.O_APPEND;
import static android.system.OsConstants.O_CREAT;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_RDWR;
import static android.system.OsConstants.O_TRUNC;
import static android.system.OsConstants.O_WRONLY;
import static android.system.OsConstants.SEEK_SET;
import static android.system.OsConstants.SOCK_STREAM;
import static android.system.OsConstants.SOCK_SEQPACKET;
import static android.system.OsConstants.SOCK_STREAM;
import static android.system.OsConstants.S_IROTH;
import static android.system.OsConstants.S_IRWXG;
import static android.system.OsConstants.S_IRWXU;
import static android.system.OsConstants.S_ISLNK;
import static android.system.OsConstants.S_ISREG;
import static android.system.OsConstants.S_IWOTH;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
@@ -33,6 +43,7 @@ import android.system.StructStat;
import android.util.Log;
import dalvik.system.CloseGuard;
import libcore.io.IoUtils;
import libcore.io.Memory;
@@ -279,8 +290,28 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
"Must specify MODE_READ_ONLY, MODE_WRITE_ONLY, or MODE_READ_WRITE");
}
int flags = 0;
switch (mode & MODE_READ_WRITE) {
case 0:
case MODE_READ_ONLY: flags = O_RDONLY; break;
case MODE_WRITE_ONLY: flags = O_WRONLY; break;
case MODE_READ_WRITE: flags = O_RDWR; break;
}
if ((mode & MODE_CREATE) != 0) flags |= O_CREAT;
if ((mode & MODE_TRUNCATE) != 0) flags |= O_TRUNC;
if ((mode & MODE_APPEND) != 0) flags |= O_APPEND;
int realMode = S_IRWXU | S_IRWXG;
if ((mode & MODE_WORLD_READABLE) != 0) realMode |= S_IROTH;
if ((mode & MODE_WORLD_WRITEABLE) != 0) realMode |= S_IWOTH;
final String path = file.getPath();
return Parcel.openFileDescriptor(path, mode);
try {
return Os.open(path, flags, realMode);
} catch (ErrnoException e) {
throw new FileNotFoundException(e.getMessage());
}
}
/**

View File

@@ -113,6 +113,8 @@ public class StorageManager {
public static final String PROP_EMULATE_FBE = "persist.sys.emulate_fbe";
/** {@hide} */
public static final String PROP_SDCARDFS = "persist.sys.sdcardfs";
/** {@hide} */
public static final String PROP_VIRTUAL_DISK = "persist.sys.virtual_disk";
/** {@hide} */
public static final String UUID_PRIVATE_INTERNAL = null;
@@ -140,6 +142,8 @@ public class StorageManager {
public static final int DEBUG_SDCARDFS_FORCE_ON = 1 << 2;
/** {@hide} */
public static final int DEBUG_SDCARDFS_FORCE_OFF = 1 << 3;
/** {@hide} */
public static final int DEBUG_VIRTUAL_DISK = 1 << 4;
// NOTE: keep in sync with installd
/** {@hide} */

View File

@@ -2078,6 +2078,20 @@ class StorageManagerService extends IStorageManager.Stub
Binder.restoreCallingIdentity(token);
}
}
if ((mask & StorageManager.DEBUG_VIRTUAL_DISK) != 0) {
final boolean enabled = (flags & StorageManager.DEBUG_VIRTUAL_DISK) != 0;
final long token = Binder.clearCallingIdentity();
try {
SystemProperties.set(StorageManager.PROP_VIRTUAL_DISK, Boolean.toString(enabled));
// Reset storage to kick new setting into place
mHandler.obtainMessage(H_RESET).sendToTarget();
} finally {
Binder.restoreCallingIdentity(token);
}
}
}
@Override