Format instance.img
When instance.img is created by VS, it's header is formatted to have the
magic number and the version field correctly set.
Bug: 193504400
Test: od -t x /dev/block/by-name/vm-instance shows the magic number and
the version number.
Change-Id: Ie2a04c648a2d8d239aa305660e4408fb0ffc2c33
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
index d136465..7c4b897 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/IVirtualizationService.aidl
@@ -16,6 +16,7 @@
package android.system.virtualizationservice;
import android.system.virtualizationservice.IVirtualMachine;
+import android.system.virtualizationservice.PartitionType;
import android.system.virtualizationservice.VirtualMachineConfig;
import android.system.virtualizationservice.VirtualMachineDebugInfo;
@@ -32,7 +33,8 @@
*
* 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);
+ void initializeWritablePartition(
+ in ParcelFileDescriptor imageFd, long size, PartitionType type);
/**
* Create or update an idsig file that digests the given APK file. The idsig file follows the
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/PartitionType.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/PartitionType.aidl
new file mode 100644
index 0000000..f25e674
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/PartitionType.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.system.virtualizationservice;
+
+/**
+ * Type of the writable partition that virtualizationservice creates via
+ * initializeWritablePartition.
+ */
+@Backing(type="int")
+enum PartitionType {
+ /**
+ * The partition is simply initialized as all zeros
+ */
+ RAW = 0,
+ /**
+ * The partition is initialized as an instance image which is formatted to hold per-VM secrets
+ */
+ ANDROID_VM_INSTANCE = 1,
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 23a9c03..ff5298c 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -32,6 +32,7 @@
VirtualMachineRawConfig::VirtualMachineRawConfig,
};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::VirtualMachineDebugInfo::VirtualMachineDebugInfo;
+use android_system_virtualizationservice::aidl::android::system::virtualizationservice::PartitionType::PartitionType;
use android_system_virtualizationservice::binder::{
self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState,
};
@@ -43,6 +44,7 @@
use std::convert::TryInto;
use std::ffi::CString;
use std::fs::{File, OpenOptions, create_dir};
+use std::io::{Error, ErrorKind, Write};
use std::num::NonZeroU32;
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
use std::path::{Path, PathBuf};
@@ -67,6 +69,12 @@
/// Gaps in composite disk images are filled with a shared zero.img.
const ZERO_FILLER_SIZE: u64 = 4096;
+/// Magic string for the instance image
+const ANDROID_VM_INSTANCE_MAGIC: &str = "Android-VM-instance";
+
+/// Version of the instance image format
+const ANDROID_VM_INSTANCE_VERSION: u16 = 1;
+
/// Implementation of `IVirtualizationService`, the entry point of the AIDL service.
#[derive(Debug, Default)]
pub struct VirtualizationService {
@@ -190,6 +198,7 @@
&self,
image_fd: &ParcelFileDescriptor,
size: i64,
+ partition_type: PartitionType,
) -> binder::Result<()> {
check_manage_access()?;
let size = size.try_into().map_err(|e| {
@@ -200,13 +209,28 @@
})?;
let image = clone_file(image_fd)?;
- QcowFile::new(image, size).map_err(|e| {
+ let mut part = QcowFile::new(image, size).map_err(|e| {
new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC,
format!("Failed to create QCOW2 image: {}", e),
)
})?;
+ match partition_type {
+ PartitionType::RAW => Ok(()),
+ PartitionType::ANDROID_VM_INSTANCE => format_as_android_vm_instance(&mut part),
+ _ => Err(Error::new(
+ ErrorKind::Unsupported,
+ format!("Unsupported partition type {:?}", partition_type),
+ )),
+ }
+ .map_err(|e| {
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("Failed to initialize partition as {:?}: {}", partition_type, e),
+ )
+ })?;
+
Ok(())
}
@@ -320,6 +344,12 @@
Ok(())
}
+fn format_as_android_vm_instance(part: &mut dyn Write) -> std::io::Result<()> {
+ part.write_all(ANDROID_VM_INSTANCE_MAGIC.as_bytes())?;
+ part.write_all(&ANDROID_VM_INSTANCE_VERSION.to_le_bytes())?;
+ part.flush()
+}
+
/// 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.