Revert "[vs] Extract writable partition initialization into a ne..."
Revert submission 2541653-libvsutil Reason for revert: This code will stay deprivileged in virtualizationmanager. No need to also link it into virtualizationservice. Reverted changes: /q/submissionid:2541653-libvsutil Change-Id: I5075ff0a65f9a8af31263116fbce05a6a9cf0b7f
This commit is contained in:
parent
0547e864fc
commit
f50c7a6627
|
@ -1,26 +0,0 @@
|
|||
package {
|
||||
default_applicable_licenses: ["Android-Apache-2.0"],
|
||||
}
|
||||
|
||||
rust_library {
|
||||
name: "libvsutil",
|
||||
crate_name: "vsutil",
|
||||
srcs: ["src/lib.rs"],
|
||||
// Only build on targets which crosvm builds on.
|
||||
enabled: false,
|
||||
target: {
|
||||
android64: {
|
||||
compile_multilib: "64",
|
||||
enabled: true,
|
||||
},
|
||||
linux_bionic_arm64: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
rustlibs: [
|
||||
"android.system.virtualizationservice-rust",
|
||||
"libbinder_rs",
|
||||
"libdisk",
|
||||
],
|
||||
apex_available: ["com.android.virt"],
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2023, 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.
|
||||
|
||||
//! Functions to process files.
|
||||
|
||||
use binder::{self, ExceptionCode, ParcelFileDescriptor, Status};
|
||||
use std::fs::File;
|
||||
|
||||
/// Converts a `&ParcelFileDescriptor` to a `File` by cloning the file.
|
||||
pub fn clone_file(fd: &ParcelFileDescriptor) -> binder::Result<File> {
|
||||
fd.as_ref().try_clone().map_err(|e| {
|
||||
Status::new_exception_str(
|
||||
ExceptionCode::BAD_PARCELABLE,
|
||||
Some(format!("Failed to clone File from ParcelFileDescriptor: {:?}", e)),
|
||||
)
|
||||
})
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// Copyright 2023, 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.
|
||||
|
||||
//! This library provides utility functions used by both various
|
||||
//! Virtualization services.
|
||||
|
||||
mod file;
|
||||
mod partition;
|
||||
|
||||
pub use file::clone_file;
|
||||
pub use partition::init_writable_partition;
|
|
@ -1,93 +0,0 @@
|
|||
// Copyright 2023, 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.
|
||||
|
||||
//! Functions to process partitions.
|
||||
|
||||
use crate::file::clone_file;
|
||||
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
|
||||
PartitionType::PartitionType,
|
||||
};
|
||||
use binder::{self, ExceptionCode, ParcelFileDescriptor, Status};
|
||||
use disk::QcowFile;
|
||||
use std::io::{Error, ErrorKind, Write};
|
||||
|
||||
/// crosvm requires all partitions to be a multiple of 4KiB.
|
||||
const PARTITION_GRANULE_BYTES: u64 = 4096;
|
||||
|
||||
/// Initialize an empty partition image of the given size to be used as a writable partition.
|
||||
pub fn init_writable_partition(
|
||||
image_fd: &ParcelFileDescriptor,
|
||||
size_bytes: i64,
|
||||
partition_type: PartitionType,
|
||||
) -> binder::Result<()> {
|
||||
let size_bytes = size_bytes.try_into().map_err(|e| {
|
||||
Status::new_exception_str(
|
||||
ExceptionCode::ILLEGAL_ARGUMENT,
|
||||
Some(format!("Invalid size {}: {:?}", size_bytes, e)),
|
||||
)
|
||||
})?;
|
||||
let size_bytes = round_up(size_bytes, PARTITION_GRANULE_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| {
|
||||
Status::new_service_specific_error_str(-1, Some(format!("Failed to reset a file: {:?}", 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)),
|
||||
)
|
||||
})?;
|
||||
|
||||
match partition_type {
|
||||
PartitionType::RAW => Ok(()),
|
||||
PartitionType::ANDROID_VM_INSTANCE => format_as_android_vm_instance(&mut part),
|
||||
PartitionType::ENCRYPTEDSTORE => format_as_encryptedstore(&mut part),
|
||||
_ => Err(Error::new(
|
||||
ErrorKind::Unsupported,
|
||||
format!("Unsupported partition type {:?}", partition_type),
|
||||
)),
|
||||
}
|
||||
.map_err(|e| {
|
||||
Status::new_service_specific_error_str(
|
||||
-1,
|
||||
Some(format!("Failed to initialize partition as {:?}: {:?}", partition_type, e)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn round_up(input: u64, granule: u64) -> u64 {
|
||||
if granule == 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(granule - 1).unwrap_or(input);
|
||||
(result / granule) * granule
|
||||
}
|
||||
|
||||
fn format_as_android_vm_instance(part: &mut dyn Write) -> std::io::Result<()> {
|
||||
const ANDROID_VM_INSTANCE_MAGIC: &str = "Android-VM-instance";
|
||||
const ANDROID_VM_INSTANCE_VERSION: u16 = 1;
|
||||
|
||||
part.write_all(ANDROID_VM_INSTANCE_MAGIC.as_bytes())?;
|
||||
part.write_all(&ANDROID_VM_INSTANCE_VERSION.to_le_bytes())?;
|
||||
part.flush()
|
||||
}
|
||||
|
||||
fn format_as_encryptedstore(part: &mut dyn Write) -> std::io::Result<()> {
|
||||
const UNFORMATTED_STORAGE_MAGIC: &str = "UNFORMATTED-STORAGE";
|
||||
|
||||
part.write_all(UNFORMATTED_STORAGE_MAGIC.as_bytes())?;
|
||||
part.flush()
|
||||
}
|
|
@ -54,7 +54,6 @@ rust_defaults {
|
|||
"libtombstoned_client_rust",
|
||||
"libvm_control",
|
||||
"libvmconfig",
|
||||
"libvsutil",
|
||||
"libzip",
|
||||
"libvsock",
|
||||
"liblibfdt",
|
||||
|
|
|
@ -53,6 +53,7 @@ use binder::{
|
|||
self, wait_for_interface, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor,
|
||||
Status, StatusCode, Strong,
|
||||
};
|
||||
use disk::QcowFile;
|
||||
use lazy_static::lazy_static;
|
||||
use log::{debug, error, info, warn};
|
||||
use microdroid_payload_config::{OsConfig, Task, TaskType, VmPayloadConfig};
|
||||
|
@ -63,7 +64,7 @@ use semver::VersionReq;
|
|||
use std::convert::TryInto;
|
||||
use std::ffi::CStr;
|
||||
use std::fs::{read_dir, remove_file, File, OpenOptions};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::io::{BufRead, BufReader, Error, ErrorKind, Write};
|
||||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::os::unix::io::{FromRawFd, IntoRawFd};
|
||||
use std::os::unix::raw::pid_t;
|
||||
|
@ -71,7 +72,6 @@ use std::path::{Path, PathBuf};
|
|||
use std::sync::{Arc, Mutex, Weak};
|
||||
use vmconfig::VmConfig;
|
||||
use vsock::VsockStream;
|
||||
use vsutil::{clone_file, init_writable_partition};
|
||||
use zip::ZipArchive;
|
||||
|
||||
/// The unique ID of a VM used (together with a port number) for vsock communication.
|
||||
|
@ -83,8 +83,19 @@ pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservic
|
|||
/// 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;
|
||||
|
||||
const MICRODROID_OS_NAME: &str = "microdroid";
|
||||
|
||||
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)
|
||||
|
@ -178,7 +189,45 @@ impl IVirtualizationService for VirtualizationService {
|
|||
partition_type: PartitionType,
|
||||
) -> binder::Result<()> {
|
||||
check_manage_access()?;
|
||||
init_writable_partition(image_fd, size_bytes, partition_type)
|
||||
let size_bytes = size_bytes.try_into().map_err(|e| {
|
||||
Status::new_exception_str(
|
||||
ExceptionCode::ILLEGAL_ARGUMENT,
|
||||
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| {
|
||||
Status::new_service_specific_error_str(
|
||||
-1,
|
||||
Some(format!("Failed to reset a file: {:?}", 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)),
|
||||
)
|
||||
})?;
|
||||
|
||||
match partition_type {
|
||||
PartitionType::RAW => Ok(()),
|
||||
PartitionType::ANDROID_VM_INSTANCE => format_as_android_vm_instance(&mut part),
|
||||
PartitionType::ENCRYPTEDSTORE => format_as_encryptedstore(&mut part),
|
||||
_ => Err(Error::new(
|
||||
ErrorKind::Unsupported,
|
||||
format!("Unsupported partition type {:?}", partition_type),
|
||||
)),
|
||||
}
|
||||
.map_err(|e| {
|
||||
Status::new_service_specific_error_str(
|
||||
-1,
|
||||
Some(format!("Failed to initialize partition as {:?}: {:?}", partition_type, e)),
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates or update the idsig file by digesting the input APK file.
|
||||
|
@ -435,6 +484,26 @@ fn write_zero_filler(zero_filler_path: &Path) -> Result<()> {
|
|||
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()
|
||||
}
|
||||
|
||||
fn format_as_encryptedstore(part: &mut dyn Write) -> std::io::Result<()> {
|
||||
part.write_all(UNFORMATTED_STORAGE_MAGIC.as_bytes())?;
|
||||
part.flush()
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -886,6 +955,16 @@ fn get_state(instance: &VmInstance) -> VirtualMachineState {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts a `&ParcelFileDescriptor` to a `File` by cloning the file.
|
||||
pub fn clone_file(file: &ParcelFileDescriptor) -> Result<File, Status> {
|
||||
file.as_ref().try_clone().map_err(|e| {
|
||||
Status::new_exception_str(
|
||||
ExceptionCode::BAD_PARCELABLE,
|
||||
Some(format!("Failed to clone File from ParcelFileDescriptor: {:?}", e)),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts an `&Option<ParcelFileDescriptor>` to an `Option<File>` by cloning the file.
|
||||
fn maybe_clone_file(file: &Option<ParcelFileDescriptor>) -> Result<Option<File>, Status> {
|
||||
file.as_ref().map(clone_file).transpose()
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
//! Functions for creating and collecting atoms.
|
||||
|
||||
use crate::aidl::GLOBAL_SERVICE;
|
||||
use crate::aidl::{clone_file, GLOBAL_SERVICE};
|
||||
use crate::crosvm::VmMetric;
|
||||
use crate::get_calling_uid;
|
||||
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
|
||||
|
@ -37,7 +37,6 @@ use microdroid_payload_config::VmPayloadConfig;
|
|||
use statslog_virtualization_rust::vm_creation_requested;
|
||||
use std::thread;
|
||||
use std::time::{Duration, SystemTime};
|
||||
use vsutil::clone_file;
|
||||
use zip::ZipArchive;
|
||||
|
||||
const INVALID_NUM_CPUS: i32 = -1;
|
||||
|
|
Loading…
Reference in New Issue