Merge "Format instance.img"

This commit is contained in:
Jiyong Park 2021-08-25 05:59:42 +00:00 committed by Gerrit Code Review
commit 1b9e4e620b
8 changed files with 106 additions and 9 deletions

View File

@ -54,6 +54,7 @@ using aidl::android::system::virtualizationservice::BnVirtualMachineCallback;
using aidl::android::system::virtualizationservice::IVirtualizationService; using aidl::android::system::virtualizationservice::IVirtualizationService;
using aidl::android::system::virtualizationservice::IVirtualMachine; using aidl::android::system::virtualizationservice::IVirtualMachine;
using aidl::android::system::virtualizationservice::IVirtualMachineCallback; using aidl::android::system::virtualizationservice::IVirtualMachineCallback;
using aidl::android::system::virtualizationservice::PartitionType;
using aidl::android::system::virtualizationservice::VirtualMachineConfig; using aidl::android::system::virtualizationservice::VirtualMachineConfig;
using aidl::com::android::compos::CompOsKeyData; using aidl::com::android::compos::CompOsKeyData;
using aidl::com::android::compos::ICompOsService; using aidl::com::android::compos::ICompOsService;
@ -442,7 +443,8 @@ static Result<void> makeInstanceImage(const std::string& image_path) {
return ErrnoError() << "Failed to create image file"; return ErrnoError() << "Failed to create image file";
} }
auto status = service->initializeWritablePartition(fd, 10 * 1024 * 1024); auto status = service->initializeWritablePartition(fd, 10 * 1024 * 1024,
PartitionType::ANDROID_VM_INSTANCE);
if (!status.isOk()) { if (!status.isOk()) {
return Error() << "Failed to initialize partition: " << status.getDescription(); return Error() << "Failed to initialize partition: " << status.getDescription();
} }

View File

@ -29,6 +29,7 @@ import android.os.ServiceManager;
import android.system.virtualizationservice.IVirtualMachine; import android.system.virtualizationservice.IVirtualMachine;
import android.system.virtualizationservice.IVirtualMachineCallback; import android.system.virtualizationservice.IVirtualMachineCallback;
import android.system.virtualizationservice.IVirtualizationService; import android.system.virtualizationservice.IVirtualizationService;
import android.system.virtualizationservice.PartitionType;
import android.system.virtualizationservice.VirtualMachineAppConfig; import android.system.virtualizationservice.VirtualMachineAppConfig;
import java.io.File; import java.io.File;
@ -165,7 +166,8 @@ public class VirtualMachine {
try { try {
service.initializeWritablePartition( service.initializeWritablePartition(
ParcelFileDescriptor.open(vm.mInstanceFilePath, MODE_READ_WRITE), ParcelFileDescriptor.open(vm.mInstanceFilePath, MODE_READ_WRITE),
INSTANCE_FILE_SIZE); INSTANCE_FILE_SIZE,
PartitionType.ANDROID_VM_INSTANCE);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
throw new VirtualMachineException("instance image missing", e); throw new VirtualMachineException("instance image missing", e);
} catch (RemoteException e) { } catch (RemoteException e) {
@ -288,7 +290,6 @@ public class VirtualMachine {
android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel = android.system.virtualizationservice.VirtualMachineConfig vmConfigParcel =
android.system.virtualizationservice.VirtualMachineConfig.appConfig(appConfig); android.system.virtualizationservice.VirtualMachineConfig.appConfig(appConfig);
mVirtualMachine = service.startVm(vmConfigParcel, mConsoleWriter); mVirtualMachine = service.startVm(vmConfigParcel, mConsoleWriter);
mVirtualMachine.registerCallback( mVirtualMachine.registerCallback(
new IVirtualMachineCallback.Stub() { new IVirtualMachineCallback.Stub() {

View File

@ -16,6 +16,7 @@
package android.system.virtualizationservice; package android.system.virtualizationservice;
import android.system.virtualizationservice.IVirtualMachine; import android.system.virtualizationservice.IVirtualMachine;
import android.system.virtualizationservice.PartitionType;
import android.system.virtualizationservice.VirtualMachineConfig; import android.system.virtualizationservice.VirtualMachineConfig;
import android.system.virtualizationservice.VirtualMachineDebugInfo; import android.system.virtualizationservice.VirtualMachineDebugInfo;
@ -32,7 +33,8 @@ interface IVirtualizationService {
* *
* The file must be open with both read and write permissions, and should be a new empty file. * 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 * Create or update an idsig file that digests the given APK file. The idsig file follows the

View File

@ -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,
}

View File

@ -32,6 +32,7 @@ use android_system_virtualizationservice::aidl::android::system::virtualizations
VirtualMachineRawConfig::VirtualMachineRawConfig, VirtualMachineRawConfig::VirtualMachineRawConfig,
}; };
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::VirtualMachineDebugInfo::VirtualMachineDebugInfo; 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::{ use android_system_virtualizationservice::binder::{
self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState, self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState,
}; };
@ -47,6 +48,7 @@ use microdroid_payload_config::VmPayloadConfig;
use std::convert::TryInto; use std::convert::TryInto;
use std::ffi::CString; use std::ffi::CString;
use std::fs::{File, OpenOptions, create_dir}; use std::fs::{File, OpenOptions, create_dir};
use std::io::{Error, ErrorKind, Write};
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd}; use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -76,6 +78,12 @@ const PORT_VM_BINDER_SERVICE: u32 = 5000;
/// Gaps in composite disk images are filled with a shared zero.img. /// Gaps in composite disk images are filled with a shared zero.img.
const ZERO_FILLER_SIZE: u64 = 4096; 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. /// Implementation of `IVirtualizationService`, the entry point of the AIDL service.
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct VirtualizationService { pub struct VirtualizationService {
@ -199,6 +207,7 @@ impl IVirtualizationService for VirtualizationService {
&self, &self,
image_fd: &ParcelFileDescriptor, image_fd: &ParcelFileDescriptor,
size: i64, size: i64,
partition_type: PartitionType,
) -> binder::Result<()> { ) -> binder::Result<()> {
check_manage_access()?; check_manage_access()?;
let size = size.try_into().map_err(|e| { let size = size.try_into().map_err(|e| {
@ -209,13 +218,28 @@ impl IVirtualizationService for VirtualizationService {
})?; })?;
let image = clone_file(image_fd)?; 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( new_binder_exception(
ExceptionCode::SERVICE_SPECIFIC, ExceptionCode::SERVICE_SPECIFIC,
format!("Failed to create QCOW2 image: {}", e), 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(()) Ok(())
} }
@ -351,6 +375,12 @@ fn write_zero_filler(zero_filler_path: &Path) -> Result<()> {
Ok(()) 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. /// 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. /// This may involve assembling a composite disk from a set of partition images.

View File

@ -15,6 +15,7 @@
//! Command to create an empty partition //! Command to create an empty partition
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService; use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::PartitionType::PartitionType;
use android_system_virtualizationservice::binder::{ParcelFileDescriptor, Strong}; use android_system_virtualizationservice::binder::{ParcelFileDescriptor, Strong};
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use std::convert::TryInto; use std::convert::TryInto;
@ -26,6 +27,7 @@ pub fn command_create_partition(
service: Strong<dyn IVirtualizationService>, service: Strong<dyn IVirtualizationService>,
image_path: &Path, image_path: &Path,
size: u64, size: u64,
partition_type: PartitionType,
) -> Result<(), Error> { ) -> Result<(), Error> {
let image = OpenOptions::new() let image = OpenOptions::new()
.create_new(true) .create_new(true)
@ -34,7 +36,14 @@ pub fn command_create_partition(
.open(image_path) .open(image_path)
.with_context(|| format!("Failed to create {:?}", image_path))?; .with_context(|| format!("Failed to create {:?}", image_path))?;
service service
.initializeWritablePartition(&ParcelFileDescriptor::new(image), size.try_into()?) .initializeWritablePartition(
.context("Failed to initialize partition with size {}, size")?; &ParcelFileDescriptor::new(image),
size.try_into()?,
partition_type,
)
.context(format!(
"Failed to initialize partition type: {:?}, size: {}",
partition_type, size
))?;
Ok(()) Ok(())
} }

View File

@ -19,6 +19,7 @@ mod run;
mod sync; mod sync;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService; use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::PartitionType::PartitionType;
use android_system_virtualizationservice::binder::{wait_for_interface, ProcessState, Strong}; use android_system_virtualizationservice::binder::{wait_for_interface, ProcessState, Strong};
use anyhow::{Context, Error}; use anyhow::{Context, Error};
use create_partition::command_create_partition; use create_partition::command_create_partition;
@ -91,9 +92,21 @@ enum Opt {
/// The desired size of the partition, in bytes. /// The desired size of the partition, in bytes.
size: u64, size: u64,
/// Type of the partition
#[structopt(short="t", long="type", default_value="raw", parse(try_from_str=parse_partition_type))]
partition_type: PartitionType,
}, },
} }
fn parse_partition_type(s: &str) -> Result<PartitionType, String> {
match s {
"raw" => Ok(PartitionType::RAW),
"instance" => Ok(PartitionType::ANDROID_VM_INSTANCE),
_ => Err(format!("Invalid partition type {}", s)),
}
}
fn main() -> Result<(), Error> { fn main() -> Result<(), Error> {
env_logger::init(); env_logger::init();
let opt = Opt::from_args(); let opt = Opt::from_args();
@ -122,7 +135,9 @@ fn main() -> Result<(), Error> {
} }
Opt::Stop { cid } => command_stop(service, cid), Opt::Stop { cid } => command_stop(service, cid),
Opt::List => command_list(service), Opt::List => command_list(service),
Opt::CreatePartition { path, size } => command_create_partition(service, &path, size), Opt::CreatePartition { path, size, partition_type } => {
command_create_partition(service, &path, size, partition_type)
}
} }
} }

View File

@ -22,6 +22,7 @@ use android_system_virtualizationservice::aidl::android::system::virtualizations
BnVirtualMachineCallback, IVirtualMachineCallback, BnVirtualMachineCallback, IVirtualMachineCallback,
}; };
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{ use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
PartitionType::PartitionType,
VirtualMachineAppConfig::VirtualMachineAppConfig, VirtualMachineAppConfig::VirtualMachineAppConfig,
VirtualMachineConfig::VirtualMachineConfig, VirtualMachineConfig::VirtualMachineConfig,
}; };
@ -60,7 +61,12 @@ pub fn command_run_app(
if !instance.exists() { if !instance.exists() {
const INSTANCE_FILE_SIZE: u64 = 10 * 1024 * 1024; const INSTANCE_FILE_SIZE: u64 = 10 * 1024 * 1024;
command_create_partition(service.clone(), instance, INSTANCE_FILE_SIZE)?; command_create_partition(
service.clone(),
instance,
INSTANCE_FILE_SIZE,
PartitionType::ANDROID_VM_INSTANCE,
)?;
} }
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig { let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {