Merge "Change requests for Rust update v1.66.0"
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
index fe9943d..b455c85 100644
--- a/javalib/api/system-current.txt
+++ b/javalib/api/system-current.txt
@@ -58,8 +58,8 @@
public final class VirtualMachineConfig {
method @Nullable public String getApkPath();
method @NonNull public int getDebugLevel();
- method @IntRange(from=0) public long getEncryptedStorageKib();
- method @IntRange(from=0) public int getMemoryMib();
+ method @IntRange(from=0) public long getEncryptedStorageBytes();
+ method @IntRange(from=0) public long getMemoryBytes();
method @IntRange(from=1) public int getNumCpus();
method @Nullable public String getPayloadBinaryName();
method public boolean isCompatibleWith(@NonNull android.system.virtualmachine.VirtualMachineConfig);
@@ -75,8 +75,8 @@
method @NonNull public android.system.virtualmachine.VirtualMachineConfig build();
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setApkPath(@NonNull String);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setDebugLevel(int);
- method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageKib(@IntRange(from=1) long);
- method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryMib(@IntRange(from=1) int);
+ method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setEncryptedStorageBytes(@IntRange(from=1) long);
+ method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setMemoryBytes(@IntRange(from=1) long);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setNumCpus(@IntRange(from=1) int);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setPayloadBinaryName(@NonNull String);
method @NonNull public android.system.virtualmachine.VirtualMachineConfig.Builder setProtectedVm(boolean);
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index ffb2e14..ba7174e 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -476,7 +476,7 @@
try {
service.initializeWritablePartition(
ParcelFileDescriptor.open(vm.mEncryptedStoreFilePath, MODE_READ_WRITE),
- config.getEncryptedStorageKib() * 1024L,
+ config.getEncryptedStorageBytes(),
PartitionType.ENCRYPTEDSTORE);
} catch (FileNotFoundException e) {
throw new VirtualMachineException("encrypted storage image missing", e);
@@ -919,7 +919,7 @@
* Stops this virtual machine. Stopping a virtual machine is like pulling the plug on a real
* computer; the machine halts immediately. Software running on the virtual machine is not
* notified of the event. Writes to {@linkplain
- * VirtualMachineConfig.Builder#setEncryptedStorageKib encrypted storage} might not be
+ * VirtualMachineConfig.Builder#setEncryptedStorageBytes encrypted storage} might not be
* persisted, and the instance might be left in an inconsistent state.
*
* <p>For a graceful shutdown, you could request the payload to call {@code exit()}, e.g. via a
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index b358f9e..cb9bad0 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -60,7 +60,7 @@
private static final String[] EMPTY_STRING_ARRAY = {};
// These define the schema of the config file persisted on disk.
- private static final int VERSION = 4;
+ private static final int VERSION = 5;
private static final String KEY_VERSION = "version";
private static final String KEY_PACKAGENAME = "packageName";
private static final String KEY_APKPATH = "apkPath";
@@ -68,9 +68,9 @@
private static final String KEY_PAYLOADBINARYNAME = "payloadBinaryPath";
private static final String KEY_DEBUGLEVEL = "debugLevel";
private static final String KEY_PROTECTED_VM = "protectedVm";
- private static final String KEY_MEMORY_MIB = "memoryMib";
+ private static final String KEY_MEMORY_BYTES = "memoryBytes";
private static final String KEY_NUM_CPUS = "numCpus";
- private static final String KEY_ENCRYPTED_STORAGE_KIB = "encryptedStorageKib";
+ private static final String KEY_ENCRYPTED_STORAGE_BYTES = "encryptedStorageBytes";
private static final String KEY_VM_OUTPUT_CAPTURED = "vmOutputCaptured";
/** @hide */
@@ -111,9 +111,10 @@
private final boolean mProtectedVm;
/**
- * The amount of RAM to give the VM, in MiB. If this is 0 or negative the default will be used.
+ * The amount of RAM to give the VM, in bytes. If this is 0 or negative the default will be
+ * used.
*/
- private final int mMemoryMib;
+ private final long mMemoryBytes;
/**
* Number of vCPUs in the VM. Defaults to 1 when not specified.
@@ -128,8 +129,8 @@
/** Name of the payload binary file within the APK that will be executed within the VM. */
@Nullable private final String mPayloadBinaryName;
- /** The size of storage in KiB. 0 indicates that encryptedStorage is not required */
- private final long mEncryptedStorageKib;
+ /** The size of storage in bytes. 0 indicates that encryptedStorage is not required */
+ private final long mEncryptedStorageBytes;
/** Whether the app can read console and log output. */
private final boolean mVmOutputCaptured;
@@ -141,9 +142,9 @@
@Nullable String payloadBinaryName,
@DebugLevel int debugLevel,
boolean protectedVm,
- int memoryMib,
+ long memoryBytes,
int numCpus,
- long encryptedStorageKib,
+ long encryptedStorageBytes,
boolean vmOutputCaptured) {
// This is only called from Builder.build(); the builder handles parameter validation.
mPackageName = packageName;
@@ -152,9 +153,9 @@
mPayloadBinaryName = payloadBinaryName;
mDebugLevel = debugLevel;
mProtectedVm = protectedVm;
- mMemoryMib = memoryMib;
+ mMemoryBytes = memoryBytes;
mNumCpus = numCpus;
- mEncryptedStorageKib = encryptedStorageKib;
+ mEncryptedStorageBytes = encryptedStorageBytes;
mVmOutputCaptured = vmOutputCaptured;
}
@@ -220,14 +221,14 @@
}
builder.setDebugLevel(debugLevel);
builder.setProtectedVm(b.getBoolean(KEY_PROTECTED_VM));
- int memoryMib = b.getInt(KEY_MEMORY_MIB);
- if (memoryMib != 0) {
- builder.setMemoryMib(memoryMib);
+ long memoryBytes = b.getLong(KEY_MEMORY_BYTES);
+ if (memoryBytes != 0) {
+ builder.setMemoryBytes(memoryBytes);
}
builder.setNumCpus(b.getInt(KEY_NUM_CPUS));
- long encryptedStorageKib = b.getLong(KEY_ENCRYPTED_STORAGE_KIB);
- if (encryptedStorageKib != 0) {
- builder.setEncryptedStorageKib(encryptedStorageKib);
+ long encryptedStorageBytes = b.getLong(KEY_ENCRYPTED_STORAGE_BYTES);
+ if (encryptedStorageBytes != 0) {
+ builder.setEncryptedStorageBytes(encryptedStorageBytes);
}
builder.setVmOutputCaptured(b.getBoolean(KEY_VM_OUTPUT_CAPTURED));
@@ -258,11 +259,11 @@
b.putInt(KEY_DEBUGLEVEL, mDebugLevel);
b.putBoolean(KEY_PROTECTED_VM, mProtectedVm);
b.putInt(KEY_NUM_CPUS, mNumCpus);
- if (mMemoryMib > 0) {
- b.putInt(KEY_MEMORY_MIB, mMemoryMib);
+ if (mMemoryBytes > 0) {
+ b.putLong(KEY_MEMORY_BYTES, mMemoryBytes);
}
- if (mEncryptedStorageKib > 0) {
- b.putLong(KEY_ENCRYPTED_STORAGE_KIB, mEncryptedStorageKib);
+ if (mEncryptedStorageBytes > 0) {
+ b.putLong(KEY_ENCRYPTED_STORAGE_BYTES, mEncryptedStorageBytes);
}
b.putBoolean(KEY_VM_OUTPUT_CAPTURED, mVmOutputCaptured);
b.writeToStream(output);
@@ -335,8 +336,8 @@
*/
@SystemApi
@IntRange(from = 0)
- public int getMemoryMib() {
- return mMemoryMib;
+ public long getMemoryBytes() {
+ return mMemoryBytes;
}
/**
@@ -357,26 +358,26 @@
*/
@SystemApi
public boolean isEncryptedStorageEnabled() {
- return mEncryptedStorageKib > 0;
+ return mEncryptedStorageBytes > 0;
}
/**
- * Returns the size of encrypted storage (in KiB) available in the VM, or 0 if encrypted storage
- * is not enabled
+ * Returns the size of encrypted storage (in bytes) available in the VM, or 0 if encrypted
+ * storage is not enabled
*
* @hide
*/
@SystemApi
@IntRange(from = 0)
- public long getEncryptedStorageKib() {
- return mEncryptedStorageKib;
+ public long getEncryptedStorageBytes() {
+ return mEncryptedStorageBytes;
}
/**
* Returns whether the app can read the VM console or log output. If not, the VM output is
* automatically forwarded to the host logcat.
*
- * @see #setVmOutputCaptured
+ * @see Builder#setVmOutputCaptured
* @hide
*/
@SystemApi
@@ -398,7 +399,7 @@
public boolean isCompatibleWith(@NonNull VirtualMachineConfig other) {
return this.mDebugLevel == other.mDebugLevel
&& this.mProtectedVm == other.mProtectedVm
- && this.mEncryptedStorageKib == other.mEncryptedStorageKib
+ && this.mEncryptedStorageBytes == other.mEncryptedStorageBytes
&& this.mVmOutputCaptured == other.mVmOutputCaptured
&& Objects.equals(this.mPayloadConfigPath, other.mPayloadConfigPath)
&& Objects.equals(this.mPayloadBinaryName, other.mPayloadBinaryName)
@@ -453,13 +454,23 @@
break;
}
vsConfig.protectedVm = mProtectedVm;
- vsConfig.memoryMib = mMemoryMib;
+ vsConfig.memoryMib = bytesToMebiBytes(mMemoryBytes);
vsConfig.numCpus = mNumCpus;
// Don't allow apps to set task profiles ... at least for now.
vsConfig.taskProfiles = EMPTY_STRING_ARRAY;
return vsConfig;
}
+ private int bytesToMebiBytes(long mMemoryBytes) {
+ long oneMebi = 1024 * 1024;
+ // We can't express requests for more than 2 exabytes, but then they're not going to succeed
+ // anyway.
+ if (mMemoryBytes > (Integer.MAX_VALUE - 1) * oneMebi) {
+ return Integer.MAX_VALUE;
+ }
+ return (int) ((mMemoryBytes + oneMebi - 1) / oneMebi);
+ }
+
/**
* A builder used to create a {@link VirtualMachineConfig}.
*
@@ -474,9 +485,9 @@
@DebugLevel private int mDebugLevel = DEBUG_LEVEL_NONE;
private boolean mProtectedVm;
private boolean mProtectedVmSet;
- private int mMemoryMib;
+ private long mMemoryBytes;
private int mNumCpus = 1;
- private long mEncryptedStorageKib;
+ private long mEncryptedStorageBytes;
private boolean mVmOutputCaptured = false;
/**
@@ -543,9 +554,9 @@
mPayloadBinaryName,
mDebugLevel,
mProtectedVm,
- mMemoryMib,
+ mMemoryBytes,
mNumCpus,
- mEncryptedStorageKib,
+ mEncryptedStorageBytes,
mVmOutputCaptured);
}
@@ -660,18 +671,18 @@
}
/**
- * Sets the amount of RAM to give the VM, in mebibytes. If not explicitly set then a default
+ * Sets the amount of RAM to give the VM, in bytes. If not explicitly set then a default
* size will be used.
*
* @hide
*/
@SystemApi
@NonNull
- public Builder setMemoryMib(@IntRange(from = 1) int memoryMib) {
- if (memoryMib <= 0) {
+ public Builder setMemoryBytes(@IntRange(from = 1) long memoryBytes) {
+ if (memoryBytes <= 0) {
throw new IllegalArgumentException("Memory size must be positive");
}
- mMemoryMib = memoryMib;
+ mMemoryBytes = memoryBytes;
return this;
}
@@ -699,8 +710,8 @@
}
/**
- * Sets the size (in KiB) of encrypted storage available to the VM. If not set, no encrypted
- * storage is provided.
+ * Sets the size (in bytes) of encrypted storage available to the VM. If not set, no
+ * encrypted storage is provided.
*
* <p>The storage is encrypted with a key deterministically derived from the VM identity
*
@@ -716,11 +727,11 @@
*/
@SystemApi
@NonNull
- public Builder setEncryptedStorageKib(@IntRange(from = 1) long encryptedStorageKib) {
- if (encryptedStorageKib <= 0) {
+ public Builder setEncryptedStorageBytes(@IntRange(from = 1) long encryptedStorageBytes) {
+ if (encryptedStorageBytes <= 0) {
throw new IllegalArgumentException("Encrypted Storage size must be positive");
}
- mEncryptedStorageKib = encryptedStorageKib;
+ mEncryptedStorageBytes = encryptedStorageBytes;
return this;
}
diff --git a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
index 40114fd..f17000a 100644
--- a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
+++ b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
@@ -60,6 +60,7 @@
private static final String TAG = "MicrodroidBenchmarks";
private static final String METRIC_NAME_PREFIX = getMetricPrefix() + "microdroid/";
private static final int IO_TEST_TRIAL_COUNT = 5;
+ private static final long ONE_MEBI = 1024 * 1024;
@Rule public Timeout globalTimeout = Timeout.seconds(300);
@@ -95,7 +96,7 @@
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_NONE)
- .setMemoryMib(mem)
+ .setMemoryBytes(mem * ONE_MEBI)
.build();
// returns true if succeeded at least once.
@@ -148,7 +149,7 @@
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_NONE)
- .setMemoryMib(256)
+ .setMemoryBytes(256 * ONE_MEBI)
.build();
forceCreateNewVirtualMachine("test_vm_boot_time", normalConfig);
@@ -176,7 +177,7 @@
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_NONE)
- .setMemoryMib(256)
+ .setMemoryBytes(256 * ONE_MEBI)
.setNumCpus(numCpus)
.build();
forceCreateNewVirtualMachine("test_vm_boot_time_multicore", normalConfig);
@@ -212,7 +213,7 @@
.setPayloadBinaryName("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_FULL)
.setVmOutputCaptured(true)
- .setMemoryMib(256)
+ .setMemoryBytes(256 * ONE_MEBI)
.build();
forceCreateNewVirtualMachine("test_vm_boot_time_debug", normalConfig);
@@ -397,7 +398,7 @@
newVmConfigBuilder()
.setPayloadConfigPath("assets/vm_config_io.json")
.setDebugLevel(DEBUG_LEVEL_NONE)
- .setMemoryMib(256)
+ .setMemoryBytes(256 * ONE_MEBI)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine(vmName, config);
MemoryUsageListener listener = new MemoryUsageListener(this::executeCommand);
@@ -469,7 +470,7 @@
newVmConfigBuilder()
.setPayloadConfigPath("assets/vm_config_io.json")
.setDebugLevel(DEBUG_LEVEL_NONE)
- .setMemoryMib(256)
+ .setMemoryBytes(256 * ONE_MEBI)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine(vmName, config);
MemoryReclaimListener listener = new MemoryReclaimListener(this::executeCommand);
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 5cd0cb1..c6915e5 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -119,8 +119,10 @@
revokePermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
}
- private static final int MIN_MEM_ARM64 = 150;
- private static final int MIN_MEM_X86_64 = 196;
+ private static final long ONE_MEBI = 1024 * 1024;
+
+ private static final long MIN_MEM_ARM64 = 150 * ONE_MEBI;
+ private static final long MIN_MEM_X86_64 = 196 * ONE_MEBI;
private static final String EXAMPLE_STRING = "Literally any string!! :)";
@Test
@@ -131,7 +133,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
@@ -164,7 +166,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_NONE)
.setVmOutputCaptured(false)
.build();
@@ -195,7 +197,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.build();
SecurityException e =
@@ -214,7 +216,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
@@ -245,7 +247,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
@@ -294,7 +296,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_vsock", config);
@@ -345,13 +347,13 @@
assertThat(minimal.getApkPath()).isNull();
assertThat(minimal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_NONE);
- assertThat(minimal.getMemoryMib()).isEqualTo(0);
+ assertThat(minimal.getMemoryBytes()).isEqualTo(0);
assertThat(minimal.getNumCpus()).isEqualTo(1);
assertThat(minimal.getPayloadBinaryName()).isEqualTo("binary.so");
assertThat(minimal.getPayloadConfigPath()).isNull();
assertThat(minimal.isProtectedVm()).isEqualTo(isProtectedVm());
assertThat(minimal.isEncryptedStorageEnabled()).isFalse();
- assertThat(minimal.getEncryptedStorageKib()).isEqualTo(0);
+ assertThat(minimal.getEncryptedStorageBytes()).isEqualTo(0);
assertThat(minimal.isVmOutputCaptured()).isEqualTo(false);
// Maximal has everything that can be set to some non-default value. (And has different
@@ -364,20 +366,20 @@
.setApkPath("/apk/path")
.setNumCpus(maxCpus)
.setDebugLevel(DEBUG_LEVEL_FULL)
- .setMemoryMib(42)
- .setEncryptedStorageKib(1024)
+ .setMemoryBytes(42)
+ .setEncryptedStorageBytes(1_000_000)
.setVmOutputCaptured(true);
VirtualMachineConfig maximal = maximalBuilder.build();
assertThat(maximal.getApkPath()).isEqualTo("/apk/path");
assertThat(maximal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_FULL);
- assertThat(maximal.getMemoryMib()).isEqualTo(42);
+ assertThat(maximal.getMemoryBytes()).isEqualTo(42);
assertThat(maximal.getNumCpus()).isEqualTo(maxCpus);
assertThat(maximal.getPayloadBinaryName()).isNull();
assertThat(maximal.getPayloadConfigPath()).isEqualTo("config/path");
assertThat(maximal.isProtectedVm()).isEqualTo(isProtectedVm());
assertThat(maximal.isEncryptedStorageEnabled()).isTrue();
- assertThat(maximal.getEncryptedStorageKib()).isEqualTo(1024);
+ assertThat(maximal.getEncryptedStorageBytes()).isEqualTo(1_000_000);
assertThat(maximal.isVmOutputCaptured()).isEqualTo(true);
assertThat(minimal.isCompatibleWith(maximal)).isFalse();
@@ -403,9 +405,9 @@
assertThrows(
IllegalArgumentException.class, () -> builder.setPayloadBinaryName("dir/file.so"));
assertThrows(IllegalArgumentException.class, () -> builder.setDebugLevel(-1));
- assertThrows(IllegalArgumentException.class, () -> builder.setMemoryMib(0));
+ assertThrows(IllegalArgumentException.class, () -> builder.setMemoryBytes(0));
assertThrows(IllegalArgumentException.class, () -> builder.setNumCpus(0));
- assertThrows(IllegalArgumentException.class, () -> builder.setEncryptedStorageKib(0));
+ assertThrows(IllegalArgumentException.class, () -> builder.setEncryptedStorageBytes(0));
// Consistency checks enforced at build time.
Exception e;
@@ -437,7 +439,7 @@
assertConfigCompatible(baseline, newBaselineBuilder()).isTrue();
// Changes that must always be compatible
- assertConfigCompatible(baseline, newBaselineBuilder().setMemoryMib(99)).isTrue();
+ assertConfigCompatible(baseline, newBaselineBuilder().setMemoryBytes(99)).isTrue();
if (maxCpus > 1) {
assertConfigCompatible(baseline, newBaselineBuilder().setNumCpus(2)).isTrue();
}
@@ -457,7 +459,7 @@
// Changes that are currently incompatible for ease of implementation, but this might change
// in the future.
assertConfigCompatible(baseline, newBaselineBuilder().setApkPath("/different")).isFalse();
- assertConfigCompatible(baseline, newBaselineBuilder().setEncryptedStorageKib(100))
+ assertConfigCompatible(baseline, newBaselineBuilder().setEncryptedStorageBytes(100_000))
.isFalse();
VirtualMachineConfig.Builder debuggableBuilder =
@@ -506,14 +508,14 @@
assertThat(vm.getName()).isEqualTo("vm_name");
assertThat(vm.getConfig().getPayloadBinaryName()).isEqualTo("binary.so");
- assertThat(vm.getConfig().getMemoryMib()).isEqualTo(0);
+ assertThat(vm.getConfig().getMemoryBytes()).isEqualTo(0);
- VirtualMachineConfig compatibleConfig = builder.setMemoryMib(42).build();
+ VirtualMachineConfig compatibleConfig = builder.setMemoryBytes(42).build();
vm.setConfig(compatibleConfig);
assertThat(vm.getName()).isEqualTo("vm_name");
assertThat(vm.getConfig().getPayloadBinaryName()).isEqualTo("binary.so");
- assertThat(vm.getConfig().getMemoryMib()).isEqualTo(42);
+ assertThat(vm.getConfig().getMemoryBytes()).isEqualTo(42);
assertThat(getVirtualMachineManager().get("vm_name")).isSameInstanceAs(vm);
}
@@ -526,7 +528,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
@@ -624,7 +626,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadConfigPath("assets/vm_config.json")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.build();
VirtualMachine vm =
@@ -646,7 +648,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_delete", config);
@@ -674,7 +676,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidExitNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_delete", config);
@@ -708,7 +710,7 @@
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
.setApkPath(getContext().getPackageCodePath())
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
@@ -744,7 +746,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadConfigPath("assets/vm_config_extra_apk.json")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_extra_apk", config);
@@ -765,7 +767,7 @@
VirtualMachineConfig lowMemConfig =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(memMib)
+ .setMemoryBytes(memMib)
.setDebugLevel(DEBUG_LEVEL_NONE)
.setVmOutputCaptured(false)
.build();
@@ -1230,7 +1232,7 @@
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_FULL);
if (encryptedStoreEnabled) {
- builder.setEncryptedStorageKib(4096);
+ builder.setEncryptedStorageBytes(4_000_000);
}
VirtualMachineConfig config = builder.build();
String vmNameOrig = "test_vm_orig";
@@ -1284,8 +1286,8 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
- .setEncryptedStorageKib(4096)
+ .setMemoryBytes(minMemoryRequired())
+ .setEncryptedStorageBytes(4_000_000)
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
@@ -1307,7 +1309,7 @@
final VirtualMachineConfig vmConfig =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
final VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_caps", vmConfig);
@@ -1331,8 +1333,8 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
- .setEncryptedStorageKib(4096)
+ .setMemoryBytes(minMemoryRequired())
+ .setEncryptedStorageBytes(4_000_000)
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_a", config);
@@ -1366,7 +1368,7 @@
VirtualMachineConfig config =
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
- .setMemoryMib(minMemoryRequired())
+ .setMemoryBytes(minMemoryRequired())
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_read_from_assets", config);
@@ -1482,7 +1484,7 @@
assertThat(e).hasMessageThat().contains(expectedContents);
}
- private int minMemoryRequired() {
+ private long minMemoryRequired() {
if (Build.SUPPORTED_ABIS.length > 0) {
String primaryAbi = Build.SUPPORTED_ABIS[0];
switch (primaryAbi) {
diff --git a/tests/testapk/src/native/idlebinary.cpp b/tests/testapk/src/native/idlebinary.cpp
index 9499d94..366120c 100644
--- a/tests/testapk/src/native/idlebinary.cpp
+++ b/tests/testapk/src/native/idlebinary.cpp
@@ -20,6 +20,6 @@
extern "C" int AVmPayload_main() {
// do nothing; just leave it alive. good night.
for (;;) {
- sleep(1000);
+ pause();
}
}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index ca42999..cab7c71 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -90,6 +90,9 @@
const UNFORMATTED_STORAGE_MAGIC: &str = "UNFORMATTED-STORAGE";
+/// crosvm requires all partitions to be a multiple of 4KiB.
+const PARTITION_GRANULARITY_BYTES: u64 = 4096;
+
lazy_static! {
pub static ref GLOBAL_SERVICE: Strong<dyn IVirtualizationServiceInternal> =
wait_for_interface(BINDER_SERVICE_IDENTIFIER)
@@ -172,16 +175,17 @@
fn initializeWritablePartition(
&self,
image_fd: &ParcelFileDescriptor,
- size: i64,
+ size_bytes: i64,
partition_type: PartitionType,
) -> binder::Result<()> {
check_manage_access()?;
- let size = size.try_into().map_err(|e| {
+ let size_bytes = size_bytes.try_into().map_err(|e| {
Status::new_exception_str(
ExceptionCode::ILLEGAL_ARGUMENT,
- Some(format!("Invalid size {}: {:?}", size, e)),
+ Some(format!("Invalid size {}: {:?}", size_bytes, e)),
)
})?;
+ let size_bytes = round_up(size_bytes, PARTITION_GRANULARITY_BYTES);
let image = clone_file(image_fd)?;
// initialize the file. Any data in the file will be erased.
image.set_len(0).map_err(|e| {
@@ -190,7 +194,7 @@
Some(format!("Failed to reset a file: {:?}", e)),
)
})?;
- let mut part = QcowFile::new(image, size).map_err(|e| {
+ let mut part = QcowFile::new(image, size_bytes).map_err(|e| {
Status::new_service_specific_error_str(
-1,
Some(format!("Failed to create QCOW2 image: {:?}", e)),
@@ -460,6 +464,15 @@
File::create(ramdump_path).context(format!("Failed to create ramdump file {:?}", &ramdump_path))
}
+fn round_up(input: u64, granularity: u64) -> u64 {
+ if granularity == 0 {
+ return input;
+ }
+ // If the input is absurdly large we round down instead of up; it's going to fail anyway.
+ let result = input.checked_add(granularity - 1).unwrap_or(input);
+ (result / granularity) * granularity
+}
+
/// Given the configuration for a disk image, assembles the `DiskFile` to pass to crosvm.
///
/// This may involve assembling a composite disk from a set of partition images.
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
index fc4c9e7..d72d5ac 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
@@ -37,7 +37,7 @@
* The file must be open with both read and write permissions, and should be a new empty file.
*/
void initializeWritablePartition(
- in ParcelFileDescriptor imageFd, long size, PartitionType type);
+ in ParcelFileDescriptor imageFd, long sizeBytes, PartitionType type);
/**
* Create or update an idsig file that digests the given APK file. The idsig file follows the