diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index c6add24..f7202da 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -2,10 +2,11 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
-rust_defaults {
-    name: "virtualizationservice_defaults",
+rust_binary {
+    name: "virtualizationservice",
     crate_name: "virtualizationservice",
     edition: "2021",
+    srcs: ["src/main.rs"],
     // Only build on targets which crosvm builds on.
     enabled: false,
     target: {
@@ -26,67 +27,14 @@
         "android.os.permissions_aidl-rust",
         "libandroid_logger",
         "libanyhow",
-        "libapkverify",
-        "libbase_rust",
         "libbinder_rs",
-        "libcommand_fds",
-        "libdisk",
-        "liblazy_static",
         "liblibc",
         "liblog_rust",
-        "libmicrodroid_metadata",
-        "libmicrodroid_payload_config",
-        "libnested_virt",
         "libnix",
-        "libonce_cell",
-        "libregex",
-        "librpcbinder_rs",
         "librustutils",
-        "libsemver",
-        "libselinux_bindgen",
-        "libserde",
-        "libserde_json",
-        "libserde_xml_rs",
-        "libshared_child",
         "libstatslog_virtualization_rust",
         "libtombstoned_client_rust",
-        "libvm_control",
-        "libvmconfig",
-        "libzip",
         "libvsock",
-        // TODO(b/202115393) stabilize the interface
-        "packagemanager_aidl-rust",
-    ],
-    shared_libs: [
-        "libbinder_rpc_unstable",
-        "libselinux",
-    ],
-}
-
-rust_binary {
-    name: "virtualizationservice",
-    defaults: ["virtualizationservice_defaults"],
-    srcs: ["src/main.rs"],
-    apex_available: ["com.android.virt"],
-}
-
-rust_binary {
-    name: "virtmgr",
-    defaults: ["virtualizationservice_defaults"],
-    srcs: ["src/virtmgr.rs"],
-    rustlibs: [
-        "libclap",
     ],
     apex_available: ["com.android.virt"],
 }
-
-rust_test {
-    name: "virtualizationservice_device_test",
-    srcs: ["src/virtmgr.rs"],
-    defaults: ["virtualizationservice_defaults"],
-    rustlibs: [
-        "libclap",
-        "libtempfile",
-    ],
-    test_suites: ["general-tests"],
-}
diff --git a/virtualizationservice/TEST_MAPPING b/virtualizationservice/TEST_MAPPING
deleted file mode 100644
index 8388ff2..0000000
--- a/virtualizationservice/TEST_MAPPING
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "avf-presubmit": [
-    {
-      "name": "virtualizationservice_device_test"
-    }
-  ]
-}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
deleted file mode 100644
index c827c2e..0000000
--- a/virtualizationservice/src/aidl.rs
+++ /dev/null
@@ -1,1178 +0,0 @@
-// 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.
-
-//! Implementation of the AIDL interface of the VirtualizationService.
-
-use crate::{get_calling_pid, get_calling_uid};
-use crate::atom::{
-    write_vm_booted_stats, write_vm_creation_stats};
-use crate::composite::make_composite_image;
-use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmContext, VmInstance, VmState};
-use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images};
-use crate::selinux::{getfilecon, SeContext};
-use android_os_permissions_aidl::aidl::android::os::IPermissionController;
-use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::{
-    DeathReason::DeathReason,
-    ErrorCode::ErrorCode,
-};
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
-    DiskImage::DiskImage,
-    IVirtualMachine::{BnVirtualMachine, IVirtualMachine},
-    IVirtualMachineCallback::IVirtualMachineCallback,
-    IVirtualizationService::IVirtualizationService,
-    MemoryTrimLevel::MemoryTrimLevel,
-    Partition::Partition,
-    PartitionType::PartitionType,
-    VirtualMachineAppConfig::{DebugLevel::DebugLevel, Payload::Payload, VirtualMachineAppConfig},
-    VirtualMachineConfig::VirtualMachineConfig,
-    VirtualMachineDebugInfo::VirtualMachineDebugInfo,
-    VirtualMachinePayloadConfig::VirtualMachinePayloadConfig,
-    VirtualMachineRawConfig::VirtualMachineRawConfig,
-    VirtualMachineState::VirtualMachineState,
-};
-use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IVirtualizationServiceInternal::IVirtualizationServiceInternal;
-use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::{
-        BnVirtualMachineService, IVirtualMachineService,
-};
-use anyhow::{bail, Context, Result};
-use apkverify::{HashAlgorithm, V4Signature};
-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};
-use nix::unistd::pipe;
-use rpcbinder::RpcServer;
-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, Error, ErrorKind, Write};
-use std::num::NonZeroU32;
-use std::os::unix::io::{FromRawFd, IntoRawFd};
-use std::os::unix::raw::pid_t;
-use std::path::{Path, PathBuf};
-use std::sync::{Arc, Mutex, Weak};
-use vmconfig::VmConfig;
-use vsock::VsockStream;
-use zip::ZipArchive;
-
-/// The unique ID of a VM used (together with a port number) for vsock communication.
-pub type Cid = u32;
-
-pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservice";
-
-/// The size of zero.img.
-/// 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";
-
-lazy_static! {
-    pub static ref GLOBAL_SERVICE: Strong<dyn IVirtualizationServiceInternal> =
-        wait_for_interface(BINDER_SERVICE_IDENTIFIER)
-            .expect("Could not connect to VirtualizationServiceInternal");
-}
-
-fn create_or_update_idsig_file(
-    input_fd: &ParcelFileDescriptor,
-    idsig_fd: &ParcelFileDescriptor,
-) -> Result<()> {
-    let mut input = clone_file(input_fd)?;
-    let metadata = input.metadata().context("failed to get input metadata")?;
-    if !metadata.is_file() {
-        bail!("input is not a regular file");
-    }
-    let mut sig = V4Signature::create(&mut input, 4096, &[], HashAlgorithm::SHA256)
-        .context("failed to create idsig")?;
-
-    let mut output = clone_file(idsig_fd)?;
-    output.set_len(0).context("failed to set_len on the idsig output")?;
-    sig.write_into(&mut output).context("failed to write idsig")?;
-    Ok(())
-}
-
-pub fn remove_temporary_files(path: &PathBuf) -> Result<()> {
-    for dir_entry in read_dir(path)? {
-        remove_file(dir_entry?.path())?;
-    }
-    Ok(())
-}
-
-/// Implementation of `IVirtualizationService`, the entry point of the AIDL service.
-#[derive(Debug, Default)]
-pub struct VirtualizationService {
-    state: Arc<Mutex<State>>,
-}
-
-impl Interface for VirtualizationService {
-    fn dump(&self, mut file: &File, _args: &[&CStr]) -> Result<(), StatusCode> {
-        check_permission("android.permission.DUMP").or(Err(StatusCode::PERMISSION_DENIED))?;
-        let state = &mut *self.state.lock().unwrap();
-        let vms = state.vms();
-        writeln!(file, "Running {0} VMs:", vms.len()).or(Err(StatusCode::UNKNOWN_ERROR))?;
-        for vm in vms {
-            writeln!(file, "VM CID: {}", vm.cid).or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\tState: {:?}", vm.vm_state.lock().unwrap())
-                .or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\tPayload state {:?}", vm.payload_state())
-                .or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\tProtected: {}", vm.protected).or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\ttemporary_directory: {}", vm.temporary_directory.to_string_lossy())
-                .or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\trequester_uid: {}", vm.requester_uid)
-                .or(Err(StatusCode::UNKNOWN_ERROR))?;
-            writeln!(file, "\trequester_debug_pid: {}", vm.requester_debug_pid)
-                .or(Err(StatusCode::UNKNOWN_ERROR))?;
-        }
-        Ok(())
-    }
-}
-
-impl IVirtualizationService for VirtualizationService {
-    /// Creates (but does not start) a new VM with the given configuration, assigning it the next
-    /// available CID.
-    ///
-    /// Returns a binder `IVirtualMachine` object referring to it, as a handle for the client.
-    fn createVm(
-        &self,
-        config: &VirtualMachineConfig,
-        console_fd: Option<&ParcelFileDescriptor>,
-        log_fd: Option<&ParcelFileDescriptor>,
-    ) -> binder::Result<Strong<dyn IVirtualMachine>> {
-        let mut is_protected = false;
-        let ret = self.create_vm_internal(config, console_fd, log_fd, &mut is_protected);
-        write_vm_creation_stats(config, is_protected, &ret);
-        ret
-    }
-
-    /// Initialise an empty partition image of the given size to be used as a writable partition.
-    fn initializeWritablePartition(
-        &self,
-        image_fd: &ParcelFileDescriptor,
-        size: i64,
-        partition_type: PartitionType,
-    ) -> binder::Result<()> {
-        check_manage_access()?;
-        let size = size.try_into().map_err(|e| {
-            Status::new_exception_str(
-                ExceptionCode::ILLEGAL_ARGUMENT,
-                Some(format!("Invalid size {}: {:?}", size, e)),
-            )
-        })?;
-        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).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.
-    fn createOrUpdateIdsigFile(
-        &self,
-        input_fd: &ParcelFileDescriptor,
-        idsig_fd: &ParcelFileDescriptor,
-    ) -> binder::Result<()> {
-        // TODO(b/193504400): do this only when (1) idsig_fd is empty or (2) the APK digest in
-        // idsig_fd is different from APK digest in input_fd
-
-        check_manage_access()?;
-
-        create_or_update_idsig_file(input_fd, idsig_fd)
-            .map_err(|e| Status::new_service_specific_error_str(-1, Some(format!("{:?}", e))))?;
-        Ok(())
-    }
-
-    /// Get a list of all currently running VMs. This method is only intended for debug purposes,
-    /// and as such is only permitted from the shell user.
-    fn debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>> {
-        // Delegate to the global service, including checking the debug permission.
-        GLOBAL_SERVICE.debugListVms()
-    }
-}
-
-impl VirtualizationService {
-    pub fn init() -> VirtualizationService {
-        VirtualizationService::default()
-    }
-
-    fn create_vm_context(
-        &self,
-        requester_debug_pid: pid_t,
-    ) -> binder::Result<(VmContext, Cid, PathBuf)> {
-        const NUM_ATTEMPTS: usize = 5;
-
-        for _ in 0..NUM_ATTEMPTS {
-            let vm_context = GLOBAL_SERVICE.allocateGlobalVmContext(requester_debug_pid as i32)?;
-            let cid = vm_context.getCid()? as Cid;
-            let temp_dir: PathBuf = vm_context.getTemporaryDirectory()?.into();
-            let service = VirtualMachineService::new_binder(self.state.clone(), cid).as_binder();
-
-            // Start VM service listening for connections from the new CID on port=CID.
-            let port = cid;
-            match RpcServer::new_vsock(service, cid, port) {
-                Ok(vm_server) => {
-                    vm_server.start();
-                    return Ok((VmContext::new(vm_context, vm_server), cid, temp_dir));
-                }
-                Err(err) => {
-                    warn!("Could not start RpcServer on port {}: {}", port, err);
-                }
-            }
-        }
-        Err(Status::new_service_specific_error_str(
-            -1,
-            Some("Too many attempts to create VM context failed."),
-        ))
-    }
-
-    fn create_vm_internal(
-        &self,
-        config: &VirtualMachineConfig,
-        console_fd: Option<&ParcelFileDescriptor>,
-        log_fd: Option<&ParcelFileDescriptor>,
-        is_protected: &mut bool,
-    ) -> binder::Result<Strong<dyn IVirtualMachine>> {
-        let requester_uid = get_calling_uid();
-        let requester_debug_pid = get_calling_pid();
-
-        // Allocating VM context checks the MANAGE_VIRTUAL_MACHINE permission.
-        let (vm_context, cid, temporary_directory) = self.create_vm_context(requester_debug_pid)?;
-
-        let is_custom = match config {
-            VirtualMachineConfig::RawConfig(_) => true,
-            VirtualMachineConfig::AppConfig(config) => {
-                // Some features are reserved for platform apps only, even when using
-                // VirtualMachineAppConfig:
-                // - controlling CPUs;
-                // - specifying a config file in the APK.
-                !config.taskProfiles.is_empty() || matches!(config.payload, Payload::ConfigPath(_))
-            }
-        };
-        if is_custom {
-            check_use_custom_virtual_machine()?;
-        }
-
-        let state = &mut *self.state.lock().unwrap();
-        let console_fd =
-            clone_or_prepare_logger_fd(config, console_fd, format!("Console({})", cid))?;
-        let log_fd = clone_or_prepare_logger_fd(config, log_fd, format!("Log({})", cid))?;
-
-        // Counter to generate unique IDs for temporary image files.
-        let mut next_temporary_image_id = 0;
-        // Files which are referred to from composite images. These must be mapped to the crosvm
-        // child process, and not closed before it is started.
-        let mut indirect_files = vec![];
-
-        let (is_app_config, config) = match config {
-            VirtualMachineConfig::RawConfig(config) => (false, BorrowedOrOwned::Borrowed(config)),
-            VirtualMachineConfig::AppConfig(config) => {
-                let config = load_app_config(config, &temporary_directory).map_err(|e| {
-                    *is_protected = config.protectedVm;
-                    let message = format!("Failed to load app config: {:?}", e);
-                    error!("{}", message);
-                    Status::new_service_specific_error_str(-1, Some(message))
-                })?;
-                (true, BorrowedOrOwned::Owned(config))
-            }
-        };
-        let config = config.as_ref();
-        *is_protected = config.protectedVm;
-
-        // Check if partition images are labeled incorrectly. This is to prevent random images
-        // which are not protected by the Android Verified Boot (e.g. bits downloaded by apps) from
-        // being loaded in a pVM. This applies to everything in the raw config, and everything but
-        // the non-executable, generated partitions in the app config.
-        config
-            .disks
-            .iter()
-            .flat_map(|disk| disk.partitions.iter())
-            .filter(|partition| {
-                if is_app_config {
-                    !is_safe_app_partition(&partition.label)
-                } else {
-                    true // all partitions are checked
-                }
-            })
-            .try_for_each(check_label_for_partition)
-            .map_err(|e| Status::new_service_specific_error_str(-1, Some(format!("{:?}", e))))?;
-
-        let kernel = maybe_clone_file(&config.kernel)?;
-        let initrd = maybe_clone_file(&config.initrd)?;
-
-        // In a protected VM, we require custom kernels to come from a trusted source (b/237054515).
-        if config.protectedVm {
-            check_label_for_kernel_files(&kernel, &initrd).map_err(|e| {
-                Status::new_service_specific_error_str(-1, Some(format!("{:?}", e)))
-            })?;
-        }
-
-        let zero_filler_path = temporary_directory.join("zero.img");
-        write_zero_filler(&zero_filler_path).map_err(|e| {
-            error!("Failed to make composite image: {:?}", e);
-            Status::new_service_specific_error_str(
-                -1,
-                Some(format!("Failed to make composite image: {:?}", e)),
-            )
-        })?;
-
-        // Assemble disk images if needed.
-        let disks = config
-            .disks
-            .iter()
-            .map(|disk| {
-                assemble_disk_image(
-                    disk,
-                    &zero_filler_path,
-                    &temporary_directory,
-                    &mut next_temporary_image_id,
-                    &mut indirect_files,
-                )
-            })
-            .collect::<Result<Vec<DiskFile>, _>>()?;
-
-        // Creating this ramdump file unconditionally is not harmful as ramdump will be created
-        // only when the VM is configured as such. `ramdump_write` is sent to crosvm and will
-        // be the backing store for the /dev/hvc1 where VM will emit ramdump to. `ramdump_read`
-        // will be sent back to the client (i.e. the VM owner) for readout.
-        let ramdump_path = temporary_directory.join("ramdump");
-        let ramdump = prepare_ramdump_file(&ramdump_path).map_err(|e| {
-            error!("Failed to prepare ramdump file: {:?}", e);
-            Status::new_service_specific_error_str(
-                -1,
-                Some(format!("Failed to prepare ramdump file: {:?}", e)),
-            )
-        })?;
-
-        // Actually start the VM.
-        let crosvm_config = CrosvmConfig {
-            cid,
-            name: config.name.clone(),
-            bootloader: maybe_clone_file(&config.bootloader)?,
-            kernel,
-            initrd,
-            disks,
-            params: config.params.to_owned(),
-            protected: *is_protected,
-            memory_mib: config.memoryMib.try_into().ok().and_then(NonZeroU32::new),
-            cpus: config.numCpus.try_into().ok().and_then(NonZeroU32::new),
-            task_profiles: config.taskProfiles.clone(),
-            console_fd,
-            log_fd,
-            ramdump: Some(ramdump),
-            indirect_files,
-            platform_version: parse_platform_version_req(&config.platformVersion)?,
-            detect_hangup: is_app_config,
-        };
-        let instance = Arc::new(
-            VmInstance::new(
-                crosvm_config,
-                temporary_directory,
-                requester_uid,
-                requester_debug_pid,
-                vm_context,
-            )
-            .map_err(|e| {
-                error!("Failed to create VM with config {:?}: {:?}", config, e);
-                Status::new_service_specific_error_str(
-                    -1,
-                    Some(format!("Failed to create VM: {:?}", e)),
-                )
-            })?,
-        );
-        state.add_vm(Arc::downgrade(&instance));
-        Ok(VirtualMachine::create(instance))
-    }
-}
-
-fn write_zero_filler(zero_filler_path: &Path) -> Result<()> {
-    let file = OpenOptions::new()
-        .create_new(true)
-        .read(true)
-        .write(true)
-        .open(zero_filler_path)
-        .with_context(|| "Failed to create zero.img")?;
-    file.set_len(ZERO_FILLER_SIZE)?;
-    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 prepare_ramdump_file(ramdump_path: &Path) -> Result<File> {
-    File::create(ramdump_path).context(format!("Failed to create ramdump file {:?}", &ramdump_path))
-}
-
-/// 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.
-fn assemble_disk_image(
-    disk: &DiskImage,
-    zero_filler_path: &Path,
-    temporary_directory: &Path,
-    next_temporary_image_id: &mut u64,
-    indirect_files: &mut Vec<File>,
-) -> Result<DiskFile, Status> {
-    let image = if !disk.partitions.is_empty() {
-        if disk.image.is_some() {
-            warn!("DiskImage {:?} contains both image and partitions.", disk);
-            return Err(Status::new_exception_str(
-                ExceptionCode::ILLEGAL_ARGUMENT,
-                Some("DiskImage contains both image and partitions."),
-            ));
-        }
-
-        let composite_image_filenames =
-            make_composite_image_filenames(temporary_directory, next_temporary_image_id);
-        let (image, partition_files) = make_composite_image(
-            &disk.partitions,
-            zero_filler_path,
-            &composite_image_filenames.composite,
-            &composite_image_filenames.header,
-            &composite_image_filenames.footer,
-        )
-        .map_err(|e| {
-            error!("Failed to make composite image with config {:?}: {:?}", disk, e);
-            Status::new_service_specific_error_str(
-                -1,
-                Some(format!("Failed to make composite image: {:?}", e)),
-            )
-        })?;
-
-        // Pass the file descriptors for the various partition files to crosvm when it
-        // is run.
-        indirect_files.extend(partition_files);
-
-        image
-    } else if let Some(image) = &disk.image {
-        clone_file(image)?
-    } else {
-        warn!("DiskImage {:?} didn't contain image or partitions.", disk);
-        return Err(Status::new_exception_str(
-            ExceptionCode::ILLEGAL_ARGUMENT,
-            Some("DiskImage didn't contain image or partitions."),
-        ));
-    };
-
-    Ok(DiskFile { image, writable: disk.writable })
-}
-
-fn load_app_config(
-    config: &VirtualMachineAppConfig,
-    temporary_directory: &Path,
-) -> Result<VirtualMachineRawConfig> {
-    let apk_file = clone_file(config.apk.as_ref().unwrap())?;
-    let idsig_file = clone_file(config.idsig.as_ref().unwrap())?;
-    let instance_file = clone_file(config.instanceImage.as_ref().unwrap())?;
-
-    let storage_image = if let Some(file) = config.encryptedStorageImage.as_ref() {
-        Some(clone_file(file)?)
-    } else {
-        None
-    };
-
-    let vm_payload_config = match &config.payload {
-        Payload::ConfigPath(config_path) => {
-            load_vm_payload_config_from_file(&apk_file, config_path.as_str())
-                .with_context(|| format!("Couldn't read config from {}", config_path))?
-        }
-        Payload::PayloadConfig(payload_config) => create_vm_payload_config(payload_config)?,
-    };
-
-    // For now, the only supported OS is Microdroid
-    let os_name = vm_payload_config.os.name.as_str();
-    if os_name != MICRODROID_OS_NAME {
-        bail!("Unknown OS \"{}\"", os_name);
-    }
-
-    // It is safe to construct a filename based on the os_name because we've already checked that it
-    // is one of the allowed values.
-    let vm_config_path = PathBuf::from(format!("/apex/com.android.virt/etc/{}.json", os_name));
-    let vm_config_file = File::open(vm_config_path)?;
-    let mut vm_config = VmConfig::load(&vm_config_file)?.to_parcelable()?;
-
-    if config.memoryMib > 0 {
-        vm_config.memoryMib = config.memoryMib;
-    }
-
-    vm_config.name = config.name.clone();
-    vm_config.protectedVm = config.protectedVm;
-    vm_config.numCpus = config.numCpus;
-    vm_config.taskProfiles = config.taskProfiles.clone();
-
-    // Microdroid takes additional init ramdisk & (optionally) storage image
-    add_microdroid_system_images(config, instance_file, storage_image, &mut vm_config)?;
-
-    // Include Microdroid payload disk (contains apks, idsigs) in vm config
-    add_microdroid_payload_images(
-        config,
-        temporary_directory,
-        apk_file,
-        idsig_file,
-        &vm_payload_config,
-        &mut vm_config,
-    )?;
-
-    Ok(vm_config)
-}
-
-fn load_vm_payload_config_from_file(apk_file: &File, config_path: &str) -> Result<VmPayloadConfig> {
-    let mut apk_zip = ZipArchive::new(apk_file)?;
-    let config_file = apk_zip.by_name(config_path)?;
-    Ok(serde_json::from_reader(config_file)?)
-}
-
-fn create_vm_payload_config(
-    payload_config: &VirtualMachinePayloadConfig,
-) -> Result<VmPayloadConfig> {
-    // There isn't an actual config file. Construct a synthetic VmPayloadConfig from the explicit
-    // parameters we've been given. Microdroid will do something equivalent inside the VM using the
-    // payload config that we send it via the metadata file.
-
-    let payload_binary_name = &payload_config.payloadBinaryName;
-    if payload_binary_name.contains('/') {
-        bail!("Payload binary name must not specify a path: {payload_binary_name}");
-    }
-
-    let task = Task { type_: TaskType::MicrodroidLauncher, command: payload_binary_name.clone() };
-    Ok(VmPayloadConfig {
-        os: OsConfig { name: MICRODROID_OS_NAME.to_owned() },
-        task: Some(task),
-        apexes: vec![],
-        extra_apks: vec![],
-        prefer_staged: false,
-        export_tombstones: false,
-        enable_authfs: false,
-    })
-}
-
-/// Generates a unique filename to use for a composite disk image.
-fn make_composite_image_filenames(
-    temporary_directory: &Path,
-    next_temporary_image_id: &mut u64,
-) -> CompositeImageFilenames {
-    let id = *next_temporary_image_id;
-    *next_temporary_image_id += 1;
-    CompositeImageFilenames {
-        composite: temporary_directory.join(format!("composite-{}.img", id)),
-        header: temporary_directory.join(format!("composite-{}-header.img", id)),
-        footer: temporary_directory.join(format!("composite-{}-footer.img", id)),
-    }
-}
-
-/// Filenames for a composite disk image, including header and footer partitions.
-#[derive(Clone, Debug, Eq, PartialEq)]
-struct CompositeImageFilenames {
-    /// The composite disk image itself.
-    composite: PathBuf,
-    /// The header partition image.
-    header: PathBuf,
-    /// The footer partition image.
-    footer: PathBuf,
-}
-
-/// Checks whether the caller has a specific permission
-fn check_permission(perm: &str) -> binder::Result<()> {
-    let calling_pid = get_calling_pid();
-    let calling_uid = get_calling_uid();
-    // Root can do anything
-    if calling_uid == 0 {
-        return Ok(());
-    }
-    let perm_svc: Strong<dyn IPermissionController::IPermissionController> =
-        binder::get_interface("permission")?;
-    if perm_svc.checkPermission(perm, calling_pid, calling_uid as i32)? {
-        Ok(())
-    } else {
-        Err(Status::new_exception_str(
-            ExceptionCode::SECURITY,
-            Some(format!("does not have the {} permission", perm)),
-        ))
-    }
-}
-
-/// Check whether the caller of the current Binder method is allowed to manage VMs
-fn check_manage_access() -> binder::Result<()> {
-    check_permission("android.permission.MANAGE_VIRTUAL_MACHINE")
-}
-
-/// Check whether the caller of the current Binder method is allowed to create custom VMs
-fn check_use_custom_virtual_machine() -> binder::Result<()> {
-    check_permission("android.permission.USE_CUSTOM_VIRTUAL_MACHINE")
-}
-
-/// Return whether a partition is exempt from selinux label checks, because we know that it does
-/// not contain code and is likely to be generated in an app-writable directory.
-fn is_safe_app_partition(label: &str) -> bool {
-    // See add_microdroid_system_images & add_microdroid_payload_images in payload.rs.
-    label == "vm-instance"
-        || label == "encryptedstore"
-        || label == "microdroid-apk-idsig"
-        || label == "payload-metadata"
-        || label.starts_with("extra-idsig-")
-}
-
-/// Check that a file SELinux label is acceptable.
-///
-/// We only want to allow code in a VM to be sourced from places that apps, and the
-/// system, do not have write access to.
-///
-/// Note that sepolicy must also grant read access for these types to both virtualization
-/// service and crosvm.
-///
-/// App private data files are deliberately excluded, to avoid arbitrary payloads being run on
-/// user devices (W^X).
-fn check_label_is_allowed(context: &SeContext) -> Result<()> {
-    match context.selinux_type()? {
-        | "system_file" // immutable dm-verity protected partition
-        | "apk_data_file" // APKs of an installed app
-        | "staging_data_file" // updated/staged APEX images
-        | "shell_data_file" // test files created via adb shell
-         => Ok(()),
-        _ => bail!("Label {} is not allowed", context),
-    }
-}
-
-fn check_label_for_partition(partition: &Partition) -> Result<()> {
-    let file = partition.image.as_ref().unwrap().as_ref();
-    check_label_is_allowed(&getfilecon(file)?)
-        .with_context(|| format!("Partition {} invalid", &partition.label))
-}
-
-fn check_label_for_kernel_files(kernel: &Option<File>, initrd: &Option<File>) -> Result<()> {
-    if let Some(f) = kernel {
-        check_label_for_file(f, "kernel")?;
-    }
-    if let Some(f) = initrd {
-        check_label_for_file(f, "initrd")?;
-    }
-    Ok(())
-}
-fn check_label_for_file(file: &File, name: &str) -> Result<()> {
-    check_label_is_allowed(&getfilecon(file)?).with_context(|| format!("{} file invalid", name))
-}
-
-/// Implementation of the AIDL `IVirtualMachine` interface. Used as a handle to a VM.
-#[derive(Debug)]
-struct VirtualMachine {
-    instance: Arc<VmInstance>,
-}
-
-impl VirtualMachine {
-    fn create(instance: Arc<VmInstance>) -> Strong<dyn IVirtualMachine> {
-        BnVirtualMachine::new_binder(VirtualMachine { instance }, BinderFeatures::default())
-    }
-}
-
-impl Interface for VirtualMachine {}
-
-impl IVirtualMachine for VirtualMachine {
-    fn getCid(&self) -> binder::Result<i32> {
-        // Don't check permission. The owner of the VM might have passed this binder object to
-        // others.
-        Ok(self.instance.cid as i32)
-    }
-
-    fn getState(&self) -> binder::Result<VirtualMachineState> {
-        // Don't check permission. The owner of the VM might have passed this binder object to
-        // others.
-        Ok(get_state(&self.instance))
-    }
-
-    fn registerCallback(
-        &self,
-        callback: &Strong<dyn IVirtualMachineCallback>,
-    ) -> binder::Result<()> {
-        // Don't check permission. The owner of the VM might have passed this binder object to
-        // others.
-        //
-        // TODO: Should this give an error if the VM is already dead?
-        self.instance.callbacks.add(callback.clone());
-        Ok(())
-    }
-
-    fn start(&self) -> binder::Result<()> {
-        self.instance.start().map_err(|e| {
-            error!("Error starting VM with CID {}: {:?}", self.instance.cid, e);
-            Status::new_service_specific_error_str(-1, Some(e.to_string()))
-        })
-    }
-
-    fn stop(&self) -> binder::Result<()> {
-        self.instance.kill().map_err(|e| {
-            error!("Error stopping VM with CID {}: {:?}", self.instance.cid, e);
-            Status::new_service_specific_error_str(-1, Some(e.to_string()))
-        })
-    }
-
-    fn onTrimMemory(&self, level: MemoryTrimLevel) -> binder::Result<()> {
-        self.instance.trim_memory(level).map_err(|e| {
-            error!("Error trimming VM with CID {}: {:?}", self.instance.cid, e);
-            Status::new_service_specific_error_str(-1, Some(e.to_string()))
-        })
-    }
-
-    fn connectVsock(&self, port: i32) -> binder::Result<ParcelFileDescriptor> {
-        if !matches!(&*self.instance.vm_state.lock().unwrap(), VmState::Running { .. }) {
-            return Err(Status::new_service_specific_error_str(-1, Some("VM is not running")));
-        }
-        let port = port as u32;
-        if port < 1024 {
-            return Err(Status::new_service_specific_error_str(
-                -1,
-                Some(format!("Can't connect to privileged port {port}")),
-            ));
-        }
-        let stream = VsockStream::connect_with_cid_port(self.instance.cid, port).map_err(|e| {
-            Status::new_service_specific_error_str(-1, Some(format!("Failed to connect: {:?}", e)))
-        })?;
-        Ok(vsock_stream_to_pfd(stream))
-    }
-}
-
-impl Drop for VirtualMachine {
-    fn drop(&mut self) {
-        debug!("Dropping {:?}", self);
-        if let Err(e) = self.instance.kill() {
-            debug!("Error stopping dropped VM with CID {}: {:?}", self.instance.cid, e);
-        }
-    }
-}
-
-/// A set of Binders to be called back in response to various events on the VM, such as when it
-/// dies.
-#[derive(Debug, Default)]
-pub struct VirtualMachineCallbacks(Mutex<Vec<Strong<dyn IVirtualMachineCallback>>>);
-
-impl VirtualMachineCallbacks {
-    /// Call all registered callbacks to notify that the payload has started.
-    pub fn notify_payload_started(&self, cid: Cid) {
-        let callbacks = &*self.0.lock().unwrap();
-        for callback in callbacks {
-            if let Err(e) = callback.onPayloadStarted(cid as i32) {
-                error!("Error notifying payload start event from VM CID {}: {:?}", cid, e);
-            }
-        }
-    }
-
-    /// Call all registered callbacks to notify that the payload is ready to serve.
-    pub fn notify_payload_ready(&self, cid: Cid) {
-        let callbacks = &*self.0.lock().unwrap();
-        for callback in callbacks {
-            if let Err(e) = callback.onPayloadReady(cid as i32) {
-                error!("Error notifying payload ready event from VM CID {}: {:?}", cid, e);
-            }
-        }
-    }
-
-    /// Call all registered callbacks to notify that the payload has finished.
-    pub fn notify_payload_finished(&self, cid: Cid, exit_code: i32) {
-        let callbacks = &*self.0.lock().unwrap();
-        for callback in callbacks {
-            if let Err(e) = callback.onPayloadFinished(cid as i32, exit_code) {
-                error!("Error notifying payload finish event from VM CID {}: {:?}", cid, e);
-            }
-        }
-    }
-
-    /// Call all registered callbacks to say that the VM encountered an error.
-    pub fn notify_error(&self, cid: Cid, error_code: ErrorCode, message: &str) {
-        let callbacks = &*self.0.lock().unwrap();
-        for callback in callbacks {
-            if let Err(e) = callback.onError(cid as i32, error_code, message) {
-                error!("Error notifying error event from VM CID {}: {:?}", cid, e);
-            }
-        }
-    }
-
-    /// Call all registered callbacks to say that the VM has died.
-    pub fn callback_on_died(&self, cid: Cid, reason: DeathReason) {
-        let callbacks = &*self.0.lock().unwrap();
-        for callback in callbacks {
-            if let Err(e) = callback.onDied(cid as i32, reason) {
-                error!("Error notifying exit of VM CID {}: {:?}", cid, e);
-            }
-        }
-    }
-
-    /// Add a new callback to the set.
-    fn add(&self, callback: Strong<dyn IVirtualMachineCallback>) {
-        self.0.lock().unwrap().push(callback);
-    }
-}
-
-/// The mutable state of the VirtualizationService. There should only be one instance of this
-/// struct.
-#[derive(Debug, Default)]
-struct State {
-    /// The VMs which have been started. When VMs are started a weak reference is added to this list
-    /// while a strong reference is returned to the caller over Binder. Once all copies of the
-    /// Binder client are dropped the weak reference here will become invalid, and will be removed
-    /// from the list opportunistically the next time `add_vm` is called.
-    vms: Vec<Weak<VmInstance>>,
-}
-
-impl State {
-    /// Get a list of VMs which still have Binder references to them.
-    fn vms(&self) -> Vec<Arc<VmInstance>> {
-        // Attempt to upgrade the weak pointers to strong pointers.
-        self.vms.iter().filter_map(Weak::upgrade).collect()
-    }
-
-    /// Add a new VM to the list.
-    fn add_vm(&mut self, vm: Weak<VmInstance>) {
-        // Garbage collect any entries from the stored list which no longer exist.
-        self.vms.retain(|vm| vm.strong_count() > 0);
-
-        // Actually add the new VM.
-        self.vms.push(vm);
-    }
-
-    /// Get a VM that corresponds to the given cid
-    fn get_vm(&self, cid: Cid) -> Option<Arc<VmInstance>> {
-        self.vms().into_iter().find(|vm| vm.cid == cid)
-    }
-}
-
-/// Gets the `VirtualMachineState` of the given `VmInstance`.
-fn get_state(instance: &VmInstance) -> VirtualMachineState {
-    match &*instance.vm_state.lock().unwrap() {
-        VmState::NotStarted { .. } => VirtualMachineState::NOT_STARTED,
-        VmState::Running { .. } => match instance.payload_state() {
-            PayloadState::Starting => VirtualMachineState::STARTING,
-            PayloadState::Started => VirtualMachineState::STARTED,
-            PayloadState::Ready => VirtualMachineState::READY,
-            PayloadState::Finished => VirtualMachineState::FINISHED,
-            PayloadState::Hangup => VirtualMachineState::DEAD,
-        },
-        VmState::Dead => VirtualMachineState::DEAD,
-        VmState::Failed => VirtualMachineState::DEAD,
-    }
-}
-
-/// 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()
-}
-
-/// Converts a `VsockStream` to a `ParcelFileDescriptor`.
-fn vsock_stream_to_pfd(stream: VsockStream) -> ParcelFileDescriptor {
-    // SAFETY: ownership is transferred from stream to f
-    let f = unsafe { File::from_raw_fd(stream.into_raw_fd()) };
-    ParcelFileDescriptor::new(f)
-}
-
-/// Parses the platform version requirement string.
-fn parse_platform_version_req(s: &str) -> Result<VersionReq, Status> {
-    VersionReq::parse(s).map_err(|e| {
-        Status::new_exception_str(
-            ExceptionCode::BAD_PARCELABLE,
-            Some(format!("Invalid platform version requirement {}: {:?}", s, e)),
-        )
-    })
-}
-
-fn is_debuggable(config: &VirtualMachineConfig) -> bool {
-    match config {
-        VirtualMachineConfig::AppConfig(config) => config.debugLevel != DebugLevel::NONE,
-        _ => false,
-    }
-}
-
-fn clone_or_prepare_logger_fd(
-    config: &VirtualMachineConfig,
-    fd: Option<&ParcelFileDescriptor>,
-    tag: String,
-) -> Result<Option<File>, Status> {
-    if let Some(fd) = fd {
-        return Ok(Some(clone_file(fd)?));
-    }
-
-    if !is_debuggable(config) {
-        return Ok(None);
-    }
-
-    let (raw_read_fd, raw_write_fd) = pipe().map_err(|e| {
-        Status::new_service_specific_error_str(-1, Some(format!("Failed to create pipe: {:?}", e)))
-    })?;
-
-    // SAFETY: We are the sole owners of these fds as they were just created.
-    let mut reader = BufReader::new(unsafe { File::from_raw_fd(raw_read_fd) });
-    let write_fd = unsafe { File::from_raw_fd(raw_write_fd) };
-
-    std::thread::spawn(move || loop {
-        let mut buf = vec![];
-        match reader.read_until(b'\n', &mut buf) {
-            Ok(0) => {
-                // EOF
-                return;
-            }
-            Ok(size) => {
-                if buf[size - 1] == b'\n' {
-                    buf.pop();
-                }
-                info!("{}: {}", &tag, &String::from_utf8_lossy(&buf));
-            }
-            Err(e) => {
-                error!("Could not read console pipe: {:?}", e);
-                return;
-            }
-        };
-    });
-
-    Ok(Some(write_fd))
-}
-
-/// Simple utility for referencing Borrowed or Owned. Similar to std::borrow::Cow, but
-/// it doesn't require that T implements Clone.
-enum BorrowedOrOwned<'a, T> {
-    Borrowed(&'a T),
-    Owned(T),
-}
-
-impl<'a, T> AsRef<T> for BorrowedOrOwned<'a, T> {
-    fn as_ref(&self) -> &T {
-        match self {
-            Self::Borrowed(b) => b,
-            Self::Owned(o) => o,
-        }
-    }
-}
-
-/// Implementation of `IVirtualMachineService`, the entry point of the AIDL service.
-#[derive(Debug, Default)]
-struct VirtualMachineService {
-    state: Arc<Mutex<State>>,
-    cid: Cid,
-}
-
-impl Interface for VirtualMachineService {}
-
-impl IVirtualMachineService for VirtualMachineService {
-    fn notifyPayloadStarted(&self) -> binder::Result<()> {
-        let cid = self.cid;
-        if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
-            info!("VM with CID {} started payload", cid);
-            vm.update_payload_state(PayloadState::Started).map_err(|e| {
-                Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some(e.to_string()))
-            })?;
-            vm.callbacks.notify_payload_started(cid);
-
-            let vm_start_timestamp = vm.vm_metric.lock().unwrap().start_timestamp;
-            write_vm_booted_stats(vm.requester_uid as i32, &vm.name, vm_start_timestamp);
-            Ok(())
-        } else {
-            error!("notifyPayloadStarted is called from an unknown CID {}", cid);
-            Err(Status::new_service_specific_error_str(
-                -1,
-                Some(format!("cannot find a VM with CID {}", cid)),
-            ))
-        }
-    }
-
-    fn notifyPayloadReady(&self) -> binder::Result<()> {
-        let cid = self.cid;
-        if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
-            info!("VM with CID {} reported payload is ready", cid);
-            vm.update_payload_state(PayloadState::Ready).map_err(|e| {
-                Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some(e.to_string()))
-            })?;
-            vm.callbacks.notify_payload_ready(cid);
-            Ok(())
-        } else {
-            error!("notifyPayloadReady is called from an unknown CID {}", cid);
-            Err(Status::new_service_specific_error_str(
-                -1,
-                Some(format!("cannot find a VM with CID {}", cid)),
-            ))
-        }
-    }
-
-    fn notifyPayloadFinished(&self, exit_code: i32) -> binder::Result<()> {
-        let cid = self.cid;
-        if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
-            info!("VM with CID {} finished payload", cid);
-            vm.update_payload_state(PayloadState::Finished).map_err(|e| {
-                Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some(e.to_string()))
-            })?;
-            vm.callbacks.notify_payload_finished(cid, exit_code);
-            Ok(())
-        } else {
-            error!("notifyPayloadFinished is called from an unknown CID {}", cid);
-            Err(Status::new_service_specific_error_str(
-                -1,
-                Some(format!("cannot find a VM with CID {}", cid)),
-            ))
-        }
-    }
-
-    fn notifyError(&self, error_code: ErrorCode, message: &str) -> binder::Result<()> {
-        let cid = self.cid;
-        if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
-            info!("VM with CID {} encountered an error", cid);
-            vm.update_payload_state(PayloadState::Finished).map_err(|e| {
-                Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some(e.to_string()))
-            })?;
-            vm.callbacks.notify_error(cid, error_code, message);
-            Ok(())
-        } else {
-            error!("notifyError is called from an unknown CID {}", cid);
-            Err(Status::new_service_specific_error_str(
-                -1,
-                Some(format!("cannot find a VM with CID {}", cid)),
-            ))
-        }
-    }
-}
-
-impl VirtualMachineService {
-    fn new_binder(state: Arc<Mutex<State>>, cid: Cid) -> Strong<dyn IVirtualMachineService> {
-        BnVirtualMachineService::new_binder(
-            VirtualMachineService { state, cid },
-            BinderFeatures::default(),
-        )
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_is_allowed_label_for_partition() -> Result<()> {
-        let expected_results = vec![
-            ("u:object_r:system_file:s0", true),
-            ("u:object_r:apk_data_file:s0", true),
-            ("u:object_r:app_data_file:s0", false),
-            ("u:object_r:app_data_file:s0:c512,c768", false),
-            ("u:object_r:privapp_data_file:s0:c512,c768", false),
-            ("invalid", false),
-            ("user:role:apk_data_file:severity:categories", true),
-            ("user:role:apk_data_file:severity:categories:extraneous", false),
-        ];
-
-        for (label, expected_valid) in expected_results {
-            let context = SeContext::new(label)?;
-            let result = check_label_is_allowed(&context);
-            if expected_valid {
-                assert!(result.is_ok(), "Expected label {} to be allowed, got {:?}", label, result);
-            } else if result.is_ok() {
-                bail!("Expected label {} to be disallowed", label);
-            }
-        }
-        Ok(())
-    }
-
-    #[test]
-    fn test_create_or_update_idsig_file_empty_apk() -> Result<()> {
-        let apk = tempfile::tempfile().unwrap();
-        let idsig = tempfile::tempfile().unwrap();
-
-        let ret = create_or_update_idsig_file(
-            &ParcelFileDescriptor::new(apk),
-            &ParcelFileDescriptor::new(idsig),
-        );
-        assert!(ret.is_err(), "should fail");
-        Ok(())
-    }
-
-    #[test]
-    fn test_create_or_update_idsig_dir_instead_of_file_for_apk() -> Result<()> {
-        let tmp_dir = tempfile::TempDir::new().unwrap();
-        let apk = File::open(tmp_dir.path()).unwrap();
-        let idsig = tempfile::tempfile().unwrap();
-
-        let ret = create_or_update_idsig_file(
-            &ParcelFileDescriptor::new(apk),
-            &ParcelFileDescriptor::new(idsig),
-        );
-        assert!(ret.is_err(), "should fail");
-        Ok(())
-    }
-
-    /// Verifies that create_or_update_idsig_file won't oom if a fd that corresponds to a directory
-    /// on ext4 filesystem is passed.
-    /// On ext4 lseek on a directory fd will return (off_t)-1 (see:
-    /// https://bugzilla.kernel.org/show_bug.cgi?id=200043), which will result in
-    /// create_or_update_idsig_file ooming while attempting to allocate petabytes of memory.
-    #[test]
-    fn test_create_or_update_idsig_does_not_crash_dir_on_ext4() -> Result<()> {
-        // APEXes are backed by the ext4.
-        let apk = File::open("/apex/com.android.virt/").unwrap();
-        let idsig = tempfile::tempfile().unwrap();
-
-        let ret = create_or_update_idsig_file(
-            &ParcelFileDescriptor::new(apk),
-            &ParcelFileDescriptor::new(idsig),
-        );
-        assert!(ret.is_err(), "should fail");
-        Ok(())
-    }
-}
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
deleted file mode 100644
index c33f262..0000000
--- a/virtualizationservice/src/atom.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2022, 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 for creating and collecting atoms.
-
-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;
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
-    IVirtualMachine::IVirtualMachine,
-    VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
-    VirtualMachineConfig::VirtualMachineConfig,
-};
-use android_system_virtualizationservice::binder::{Status, Strong};
-use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::{
-    AtomVmBooted::AtomVmBooted,
-    AtomVmCreationRequested::AtomVmCreationRequested,
-    AtomVmExited::AtomVmExited,
-};
-use anyhow::{anyhow, Result};
-use binder::ParcelFileDescriptor;
-use log::warn;
-use microdroid_payload_config::VmPayloadConfig;
-use statslog_virtualization_rust::vm_creation_requested;
-use std::thread;
-use std::time::{Duration, SystemTime};
-use zip::ZipArchive;
-
-fn get_apex_list(config: &VirtualMachineAppConfig) -> String {
-    match &config.payload {
-        Payload::PayloadConfig(_) => String::new(),
-        Payload::ConfigPath(config_path) => {
-            let vm_payload_config = get_vm_payload_config(&config.apk, config_path);
-            if let Ok(vm_payload_config) = vm_payload_config {
-                vm_payload_config
-                    .apexes
-                    .iter()
-                    .map(|x| x.name.clone())
-                    .collect::<Vec<String>>()
-                    .join(":")
-            } else {
-                "INFO: Can't get VmPayloadConfig".to_owned()
-            }
-        }
-    }
-}
-
-fn get_vm_payload_config(
-    apk_fd: &Option<ParcelFileDescriptor>,
-    config_path: &str,
-) -> Result<VmPayloadConfig> {
-    let apk = apk_fd.as_ref().ok_or_else(|| anyhow!("APK is none"))?;
-    let apk_file = clone_file(apk)?;
-    let mut apk_zip = ZipArchive::new(&apk_file)?;
-    let config_file = apk_zip.by_name(config_path)?;
-    let vm_payload_config: VmPayloadConfig = serde_json::from_reader(config_file)?;
-    Ok(vm_payload_config)
-}
-
-fn get_duration(vm_start_timestamp: Option<SystemTime>) -> Duration {
-    match vm_start_timestamp {
-        Some(vm_start_timestamp) => vm_start_timestamp.elapsed().unwrap_or_default(),
-        None => Duration::default(),
-    }
-}
-
-/// Write the stats of VMCreation to statsd
-pub fn write_vm_creation_stats(
-    config: &VirtualMachineConfig,
-    is_protected: bool,
-    ret: &binder::Result<Strong<dyn IVirtualMachine>>,
-) {
-    let creation_succeeded;
-    let binder_exception_code;
-    match ret {
-        Ok(_) => {
-            creation_succeeded = true;
-            binder_exception_code = Status::ok().exception_code() as i32;
-        }
-        Err(ref e) => {
-            creation_succeeded = false;
-            binder_exception_code = e.exception_code() as i32;
-        }
-    }
-    let (vm_identifier, config_type, num_cpus, memory_mib, apexes) = match config {
-        VirtualMachineConfig::AppConfig(config) => (
-            config.name.clone(),
-            vm_creation_requested::ConfigType::VirtualMachineAppConfig,
-            config.numCpus,
-            config.memoryMib,
-            get_apex_list(config),
-        ),
-        VirtualMachineConfig::RawConfig(config) => (
-            config.name.clone(),
-            vm_creation_requested::ConfigType::VirtualMachineRawConfig,
-            config.numCpus,
-            config.memoryMib,
-            String::new(),
-        ),
-    };
-
-    let atom = AtomVmCreationRequested {
-        uid: get_calling_uid() as i32,
-        vmIdentifier: vm_identifier,
-        isProtected: is_protected,
-        creationSucceeded: creation_succeeded,
-        binderExceptionCode: binder_exception_code,
-        configType: config_type as i32,
-        numCpus: num_cpus,
-        memoryMib: memory_mib,
-        apexes,
-    };
-
-    thread::spawn(move || {
-        GLOBAL_SERVICE.atomVmCreationRequested(&atom).unwrap_or_else(|e| {
-            warn!("Failed to write VmCreationRequested atom: {e}");
-        });
-    });
-}
-
-/// Write the stats of VM boot to statsd
-/// The function creates a separate thread which waits fro statsd to start to push atom
-pub fn write_vm_booted_stats(
-    uid: i32,
-    vm_identifier: &str,
-    vm_start_timestamp: Option<SystemTime>,
-) {
-    let vm_identifier = vm_identifier.to_owned();
-    let duration = get_duration(vm_start_timestamp);
-
-    let atom = AtomVmBooted {
-        uid,
-        vmIdentifier: vm_identifier,
-        elapsedTimeMillis: duration.as_millis() as i64,
-    };
-
-    thread::spawn(move || {
-        GLOBAL_SERVICE.atomVmBooted(&atom).unwrap_or_else(|e| {
-            warn!("Failed to write VmCreationRequested atom: {e}");
-        });
-    });
-}
-
-/// Write the stats of VM exit to statsd
-/// The function creates a separate thread which waits fro statsd to start to push atom
-pub fn write_vm_exited_stats(
-    uid: i32,
-    vm_identifier: &str,
-    reason: DeathReason,
-    exit_signal: Option<i32>,
-    vm_metric: &VmMetric,
-) {
-    let vm_identifier = vm_identifier.to_owned();
-    let elapsed_time_millis = get_duration(vm_metric.start_timestamp).as_millis() as i64;
-    let guest_time_millis = vm_metric.cpu_guest_time.unwrap_or_default();
-    let rss = vm_metric.rss.unwrap_or_default();
-
-    let atom = AtomVmExited {
-        uid,
-        vmIdentifier: vm_identifier,
-        elapsedTimeMillis: elapsed_time_millis,
-        deathReason: reason,
-        guestTimeMillis: guest_time_millis,
-        rssVmKb: rss.vm,
-        rssCrosvmKb: rss.crosvm,
-        exitSignal: exit_signal.unwrap_or_default(),
-    };
-
-    thread::spawn(move || {
-        GLOBAL_SERVICE.atomVmExited(&atom).unwrap_or_else(|e| {
-            warn!("Failed to write VmExited atom: {e}");
-        });
-    });
-}
diff --git a/virtualizationservice/src/composite.rs b/virtualizationservice/src/composite.rs
deleted file mode 100644
index fe17ff4..0000000
--- a/virtualizationservice/src/composite.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-// 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.
-
-//! Functions for creating a composite disk image.
-
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::Partition::Partition;
-use anyhow::{anyhow, Context, Error};
-use disk::{
-    create_composite_disk, create_disk_file, ImagePartitionType, PartitionInfo, MAX_NESTING_DEPTH,
-};
-use std::fs::{File, OpenOptions};
-use std::os::unix::io::AsRawFd;
-use std::path::{Path, PathBuf};
-
-/// Constructs a composite disk image for the given list of partitions, and opens it ready to use.
-///
-/// Returns the composite disk image file, and a list of files whose file descriptors must be passed
-/// to any process which wants to use it. This is necessary because the composite image contains
-/// paths of the form `/proc/self/fd/N` for the partition images.
-pub fn make_composite_image(
-    partitions: &[Partition],
-    zero_filler_path: &Path,
-    output_path: &Path,
-    header_path: &Path,
-    footer_path: &Path,
-) -> Result<(File, Vec<File>), Error> {
-    let (partitions, mut files) = convert_partitions(partitions)?;
-
-    let mut composite_image = OpenOptions::new()
-        .create_new(true)
-        .read(true)
-        .write(true)
-        .open(output_path)
-        .with_context(|| format!("Failed to create composite image {:?}", output_path))?;
-    let mut header_file =
-        OpenOptions::new().create_new(true).read(true).write(true).open(header_path).with_context(
-            || format!("Failed to create composite image header {:?}", header_path),
-        )?;
-    let mut footer_file =
-        OpenOptions::new().create_new(true).read(true).write(true).open(footer_path).with_context(
-            || format!("Failed to create composite image header {:?}", footer_path),
-        )?;
-    let zero_filler_file = File::open(zero_filler_path).with_context(|| {
-        format!("Failed to open composite image zero filler {:?}", zero_filler_path)
-    })?;
-
-    create_composite_disk(
-        &partitions,
-        &fd_path_for_file(&zero_filler_file),
-        &fd_path_for_file(&header_file),
-        &mut header_file,
-        &fd_path_for_file(&footer_file),
-        &mut footer_file,
-        &mut composite_image,
-    )?;
-
-    // Re-open the composite image as read-only.
-    let composite_image = File::open(output_path)
-        .with_context(|| format!("Failed to open composite image {:?}", output_path))?;
-
-    files.push(header_file);
-    files.push(footer_file);
-    files.push(zero_filler_file);
-
-    Ok((composite_image, files))
-}
-
-/// Given the AIDL config containing a list of partitions, with a [`ParcelFileDescriptor`] for each
-/// partition, returns the corresponding list of PartitionInfo and the list of files whose file
-/// descriptors must be passed to any process using the composite image.
-fn convert_partitions(partitions: &[Partition]) -> Result<(Vec<PartitionInfo>, Vec<File>), Error> {
-    // File descriptors to pass to child process.
-    let mut files = vec![];
-
-    let partitions = partitions
-        .iter()
-        .map(|partition| {
-            // TODO(b/187187765): This shouldn't be an Option.
-            let file = partition
-                .image
-                .as_ref()
-                .context("Invalid partition image file descriptor")?
-                .as_ref()
-                .try_clone()
-                .context("Failed to clone partition image file descriptor")?;
-            let path = fd_path_for_file(&file);
-            let size = get_partition_size(&file, &path)?;
-            files.push(file);
-
-            Ok(PartitionInfo {
-                label: partition.label.to_owned(),
-                path,
-                partition_type: ImagePartitionType::LinuxFilesystem,
-                writable: partition.writable,
-                size,
-            })
-        })
-        .collect::<Result<_, Error>>()?;
-
-    Ok((partitions, files))
-}
-
-fn fd_path_for_file(file: &File) -> PathBuf {
-    let fd = file.as_raw_fd();
-    format!("/proc/self/fd/{}", fd).into()
-}
-
-/// Find the size of the partition image in the given file by parsing the header.
-///
-/// This will work for raw, QCOW2, composite and Android sparse images.
-fn get_partition_size(partition: &File, path: &Path) -> Result<u64, Error> {
-    // TODO: Use `context` once disk::Error implements std::error::Error.
-    // TODO: Add check for is_sparse_file
-    Ok(create_disk_file(
-        partition.try_clone()?,
-        /* is_sparse_file */ false,
-        MAX_NESTING_DEPTH,
-        path,
-    )
-    .map_err(|e| anyhow!("Failed to open partition image: {}", e))?
-    .get_len()?)
-}
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
deleted file mode 100644
index 98e7d99..0000000
--- a/virtualizationservice/src/crosvm.rs
+++ /dev/null
@@ -1,861 +0,0 @@
-// 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.
-
-//! Functions for running instances of `crosvm`.
-
-use crate::aidl::{remove_temporary_files, Cid, VirtualMachineCallbacks};
-use crate::atom::write_vm_exited_stats;
-use anyhow::{anyhow, bail, Context, Error, Result};
-use command_fds::CommandFdExt;
-use lazy_static::lazy_static;
-use libc::{sysconf, _SC_CLK_TCK};
-use log::{debug, error, info};
-use semver::{Version, VersionReq};
-use nix::{fcntl::OFlag, unistd::pipe2, unistd::Uid, unistd::User};
-use regex::{Captures, Regex};
-use rustutils::system_properties;
-use shared_child::SharedChild;
-use std::borrow::Cow;
-use std::cmp::max;
-use std::fmt;
-use std::fs::{read_to_string, File};
-use std::io::{self, Read};
-use std::mem;
-use std::num::NonZeroU32;
-use std::os::unix::io::{AsRawFd, RawFd, FromRawFd};
-use std::os::unix::process::ExitStatusExt;
-use std::path::{Path, PathBuf};
-use std::process::{Command, ExitStatus};
-use std::sync::{Arc, Condvar, Mutex};
-use std::time::{Duration, SystemTime};
-use std::thread::{self, JoinHandle};
-use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::MemoryTrimLevel::MemoryTrimLevel;
-use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IGlobalVmContext::IGlobalVmContext;
-use binder::Strong;
-use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
-use tombstoned_client::{TombstonedConnection, DebuggerdDumpType};
-use rpcbinder::RpcServer;
-
-/// external/crosvm
-use base::UnixSeqpacketListener;
-use vm_control::{BalloonControlCommand, VmRequest, VmResponse};
-
-const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
-
-/// Version of the platform that crosvm currently implements. The format follows SemVer. This
-/// should be updated when there is a platform change in the crosvm side. Having this value here is
-/// fine because virtualizationservice and crosvm are supposed to be updated together in the virt
-/// APEX.
-const CROSVM_PLATFORM_VERSION: &str = "1.0.0";
-
-/// The exit status which crosvm returns when it has an error starting a VM.
-const CROSVM_START_ERROR_STATUS: i32 = 1;
-/// The exit status which crosvm returns when a VM requests a reboot.
-const CROSVM_REBOOT_STATUS: i32 = 32;
-/// The exit status which crosvm returns when it crashes due to an error.
-const CROSVM_CRASH_STATUS: i32 = 33;
-/// The exit status which crosvm returns when vcpu is stalled.
-const CROSVM_WATCHDOG_REBOOT_STATUS: i32 = 36;
-
-const MILLIS_PER_SEC: i64 = 1000;
-
-const SYSPROP_CUSTOM_PVMFW_PATH: &str = "hypervisor.pvmfw.path";
-
-lazy_static! {
-    /// If the VM doesn't move to the Started state within this amount time, a hang-up error is
-    /// triggered.
-    static ref BOOT_HANGUP_TIMEOUT: Duration = if nested_virt::is_nested_virtualization().unwrap() {
-        // Nested virtualization is slow, so we need a longer timeout.
-        Duration::from_secs(100)
-    } else {
-        Duration::from_secs(10)
-    };
-}
-
-/// Configuration for a VM to run with crosvm.
-#[derive(Debug)]
-pub struct CrosvmConfig {
-    pub cid: Cid,
-    pub name: String,
-    pub bootloader: Option<File>,
-    pub kernel: Option<File>,
-    pub initrd: Option<File>,
-    pub disks: Vec<DiskFile>,
-    pub params: Option<String>,
-    pub protected: bool,
-    pub memory_mib: Option<NonZeroU32>,
-    pub cpus: Option<NonZeroU32>,
-    pub task_profiles: Vec<String>,
-    pub console_fd: Option<File>,
-    pub log_fd: Option<File>,
-    pub ramdump: Option<File>,
-    pub indirect_files: Vec<File>,
-    pub platform_version: VersionReq,
-    pub detect_hangup: bool,
-}
-
-/// A disk image to pass to crosvm for a VM.
-#[derive(Debug)]
-pub struct DiskFile {
-    pub image: File,
-    pub writable: bool,
-}
-
-/// The lifecycle state which the payload in the VM has reported itself to be in.
-///
-/// Note that the order of enum variants is significant; only forward transitions are allowed by
-/// [`VmInstance::update_payload_state`].
-#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
-pub enum PayloadState {
-    Starting,
-    Started,
-    Ready,
-    Finished,
-    Hangup, // Hasn't reached to Ready before timeout expires
-}
-
-/// The current state of the VM itself.
-#[derive(Debug)]
-pub enum VmState {
-    /// The VM has not yet tried to start.
-    NotStarted {
-        ///The configuration needed to start the VM, if it has not yet been started.
-        config: CrosvmConfig,
-    },
-    /// The VM has been started.
-    Running {
-        /// The crosvm child process.
-        child: Arc<SharedChild>,
-        /// The thread waiting for crosvm to finish.
-        monitor_vm_exit_thread: Option<JoinHandle<()>>,
-    },
-    /// The VM died or was killed.
-    Dead,
-    /// The VM failed to start.
-    Failed,
-}
-
-/// RSS values of VM and CrosVM process itself.
-#[derive(Copy, Clone, Debug, Default)]
-pub struct Rss {
-    pub vm: i64,
-    pub crosvm: i64,
-}
-
-/// Metrics regarding the VM.
-#[derive(Debug, Default)]
-pub struct VmMetric {
-    /// Recorded timestamp when the VM is started.
-    pub start_timestamp: Option<SystemTime>,
-    /// Update most recent guest_time periodically from /proc/[crosvm pid]/stat while VM is running.
-    pub cpu_guest_time: Option<i64>,
-    /// Update maximum RSS values periodically from /proc/[crosvm pid]/smaps while VM is running.
-    pub rss: Option<Rss>,
-}
-
-impl VmState {
-    /// Tries to start the VM, if it is in the `NotStarted` state.
-    ///
-    /// Returns an error if the VM is in the wrong state, or fails to start.
-    fn start(&mut self, instance: Arc<VmInstance>) -> Result<(), Error> {
-        let state = mem::replace(self, VmState::Failed);
-        if let VmState::NotStarted { config } = state {
-            let detect_hangup = config.detect_hangup;
-            let (failure_pipe_read, failure_pipe_write) = create_pipe()?;
-
-            // If this fails and returns an error, `self` will be left in the `Failed` state.
-            let child =
-                Arc::new(run_vm(config, &instance.crosvm_control_socket_path, failure_pipe_write)?);
-
-            let instance_monitor_status = instance.clone();
-            let child_monitor_status = child.clone();
-            thread::spawn(move || {
-                instance_monitor_status.clone().monitor_vm_status(child_monitor_status);
-            });
-
-            let child_clone = child.clone();
-            let instance_clone = instance.clone();
-            let monitor_vm_exit_thread = Some(thread::spawn(move || {
-                instance_clone.monitor_vm_exit(child_clone, failure_pipe_read);
-            }));
-
-            if detect_hangup {
-                let child_clone = child.clone();
-                thread::spawn(move || {
-                    instance.monitor_payload_hangup(child_clone);
-                });
-            }
-
-            // If it started correctly, update the state.
-            *self = VmState::Running { child, monitor_vm_exit_thread };
-            Ok(())
-        } else {
-            *self = state;
-            bail!("VM already started or failed")
-        }
-    }
-}
-
-/// Internal struct that holds the handles to globally unique resources of a VM.
-#[derive(Debug)]
-pub struct VmContext {
-    #[allow(dead_code)] // Keeps the global context alive
-    global_context: Strong<dyn IGlobalVmContext>,
-    #[allow(dead_code)] // Keeps the server alive
-    vm_server: RpcServer,
-}
-
-impl VmContext {
-    /// Construct new VmContext.
-    pub fn new(global_context: Strong<dyn IGlobalVmContext>, vm_server: RpcServer) -> VmContext {
-        VmContext { global_context, vm_server }
-    }
-}
-
-/// Information about a particular instance of a VM which may be running.
-#[derive(Debug)]
-pub struct VmInstance {
-    /// The current state of the VM.
-    pub vm_state: Mutex<VmState>,
-    /// Global resources allocated for this VM.
-    #[allow(dead_code)] // Keeps the context alive
-    vm_context: VmContext,
-    /// The CID assigned to the VM for vsock communication.
-    pub cid: Cid,
-    /// Path to crosvm control socket
-    crosvm_control_socket_path: PathBuf,
-    /// The name of the VM.
-    pub name: String,
-    /// Whether the VM is a protected VM.
-    pub protected: bool,
-    /// Directory of temporary files used by the VM while it is running.
-    pub temporary_directory: PathBuf,
-    /// The UID of the process which requested the VM.
-    pub requester_uid: u32,
-    /// The PID of the process which requested the VM. Note that this process may no longer exist
-    /// and the PID may have been reused for a different process, so this should not be trusted.
-    pub requester_debug_pid: i32,
-    /// Callbacks to clients of the VM.
-    pub callbacks: VirtualMachineCallbacks,
-    /// VirtualMachineService binder object for the VM.
-    pub vm_service: Mutex<Option<Strong<dyn IVirtualMachineService>>>,
-    /// Recorded metrics of VM such as timestamp or cpu / memory usage.
-    pub vm_metric: Mutex<VmMetric>,
-    /// The latest lifecycle state which the payload reported itself to be in.
-    payload_state: Mutex<PayloadState>,
-    /// Represents the condition that payload_state was updated
-    payload_state_updated: Condvar,
-    /// The human readable name of requester_uid
-    requester_uid_name: String,
-}
-
-impl fmt::Display for VmInstance {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let adj = if self.protected { "Protected" } else { "Non-protected" };
-        write!(
-            f,
-            "{} virtual machine \"{}\" (owner: {}, cid: {})",
-            adj, self.name, self.requester_uid_name, self.cid
-        )
-    }
-}
-
-impl VmInstance {
-    /// Validates the given config and creates a new `VmInstance` but doesn't start running it.
-    pub fn new(
-        config: CrosvmConfig,
-        temporary_directory: PathBuf,
-        requester_uid: u32,
-        requester_debug_pid: i32,
-        vm_context: VmContext,
-    ) -> Result<VmInstance, Error> {
-        validate_config(&config)?;
-        let cid = config.cid;
-        let name = config.name.clone();
-        let protected = config.protected;
-        let requester_uid_name = User::from_uid(Uid::from_raw(requester_uid))
-            .ok()
-            .flatten()
-            .map_or_else(|| format!("{}", requester_uid), |u| u.name);
-        let instance = VmInstance {
-            vm_state: Mutex::new(VmState::NotStarted { config }),
-            vm_context,
-            cid,
-            crosvm_control_socket_path: temporary_directory.join("crosvm.sock"),
-            name,
-            protected,
-            temporary_directory,
-            requester_uid,
-            requester_debug_pid,
-            callbacks: Default::default(),
-            vm_service: Mutex::new(None),
-            vm_metric: Mutex::new(Default::default()),
-            payload_state: Mutex::new(PayloadState::Starting),
-            payload_state_updated: Condvar::new(),
-            requester_uid_name,
-        };
-        info!("{} created", &instance);
-        Ok(instance)
-    }
-
-    /// Starts an instance of `crosvm` to manage the VM. The `crosvm` instance will be killed when
-    /// the `VmInstance` is dropped.
-    pub fn start(self: &Arc<Self>) -> Result<(), Error> {
-        let mut vm_metric = self.vm_metric.lock().unwrap();
-        vm_metric.start_timestamp = Some(SystemTime::now());
-        let ret = self.vm_state.lock().unwrap().start(self.clone());
-        if ret.is_ok() {
-            info!("{} started", &self);
-        }
-        ret.with_context(|| format!("{} failed to start", &self))
-    }
-
-    /// Monitors the exit of the VM (i.e. termination of the `child` process). When that happens,
-    /// handles the event by updating the state, noityfing the event to clients by calling
-    /// callbacks, and removing temporary files for the VM.
-    fn monitor_vm_exit(&self, child: Arc<SharedChild>, mut failure_pipe_read: File) {
-        let result = child.wait();
-        match &result {
-            Err(e) => error!("Error waiting for crosvm({}) instance to die: {}", child.id(), e),
-            Ok(status) => {
-                info!("crosvm({}) exited with status {}", child.id(), status);
-                if let Some(exit_status_code) = status.code() {
-                    if exit_status_code == CROSVM_WATCHDOG_REBOOT_STATUS {
-                        info!("detected vcpu stall on crosvm");
-                    }
-                }
-            }
-        }
-
-        let mut vm_state = self.vm_state.lock().unwrap();
-        *vm_state = VmState::Dead;
-        // Ensure that the mutex is released before calling the callbacks.
-        drop(vm_state);
-        info!("{} exited", &self);
-
-        // Read the pipe to see if any failure reason is written
-        let mut failure_reason = String::new();
-        match failure_pipe_read.read_to_string(&mut failure_reason) {
-            Err(e) => error!("Error reading VM failure reason from pipe: {}", e),
-            Ok(len) if len > 0 => info!("VM returned failure reason '{}'", &failure_reason),
-            _ => (),
-        };
-
-        // In case of hangup, the pipe doesn't give us any information because the hangup can't be
-        // detected on the VM side (otherwise, it isn't a hangup), but in the
-        // monitor_payload_hangup function below which updates the payload state to Hangup.
-        let failure_reason =
-            if failure_reason.is_empty() && self.payload_state() == PayloadState::Hangup {
-                Cow::from("HANGUP")
-            } else {
-                Cow::from(failure_reason)
-            };
-
-        self.handle_ramdump().unwrap_or_else(|e| error!("Error handling ramdump: {}", e));
-
-        let death_reason = death_reason(&result, &failure_reason);
-        let exit_signal = exit_signal(&result);
-
-        self.callbacks.callback_on_died(self.cid, death_reason);
-
-        let vm_metric = self.vm_metric.lock().unwrap();
-        write_vm_exited_stats(
-            self.requester_uid as i32,
-            &self.name,
-            death_reason,
-            exit_signal,
-            &*vm_metric,
-        );
-
-        // Delete temporary files. The folder itself is removed by VirtualizationServiceInternal.
-        remove_temporary_files(&self.temporary_directory).unwrap_or_else(|e| {
-            error!("Error removing temporary files from {:?}: {}", self.temporary_directory, e);
-        });
-    }
-
-    /// Waits until payload is started, or timeout expires. When timeout occurs, kill
-    /// the VM to prevent indefinite hangup and update the payload_state accordingly.
-    fn monitor_payload_hangup(&self, child: Arc<SharedChild>) {
-        debug!("Starting to monitor hangup for Microdroid({})", child.id());
-        let (_, result) = self
-            .payload_state_updated
-            .wait_timeout_while(self.payload_state.lock().unwrap(), *BOOT_HANGUP_TIMEOUT, |s| {
-                *s < PayloadState::Started
-            })
-            .unwrap();
-        let child_still_running = child.try_wait().ok() == Some(None);
-        if result.timed_out() && child_still_running {
-            error!(
-                "Microdroid({}) failed to start payload within {} secs timeout. Shutting down.",
-                child.id(),
-                BOOT_HANGUP_TIMEOUT.as_secs()
-            );
-            self.update_payload_state(PayloadState::Hangup).unwrap();
-            if let Err(e) = self.kill() {
-                error!("Error stopping timed-out VM with CID {}: {:?}", child.id(), e);
-            }
-        }
-    }
-
-    fn monitor_vm_status(&self, child: Arc<SharedChild>) {
-        let pid = child.id();
-
-        loop {
-            {
-                // Check VM state
-                let vm_state = &*self.vm_state.lock().unwrap();
-                if let VmState::Dead = vm_state {
-                    break;
-                }
-
-                let mut vm_metric = self.vm_metric.lock().unwrap();
-
-                // Get CPU Information
-                if let Ok(guest_time) = get_guest_time(pid) {
-                    vm_metric.cpu_guest_time = Some(guest_time);
-                } else {
-                    error!("Failed to parse /proc/[pid]/stat");
-                }
-
-                // Get Memory Information
-                if let Ok(rss) = get_rss(pid) {
-                    vm_metric.rss = match &vm_metric.rss {
-                        Some(x) => Some(Rss::extract_max(x, &rss)),
-                        None => Some(rss),
-                    }
-                } else {
-                    error!("Failed to parse /proc/[pid]/smaps");
-                }
-            }
-
-            thread::sleep(Duration::from_secs(1));
-        }
-    }
-
-    /// Returns the last reported state of the VM payload.
-    pub fn payload_state(&self) -> PayloadState {
-        *self.payload_state.lock().unwrap()
-    }
-
-    /// Updates the payload state to the given value, if it is a valid state transition.
-    pub fn update_payload_state(&self, new_state: PayloadState) -> Result<(), Error> {
-        let mut state_locked = self.payload_state.lock().unwrap();
-        // Only allow forward transitions, e.g. from starting to started or finished, not back in
-        // the other direction.
-        if new_state > *state_locked {
-            *state_locked = new_state;
-            self.payload_state_updated.notify_all();
-            Ok(())
-        } else {
-            bail!("Invalid payload state transition from {:?} to {:?}", *state_locked, new_state)
-        }
-    }
-
-    /// Kills the crosvm instance, if it is running.
-    pub fn kill(&self) -> Result<(), Error> {
-        let monitor_vm_exit_thread = {
-            let vm_state = &mut *self.vm_state.lock().unwrap();
-            if let VmState::Running { child, monitor_vm_exit_thread } = vm_state {
-                let id = child.id();
-                debug!("Killing crosvm({})", id);
-                // TODO: Talk to crosvm to shutdown cleanly.
-                child.kill().with_context(|| format!("Error killing crosvm({id}) instance"))?;
-                monitor_vm_exit_thread.take()
-            } else {
-                bail!("VM is not running")
-            }
-        };
-
-        // Wait for monitor_vm_exit() to finish. Must release vm_state lock
-        // first, as monitor_vm_exit() takes it as well.
-        monitor_vm_exit_thread.map(JoinHandle::join);
-
-        Ok(())
-    }
-
-    /// Responds to memory-trimming notifications by inflating the virtio
-    /// balloon to reclaim guest memory.
-    pub fn trim_memory(&self, level: MemoryTrimLevel) -> Result<(), Error> {
-        let request = VmRequest::BalloonCommand(BalloonControlCommand::Stats {});
-        match vm_control::client::handle_request(&request, &self.crosvm_control_socket_path) {
-            Ok(VmResponse::BalloonStats { stats, balloon_actual: _ }) => {
-                if let Some(total_memory) = stats.total_memory {
-                    // Reclaim up to 50% of total memory assuming worst case
-                    // most memory is anonymous and must be swapped to zram
-                    // with an approximate 2:1 compression ratio.
-                    let pct = match level {
-                        MemoryTrimLevel::TRIM_MEMORY_RUNNING_CRITICAL => 50,
-                        MemoryTrimLevel::TRIM_MEMORY_RUNNING_LOW => 30,
-                        MemoryTrimLevel::TRIM_MEMORY_RUNNING_MODERATE => 10,
-                        _ => bail!("Invalid memory trim level {:?}", level),
-                    };
-                    let command =
-                        BalloonControlCommand::Adjust { num_bytes: total_memory * pct / 100 };
-                    if let Err(e) = vm_control::client::handle_request(
-                        &VmRequest::BalloonCommand(command),
-                        &self.crosvm_control_socket_path,
-                    ) {
-                        bail!("Error sending balloon adjustment: {:?}", e);
-                    }
-                }
-            }
-            Ok(VmResponse::Err(e)) => {
-                // ENOTSUP is returned when the balloon protocol is not initialised. This
-                // can occur for numerous reasons: Guest is still booting, guest doesn't
-                // support ballooning, host doesn't support ballooning. We don't log or
-                // raise an error in this case: trim is just a hint and we can ignore it.
-                if e.errno() != libc::ENOTSUP {
-                    bail!("Errno return when requesting balloon stats: {}", e.errno())
-                }
-            }
-            e => bail!("Error requesting balloon stats: {:?}", e),
-        }
-        Ok(())
-    }
-
-    /// Checks if ramdump has been created. If so, send it to tombstoned.
-    fn handle_ramdump(&self) -> Result<(), Error> {
-        let ramdump_path = self.temporary_directory.join("ramdump");
-        if std::fs::metadata(&ramdump_path)?.len() > 0 {
-            Self::send_ramdump_to_tombstoned(&ramdump_path)?;
-        }
-        Ok(())
-    }
-
-    fn send_ramdump_to_tombstoned(ramdump_path: &Path) -> Result<(), Error> {
-        let mut input = File::open(ramdump_path)
-            .context(format!("Failed to open ramdump {:?} for reading", ramdump_path))?;
-
-        let pid = std::process::id() as i32;
-        let conn = TombstonedConnection::connect(pid, DebuggerdDumpType::Tombstone)
-            .context("Failed to connect to tombstoned")?;
-        let mut output = conn
-            .text_output
-            .as_ref()
-            .ok_or_else(|| anyhow!("Could not get file to write the tombstones on"))?;
-
-        std::io::copy(&mut input, &mut output).context("Failed to send ramdump to tombstoned")?;
-        info!("Ramdump {:?} sent to tombstoned", ramdump_path);
-
-        conn.notify_completion()?;
-        Ok(())
-    }
-}
-
-impl Rss {
-    fn extract_max(x: &Rss, y: &Rss) -> Rss {
-        Rss { vm: max(x.vm, y.vm), crosvm: max(x.crosvm, y.crosvm) }
-    }
-}
-
-// Get guest time from /proc/[crosvm pid]/stat
-fn get_guest_time(pid: u32) -> Result<i64> {
-    let file = read_to_string(format!("/proc/{}/stat", pid))?;
-    let data_list: Vec<_> = file.split_whitespace().collect();
-
-    // Information about guest_time is at 43th place of the file split with the whitespace.
-    // Example of /proc/[pid]/stat :
-    // 6603 (kworker/104:1H-kblockd) I 2 0 0 0 -1 69238880 0 0 0 0 0 88 0 0 0 -20 1 0 1845 0 0
-    // 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 104 0 0 0 0 0 0 0 0 0 0 0 0 0
-    if data_list.len() < 43 {
-        bail!("Failed to parse command result for getting guest time : {}", file);
-    }
-
-    let guest_time_ticks = data_list[42].parse::<i64>()?;
-    // SAFETY : It just returns an integer about CPU tick information.
-    let ticks_per_sec = unsafe { sysconf(_SC_CLK_TCK) } as i64;
-    Ok(guest_time_ticks * MILLIS_PER_SEC / ticks_per_sec)
-}
-
-// Get rss from /proc/[crosvm pid]/smaps
-fn get_rss(pid: u32) -> Result<Rss> {
-    let file = read_to_string(format!("/proc/{}/smaps", pid))?;
-    let lines: Vec<_> = file.split('\n').collect();
-
-    let mut rss_vm_total = 0i64;
-    let mut rss_crosvm_total = 0i64;
-    let mut is_vm = false;
-    for line in lines {
-        if line.contains("crosvm_guest") {
-            is_vm = true;
-        } else if line.contains("Rss:") {
-            let data_list: Vec<_> = line.split_whitespace().collect();
-            if data_list.len() < 2 {
-                bail!("Failed to parse command result for getting rss :\n{}", line);
-            }
-            let rss = data_list[1].parse::<i64>()?;
-
-            if is_vm {
-                rss_vm_total += rss;
-                is_vm = false;
-            }
-            rss_crosvm_total += rss;
-        }
-    }
-
-    Ok(Rss { vm: rss_vm_total, crosvm: rss_crosvm_total })
-}
-
-fn death_reason(result: &Result<ExitStatus, io::Error>, mut failure_reason: &str) -> DeathReason {
-    if let Some(position) = failure_reason.find('|') {
-        // Separator indicates extra context information is present after the failure name.
-        error!("Failure info: {}", &failure_reason[(position + 1)..]);
-        failure_reason = &failure_reason[..position];
-    }
-    if let Ok(status) = result {
-        match failure_reason {
-            "PVM_FIRMWARE_PUBLIC_KEY_MISMATCH" => {
-                return DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH
-            }
-            "PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED" => {
-                return DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED
-            }
-            "BOOTLOADER_PUBLIC_KEY_MISMATCH" => return DeathReason::BOOTLOADER_PUBLIC_KEY_MISMATCH,
-            "BOOTLOADER_INSTANCE_IMAGE_CHANGED" => {
-                return DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED
-            }
-            "MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE" => {
-                return DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE
-            }
-            "MICRODROID_PAYLOAD_HAS_CHANGED" => return DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED,
-            "MICRODROID_PAYLOAD_VERIFICATION_FAILED" => {
-                return DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED
-            }
-            "MICRODROID_INVALID_PAYLOAD_CONFIG" => {
-                return DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG
-            }
-            "MICRODROID_UNKNOWN_RUNTIME_ERROR" => {
-                return DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR
-            }
-            "HANGUP" => return DeathReason::HANGUP,
-            _ => {}
-        }
-        match status.code() {
-            None => DeathReason::KILLED,
-            Some(0) => DeathReason::SHUTDOWN,
-            Some(CROSVM_START_ERROR_STATUS) => DeathReason::START_FAILED,
-            Some(CROSVM_REBOOT_STATUS) => DeathReason::REBOOT,
-            Some(CROSVM_CRASH_STATUS) => DeathReason::CRASH,
-            Some(CROSVM_WATCHDOG_REBOOT_STATUS) => DeathReason::WATCHDOG_REBOOT,
-            Some(_) => DeathReason::UNKNOWN,
-        }
-    } else {
-        DeathReason::INFRASTRUCTURE_ERROR
-    }
-}
-
-fn exit_signal(result: &Result<ExitStatus, io::Error>) -> Option<i32> {
-    match result {
-        Ok(status) => status.signal(),
-        Err(_) => None,
-    }
-}
-
-/// Starts an instance of `crosvm` to manage a new VM.
-fn run_vm(
-    config: CrosvmConfig,
-    crosvm_control_socket_path: &Path,
-    failure_pipe_write: File,
-) -> Result<SharedChild, Error> {
-    validate_config(&config)?;
-
-    let mut command = Command::new(CROSVM_PATH);
-    // TODO(qwandor): Remove --disable-sandbox.
-    command
-        .arg("--extended-status")
-        // Configure the logger for the crosvm process to silence logs from the disk crate which
-        // don't provide much information to us (but do spamming us).
-        .arg("--log-level")
-        .arg("info,disk=off")
-        .arg("run")
-        .arg("--disable-sandbox")
-        .arg("--cid")
-        .arg(config.cid.to_string());
-
-    if system_properties::read_bool("hypervisor.memory_reclaim.supported", false)? {
-        command.arg("--balloon-page-reporting");
-    } else {
-        command.arg("--no-balloon");
-    }
-
-    if config.protected {
-        match system_properties::read(SYSPROP_CUSTOM_PVMFW_PATH)? {
-            Some(pvmfw_path) if !pvmfw_path.is_empty() => {
-                command.arg("--protected-vm-with-firmware").arg(pvmfw_path)
-            }
-            _ => command.arg("--protected-vm"),
-        };
-
-        // 3 virtio-console devices + vsock = 4.
-        let virtio_pci_device_count = 4 + config.disks.len();
-        // crosvm virtio queue has 256 entries, so 2 MiB per device (2 pages per entry) should be
-        // enough.
-        let swiotlb_size_mib = 2 * virtio_pci_device_count;
-        command.arg("--swiotlb").arg(swiotlb_size_mib.to_string());
-    }
-
-    if let Some(memory_mib) = config.memory_mib {
-        command.arg("--mem").arg(memory_mib.to_string());
-    }
-
-    if let Some(cpus) = config.cpus {
-        command.arg("--cpus").arg(cpus.to_string());
-    }
-
-    if !config.task_profiles.is_empty() {
-        command.arg("--task-profiles").arg(config.task_profiles.join(","));
-    }
-
-    // Keep track of what file descriptors should be mapped to the crosvm process.
-    let mut preserved_fds = config.indirect_files.iter().map(|file| file.as_raw_fd()).collect();
-
-    // Setup the serial devices.
-    // 1. uart device: used as the output device by bootloaders and as early console by linux
-    // 2. uart device: used to report the reason for the VM failing.
-    // 3. virtio-console device: used as the console device where kmsg is redirected to
-    // 4. virtio-console device: used as the ramdump output
-    // 5. virtio-console device: used as the logcat output
-    //
-    // When [console|log]_fd is not specified, the devices are attached to sink, which means what's
-    // written there is discarded.
-    let console_arg = format_serial_arg(&mut preserved_fds, &config.console_fd);
-    let log_arg = format_serial_arg(&mut preserved_fds, &config.log_fd);
-    let failure_serial_path = add_preserved_fd(&mut preserved_fds, &failure_pipe_write);
-    let ramdump_arg = format_serial_arg(&mut preserved_fds, &config.ramdump);
-
-    // Warning: Adding more serial devices requires you to shift the PCI device ID of the boot
-    // disks in bootconfig.x86_64. This is because x86 crosvm puts serial devices and the block
-    // devices in the same PCI bus and serial devices comes before the block devices. Arm crosvm
-    // doesn't have the issue.
-    // /dev/ttyS0
-    command.arg(format!("--serial={},hardware=serial,num=1", &console_arg));
-    // /dev/ttyS1
-    command.arg(format!("--serial=type=file,path={},hardware=serial,num=2", &failure_serial_path));
-    // /dev/hvc0
-    command.arg(format!("--serial={},hardware=virtio-console,num=1", &console_arg));
-    // /dev/hvc1
-    command.arg(format!("--serial={},hardware=virtio-console,num=2", &ramdump_arg));
-    // /dev/hvc2
-    command.arg(format!("--serial={},hardware=virtio-console,num=3", &log_arg));
-
-    if let Some(bootloader) = &config.bootloader {
-        command.arg("--bios").arg(add_preserved_fd(&mut preserved_fds, bootloader));
-    }
-
-    if let Some(initrd) = &config.initrd {
-        command.arg("--initrd").arg(add_preserved_fd(&mut preserved_fds, initrd));
-    }
-
-    if let Some(params) = &config.params {
-        command.arg("--params").arg(params);
-    }
-
-    for disk in &config.disks {
-        command
-            .arg(if disk.writable { "--rwdisk" } else { "--disk" })
-            .arg(add_preserved_fd(&mut preserved_fds, &disk.image));
-    }
-
-    if let Some(kernel) = &config.kernel {
-        command.arg(add_preserved_fd(&mut preserved_fds, kernel));
-    }
-
-    let control_server_socket = UnixSeqpacketListener::bind(crosvm_control_socket_path)
-        .context("failed to create control server")?;
-    command.arg("--socket").arg(add_preserved_fd(&mut preserved_fds, &control_server_socket));
-
-    debug!("Preserving FDs {:?}", preserved_fds);
-    command.preserved_fds(preserved_fds);
-
-    command.arg("--params").arg("crashkernel=17M");
-    print_crosvm_args(&command);
-
-    let result = SharedChild::spawn(&mut command)?;
-    debug!("Spawned crosvm({}).", result.id());
-    Ok(result)
-}
-
-/// Ensure that the configuration has a valid combination of fields set, or return an error if not.
-fn validate_config(config: &CrosvmConfig) -> Result<(), Error> {
-    if config.bootloader.is_none() && config.kernel.is_none() {
-        bail!("VM must have either a bootloader or a kernel image.");
-    }
-    if config.bootloader.is_some() && (config.kernel.is_some() || config.initrd.is_some()) {
-        bail!("Can't have both bootloader and kernel/initrd image.");
-    }
-    let version = Version::parse(CROSVM_PLATFORM_VERSION).unwrap();
-    if !config.platform_version.matches(&version) {
-        bail!(
-            "Incompatible platform version. The config is compatible with platform version(s) \
-              {}, but the actual platform version is {}",
-            config.platform_version,
-            version
-        );
-    }
-
-    Ok(())
-}
-
-/// Print arguments of the crosvm command. In doing so, /proc/self/fd/XX is annotated with the
-/// actual file path if the FD is backed by a regular file. If not, the /proc path is printed
-/// unmodified.
-fn print_crosvm_args(command: &Command) {
-    let re = Regex::new(r"/proc/self/fd/[\d]+").unwrap();
-    info!(
-        "Running crosvm with args: {:?}",
-        command
-            .get_args()
-            .map(|s| s.to_string_lossy())
-            .map(|s| {
-                re.replace_all(&s, |caps: &Captures| {
-                    let path = &caps[0];
-                    if let Ok(realpath) = std::fs::canonicalize(path) {
-                        format!("{} ({})", path, realpath.to_string_lossy())
-                    } else {
-                        path.to_owned()
-                    }
-                })
-                .into_owned()
-            })
-            .collect::<Vec<_>>()
-    );
-}
-
-/// Adds the file descriptor for `file` to `preserved_fds`, and returns a string of the form
-/// "/proc/self/fd/N" where N is the file descriptor.
-fn add_preserved_fd(preserved_fds: &mut Vec<RawFd>, file: &dyn AsRawFd) -> String {
-    let fd = file.as_raw_fd();
-    preserved_fds.push(fd);
-    format!("/proc/self/fd/{}", fd)
-}
-
-/// Adds the file descriptor for `file` (if any) to `preserved_fds`, and returns the appropriate
-/// string for a crosvm `--serial` flag. If `file` is none, creates a dummy sink device.
-fn format_serial_arg(preserved_fds: &mut Vec<RawFd>, file: &Option<File>) -> String {
-    if let Some(file) = file {
-        format!("type=file,path={}", add_preserved_fd(preserved_fds, file))
-    } else {
-        "type=sink".to_string()
-    }
-}
-
-/// Creates a new pipe with the `O_CLOEXEC` flag set, and returns the read side and write side.
-fn create_pipe() -> Result<(File, File), Error> {
-    let (raw_read, raw_write) = pipe2(OFlag::O_CLOEXEC)?;
-    // SAFETY: We are the sole owners of these fds as they were just created.
-    let read_fd = unsafe { File::from_raw_fd(raw_read) };
-    let write_fd = unsafe { File::from_raw_fd(raw_write) };
-    Ok((read_fd, write_fd))
-}
diff --git a/virtualizationservice/src/payload.rs b/virtualizationservice/src/payload.rs
deleted file mode 100644
index 02e8f8e..0000000
--- a/virtualizationservice/src/payload.rs
+++ /dev/null
@@ -1,684 +0,0 @@
-// 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.
-
-//! Payload disk image
-
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
-    DiskImage::DiskImage,
-    Partition::Partition,
-    VirtualMachineAppConfig::DebugLevel::DebugLevel,
-    VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
-    VirtualMachineRawConfig::VirtualMachineRawConfig,
-};
-use anyhow::{anyhow, bail, Context, Result};
-use binder::{wait_for_interface, ParcelFileDescriptor};
-use log::{info, warn};
-use microdroid_metadata::{ApexPayload, ApkPayload, Metadata, PayloadConfig, PayloadMetadata};
-use microdroid_payload_config::{ApexConfig, VmPayloadConfig};
-use once_cell::sync::OnceCell;
-use packagemanager_aidl::aidl::android::content::pm::{
-    IPackageManagerNative::IPackageManagerNative, StagedApexInfo::StagedApexInfo,
-};
-use regex::Regex;
-use serde::Deserialize;
-use serde_xml_rs::from_reader;
-use std::collections::HashSet;
-use std::fs::{metadata, File, OpenOptions};
-use std::path::{Path, PathBuf};
-use std::process::Command;
-use std::time::SystemTime;
-use vmconfig::open_parcel_file;
-
-/// The list of APEXes which microdroid requires.
-// TODO(b/192200378) move this to microdroid.json?
-const MICRODROID_REQUIRED_APEXES: [&str; 1] = ["com.android.os.statsd"];
-const MICRODROID_REQUIRED_APEXES_DEBUG: [&str; 1] = ["com.android.adbd"];
-
-const APEX_INFO_LIST_PATH: &str = "/apex/apex-info-list.xml";
-
-const PACKAGE_MANAGER_NATIVE_SERVICE: &str = "package_native";
-
-/// Represents the list of APEXes
-#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
-struct ApexInfoList {
-    #[serde(rename = "apex-info")]
-    list: Vec<ApexInfo>,
-}
-
-#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
-struct ApexInfo {
-    #[serde(rename = "moduleName")]
-    name: String,
-    #[serde(rename = "versionCode")]
-    version: u64,
-    #[serde(rename = "modulePath")]
-    path: PathBuf,
-
-    #[serde(default)]
-    has_classpath_jar: bool,
-
-    // The field claims to be milliseconds but is actually seconds.
-    #[serde(rename = "lastUpdateMillis")]
-    last_update_seconds: u64,
-
-    #[serde(rename = "isFactory")]
-    is_factory: bool,
-
-    #[serde(rename = "isActive")]
-    is_active: bool,
-
-    #[serde(rename = "provideSharedApexLibs")]
-    provide_shared_apex_libs: bool,
-}
-
-impl ApexInfoList {
-    /// Loads ApexInfoList
-    fn load() -> Result<&'static ApexInfoList> {
-        static INSTANCE: OnceCell<ApexInfoList> = OnceCell::new();
-        INSTANCE.get_or_try_init(|| {
-            let apex_info_list = File::open(APEX_INFO_LIST_PATH)
-                .context(format!("Failed to open {}", APEX_INFO_LIST_PATH))?;
-            let mut apex_info_list: ApexInfoList = from_reader(apex_info_list)
-                .context(format!("Failed to parse {}", APEX_INFO_LIST_PATH))?;
-
-            // For active APEXes, we run derive_classpath and parse its output to see if it
-            // contributes to the classpath(s). (This allows us to handle any new classpath env
-            // vars seamlessly.)
-            let classpath_vars = run_derive_classpath()?;
-            let classpath_apexes = find_apex_names_in_classpath(&classpath_vars)?;
-
-            for apex_info in apex_info_list.list.iter_mut() {
-                apex_info.has_classpath_jar = classpath_apexes.contains(&apex_info.name);
-            }
-
-            Ok(apex_info_list)
-        })
-    }
-
-    // Override apex info with the staged one
-    fn override_staged_apex(&mut self, staged_apex_info: &StagedApexInfo) -> Result<()> {
-        let mut need_to_add: Option<ApexInfo> = None;
-        for apex_info in self.list.iter_mut() {
-            if staged_apex_info.moduleName == apex_info.name {
-                if apex_info.is_active && apex_info.is_factory {
-                    // Copy the entry to the end as factory/non-active after the loop
-                    // to keep the factory version. Typically this step is unncessary,
-                    // but some apexes (like sharedlibs) need to be kept even if it's inactive.
-                    need_to_add.replace(ApexInfo { is_active: false, ..apex_info.clone() });
-                    // And make this one as non-factory. Note that this one is still active
-                    // and overridden right below.
-                    apex_info.is_factory = false;
-                }
-                // Active one is overridden with the staged one.
-                if apex_info.is_active {
-                    apex_info.version = staged_apex_info.versionCode as u64;
-                    apex_info.path = PathBuf::from(&staged_apex_info.diskImagePath);
-                    apex_info.has_classpath_jar = staged_apex_info.hasClassPathJars;
-                    apex_info.last_update_seconds = last_updated(&apex_info.path)?;
-                }
-            }
-        }
-        if let Some(info) = need_to_add {
-            self.list.push(info);
-        }
-        Ok(())
-    }
-}
-
-fn last_updated<P: AsRef<Path>>(path: P) -> Result<u64> {
-    let metadata = metadata(path)?;
-    Ok(metadata.modified()?.duration_since(SystemTime::UNIX_EPOCH)?.as_secs())
-}
-
-impl ApexInfo {
-    fn matches(&self, apex_config: &ApexConfig) -> bool {
-        // Match with pseudo name "{CLASSPATH}" which represents APEXes contributing
-        // to any derive_classpath environment variable
-        if apex_config.name == "{CLASSPATH}" && self.has_classpath_jar {
-            return true;
-        }
-        if apex_config.name == self.name {
-            return true;
-        }
-        false
-    }
-}
-
-struct PackageManager {
-    apex_info_list: &'static ApexInfoList,
-}
-
-impl PackageManager {
-    fn new() -> Result<Self> {
-        let apex_info_list = ApexInfoList::load()?;
-        Ok(Self { apex_info_list })
-    }
-
-    fn get_apex_list(&self, prefer_staged: bool) -> Result<ApexInfoList> {
-        // get the list of active apexes
-        let mut list = self.apex_info_list.clone();
-        // When prefer_staged, we override ApexInfo by consulting "package_native"
-        if prefer_staged {
-            let pm =
-                wait_for_interface::<dyn IPackageManagerNative>(PACKAGE_MANAGER_NATIVE_SERVICE)
-                    .context("Failed to get service when prefer_staged is set.")?;
-            let staged =
-                pm.getStagedApexModuleNames().context("getStagedApexModuleNames failed")?;
-            for name in staged {
-                if let Some(staged_apex_info) =
-                    pm.getStagedApexInfo(&name).context("getStagedApexInfo failed")?
-                {
-                    list.override_staged_apex(&staged_apex_info)?;
-                }
-            }
-        }
-        Ok(list)
-    }
-}
-
-fn make_metadata_file(
-    app_config: &VirtualMachineAppConfig,
-    apex_infos: &[&ApexInfo],
-    temporary_directory: &Path,
-) -> Result<ParcelFileDescriptor> {
-    let payload_metadata = match &app_config.payload {
-        Payload::PayloadConfig(payload_config) => PayloadMetadata::config(PayloadConfig {
-            payload_binary_name: payload_config.payloadBinaryName.clone(),
-            ..Default::default()
-        }),
-        Payload::ConfigPath(config_path) => {
-            PayloadMetadata::config_path(format!("/mnt/apk/{}", config_path))
-        }
-    };
-
-    let metadata = Metadata {
-        version: 1,
-        apexes: apex_infos
-            .iter()
-            .enumerate()
-            .map(|(i, apex_info)| {
-                Ok(ApexPayload {
-                    name: apex_info.name.clone(),
-                    partition_name: format!("microdroid-apex-{}", i),
-                    last_update_seconds: apex_info.last_update_seconds,
-                    is_factory: apex_info.is_factory,
-                    ..Default::default()
-                })
-            })
-            .collect::<Result<_>>()?,
-        apk: Some(ApkPayload {
-            name: "apk".to_owned(),
-            payload_partition_name: "microdroid-apk".to_owned(),
-            idsig_partition_name: "microdroid-apk-idsig".to_owned(),
-            ..Default::default()
-        })
-        .into(),
-        payload: Some(payload_metadata),
-        ..Default::default()
-    };
-
-    // Write metadata to file.
-    let metadata_path = temporary_directory.join("metadata");
-    let mut metadata_file = OpenOptions::new()
-        .create_new(true)
-        .read(true)
-        .write(true)
-        .open(&metadata_path)
-        .with_context(|| format!("Failed to open metadata file {:?}", metadata_path))?;
-    microdroid_metadata::write_metadata(&metadata, &mut metadata_file)?;
-
-    // Re-open the metadata file as read-only.
-    open_parcel_file(&metadata_path, false)
-}
-
-/// Creates a DiskImage with partitions:
-///   payload-metadata: metadata
-///   microdroid-apex-0: apex 0
-///   microdroid-apex-1: apex 1
-///   ..
-///   microdroid-apk: apk
-///   microdroid-apk-idsig: idsig
-///   extra-apk-0:   additional apk 0
-///   extra-idsig-0: additional idsig 0
-///   extra-apk-1:   additional apk 1
-///   extra-idsig-1: additional idsig 1
-///   ..
-fn make_payload_disk(
-    app_config: &VirtualMachineAppConfig,
-    apk_file: File,
-    idsig_file: File,
-    vm_payload_config: &VmPayloadConfig,
-    temporary_directory: &Path,
-) -> Result<DiskImage> {
-    if vm_payload_config.extra_apks.len() != app_config.extraIdsigs.len() {
-        bail!(
-            "payload config has {} apks, but app config has {} idsigs",
-            vm_payload_config.extra_apks.len(),
-            app_config.extraIdsigs.len()
-        );
-    }
-
-    let pm = PackageManager::new()?;
-    let apex_list = pm.get_apex_list(vm_payload_config.prefer_staged)?;
-
-    // collect APEXes from config
-    let mut apex_infos =
-        collect_apex_infos(&apex_list, &vm_payload_config.apexes, app_config.debugLevel);
-
-    // Pass sorted list of apexes. Sorting key shouldn't use `path` because it will change after
-    // reboot with prefer_staged. `last_update_seconds` is added to distinguish "samegrade"
-    // update.
-    apex_infos.sort_by_key(|info| (&info.name, &info.version, &info.last_update_seconds));
-    info!("Microdroid payload APEXes: {:?}", apex_infos.iter().map(|ai| &ai.name));
-
-    let metadata_file = make_metadata_file(app_config, &apex_infos, temporary_directory)?;
-    // put metadata at the first partition
-    let mut partitions = vec![Partition {
-        label: "payload-metadata".to_owned(),
-        image: Some(metadata_file),
-        writable: false,
-    }];
-
-    for (i, apex_info) in apex_infos.iter().enumerate() {
-        let apex_file = open_parcel_file(&apex_info.path, false)?;
-        partitions.push(Partition {
-            label: format!("microdroid-apex-{}", i),
-            image: Some(apex_file),
-            writable: false,
-        });
-    }
-    partitions.push(Partition {
-        label: "microdroid-apk".to_owned(),
-        image: Some(ParcelFileDescriptor::new(apk_file)),
-        writable: false,
-    });
-    partitions.push(Partition {
-        label: "microdroid-apk-idsig".to_owned(),
-        image: Some(ParcelFileDescriptor::new(idsig_file)),
-        writable: false,
-    });
-
-    // we've already checked that extra_apks and extraIdsigs are in the same size.
-    let extra_apks = &vm_payload_config.extra_apks;
-    let extra_idsigs = &app_config.extraIdsigs;
-    for (i, (extra_apk, extra_idsig)) in extra_apks.iter().zip(extra_idsigs.iter()).enumerate() {
-        partitions.push(Partition {
-            label: format!("extra-apk-{}", i),
-            image: Some(ParcelFileDescriptor::new(
-                File::open(PathBuf::from(&extra_apk.path)).with_context(|| {
-                    format!("Failed to open the extra apk #{} {}", i, extra_apk.path)
-                })?,
-            )),
-            writable: false,
-        });
-
-        partitions.push(Partition {
-            label: format!("extra-idsig-{}", i),
-            image: Some(ParcelFileDescriptor::new(
-                extra_idsig
-                    .as_ref()
-                    .try_clone()
-                    .with_context(|| format!("Failed to clone the extra idsig #{}", i))?,
-            )),
-            writable: false,
-        });
-    }
-
-    Ok(DiskImage { image: None, partitions, writable: false })
-}
-
-fn run_derive_classpath() -> Result<String> {
-    let result = Command::new("/apex/com.android.sdkext/bin/derive_classpath")
-        .arg("/proc/self/fd/1")
-        .output()
-        .context("Failed to run derive_classpath")?;
-
-    if !result.status.success() {
-        bail!("derive_classpath returned {}", result.status);
-    }
-
-    String::from_utf8(result.stdout).context("Converting derive_classpath output")
-}
-
-fn find_apex_names_in_classpath(classpath_vars: &str) -> Result<HashSet<String>> {
-    // Each line should be in the format "export <var name> <paths>", where <paths> is a
-    // colon-separated list of paths to JARs. We don't care about the var names, and we're only
-    // interested in paths that look like "/apex/<apex name>/<anything>" so we know which APEXes
-    // contribute to at least one var.
-    let mut apexes = HashSet::new();
-
-    let pattern = Regex::new(r"^export [^ ]+ ([^ ]+)$").context("Failed to construct Regex")?;
-    for line in classpath_vars.lines() {
-        if let Some(captures) = pattern.captures(line) {
-            if let Some(paths) = captures.get(1) {
-                apexes.extend(paths.as_str().split(':').filter_map(|path| {
-                    let path = path.strip_prefix("/apex/")?;
-                    Some(path[..path.find('/')?].to_owned())
-                }));
-                continue;
-            }
-        }
-        warn!("Malformed line from derive_classpath: {}", line);
-    }
-
-    Ok(apexes)
-}
-
-// Collect ApexInfos from VM config
-fn collect_apex_infos<'a>(
-    apex_list: &'a ApexInfoList,
-    apex_configs: &[ApexConfig],
-    debug_level: DebugLevel,
-) -> Vec<&'a ApexInfo> {
-    let mut additional_apexes: Vec<&str> = MICRODROID_REQUIRED_APEXES.to_vec();
-    if debug_level != DebugLevel::NONE {
-        additional_apexes.extend(MICRODROID_REQUIRED_APEXES_DEBUG.to_vec());
-    }
-
-    apex_list
-        .list
-        .iter()
-        .filter(|ai| {
-            apex_configs.iter().any(|cfg| ai.matches(cfg) && ai.is_active)
-                || additional_apexes.iter().any(|name| name == &ai.name && ai.is_active)
-                || ai.provide_shared_apex_libs
-        })
-        .collect()
-}
-
-pub fn add_microdroid_system_images(
-    config: &VirtualMachineAppConfig,
-    instance_file: File,
-    storage_image: Option<File>,
-    vm_config: &mut VirtualMachineRawConfig,
-) -> Result<()> {
-    let debug_suffix = match config.debugLevel {
-        DebugLevel::NONE => "normal",
-        DebugLevel::FULL => "debuggable",
-        _ => return Err(anyhow!("unsupported debug level: {:?}", config.debugLevel)),
-    };
-    let initrd = format!("/apex/com.android.virt/etc/microdroid_initrd_{}.img", debug_suffix);
-    vm_config.initrd = Some(open_parcel_file(Path::new(&initrd), false)?);
-
-    let mut writable_partitions = vec![Partition {
-        label: "vm-instance".to_owned(),
-        image: Some(ParcelFileDescriptor::new(instance_file)),
-        writable: true,
-    }];
-
-    if let Some(file) = storage_image {
-        writable_partitions.push(Partition {
-            label: "encryptedstore".to_owned(),
-            image: Some(ParcelFileDescriptor::new(file)),
-            writable: true,
-        });
-    }
-
-    vm_config.disks.push(DiskImage {
-        image: None,
-        partitions: writable_partitions,
-        writable: true,
-    });
-
-    Ok(())
-}
-
-pub fn add_microdroid_payload_images(
-    config: &VirtualMachineAppConfig,
-    temporary_directory: &Path,
-    apk_file: File,
-    idsig_file: File,
-    vm_payload_config: &VmPayloadConfig,
-    vm_config: &mut VirtualMachineRawConfig,
-) -> Result<()> {
-    vm_config.disks.push(make_payload_disk(
-        config,
-        apk_file,
-        idsig_file,
-        vm_payload_config,
-        temporary_directory,
-    )?);
-
-    Ok(())
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use tempfile::NamedTempFile;
-
-    #[test]
-    fn test_find_apex_names_in_classpath() {
-        let vars = r#"
-export FOO /apex/unterminated
-export BAR /apex/valid.apex/something
-wrong
-export EMPTY
-export OTHER /foo/bar:/baz:/apex/second.valid.apex/:gibberish:"#;
-        let expected = vec!["valid.apex", "second.valid.apex"];
-        let expected: HashSet<_> = expected.into_iter().map(ToString::to_string).collect();
-
-        assert_eq!(find_apex_names_in_classpath(vars).unwrap(), expected);
-    }
-
-    #[test]
-    fn test_collect_apexes() {
-        let apex_info_list = ApexInfoList {
-            list: vec![
-                ApexInfo {
-                    // 0
-                    name: "com.android.adbd".to_string(),
-                    path: PathBuf::from("adbd"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 12345678,
-                    is_factory: true,
-                    is_active: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 1
-                    name: "com.android.os.statsd".to_string(),
-                    path: PathBuf::from("statsd"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 12345678,
-                    is_factory: true,
-                    is_active: false,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 2
-                    name: "com.android.os.statsd".to_string(),
-                    path: PathBuf::from("statsd/updated"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 12345678 + 1,
-                    is_factory: false,
-                    is_active: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 3
-                    name: "no_classpath".to_string(),
-                    path: PathBuf::from("no_classpath"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 12345678,
-                    is_factory: true,
-                    is_active: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 4
-                    name: "has_classpath".to_string(),
-                    path: PathBuf::from("has_classpath"),
-                    has_classpath_jar: true,
-                    last_update_seconds: 87654321,
-                    is_factory: true,
-                    is_active: false,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 5
-                    name: "has_classpath".to_string(),
-                    path: PathBuf::from("has_classpath/updated"),
-                    has_classpath_jar: true,
-                    last_update_seconds: 87654321 + 1,
-                    is_factory: false,
-                    is_active: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 6
-                    name: "apex-foo".to_string(),
-                    path: PathBuf::from("apex-foo"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 87654321,
-                    is_factory: true,
-                    is_active: false,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 7
-                    name: "apex-foo".to_string(),
-                    path: PathBuf::from("apex-foo/updated"),
-                    has_classpath_jar: false,
-                    last_update_seconds: 87654321 + 1,
-                    is_factory: false,
-                    is_active: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 8
-                    name: "sharedlibs".to_string(),
-                    path: PathBuf::from("apex-foo"),
-                    last_update_seconds: 87654321,
-                    is_factory: true,
-                    provide_shared_apex_libs: true,
-                    ..Default::default()
-                },
-                ApexInfo {
-                    // 9
-                    name: "sharedlibs".to_string(),
-                    path: PathBuf::from("apex-foo/updated"),
-                    last_update_seconds: 87654321 + 1,
-                    is_active: true,
-                    provide_shared_apex_libs: true,
-                    ..Default::default()
-                },
-            ],
-        };
-        let apex_configs = vec![
-            ApexConfig { name: "apex-foo".to_string() },
-            ApexConfig { name: "{CLASSPATH}".to_string() },
-        ];
-        assert_eq!(
-            collect_apex_infos(&apex_info_list, &apex_configs, DebugLevel::FULL),
-            vec![
-                // Pass active/required APEXes
-                &apex_info_list.list[0],
-                &apex_info_list.list[2],
-                // Pass active APEXes specified in the config
-                &apex_info_list.list[5],
-                &apex_info_list.list[7],
-                // Pass both preinstalled(inactive) and updated(active) for "sharedlibs" APEXes
-                &apex_info_list.list[8],
-                &apex_info_list.list[9],
-            ]
-        );
-    }
-
-    #[test]
-    fn test_prefer_staged_apex_with_factory_active_apex() {
-        let single_apex = ApexInfo {
-            name: "foo".to_string(),
-            version: 1,
-            path: PathBuf::from("foo.apex"),
-            is_factory: true,
-            is_active: true,
-            ..Default::default()
-        };
-        let mut apex_info_list = ApexInfoList { list: vec![single_apex.clone()] };
-
-        let staged = NamedTempFile::new().unwrap();
-        apex_info_list
-            .override_staged_apex(&StagedApexInfo {
-                moduleName: "foo".to_string(),
-                versionCode: 2,
-                diskImagePath: staged.path().to_string_lossy().to_string(),
-                ..Default::default()
-            })
-            .expect("should be ok");
-
-        assert_eq!(
-            apex_info_list,
-            ApexInfoList {
-                list: vec![
-                    ApexInfo {
-                        version: 2,
-                        is_factory: false,
-                        path: staged.path().to_owned(),
-                        last_update_seconds: last_updated(staged.path()).unwrap(),
-                        ..single_apex.clone()
-                    },
-                    ApexInfo { is_active: false, ..single_apex },
-                ],
-            }
-        );
-    }
-
-    #[test]
-    fn test_prefer_staged_apex_with_factory_and_inactive_apex() {
-        let factory_apex = ApexInfo {
-            name: "foo".to_string(),
-            version: 1,
-            path: PathBuf::from("foo.apex"),
-            is_factory: true,
-            ..Default::default()
-        };
-        let active_apex = ApexInfo {
-            name: "foo".to_string(),
-            version: 2,
-            path: PathBuf::from("foo.downloaded.apex"),
-            is_active: true,
-            ..Default::default()
-        };
-        let mut apex_info_list =
-            ApexInfoList { list: vec![factory_apex.clone(), active_apex.clone()] };
-
-        let staged = NamedTempFile::new().unwrap();
-        apex_info_list
-            .override_staged_apex(&StagedApexInfo {
-                moduleName: "foo".to_string(),
-                versionCode: 3,
-                diskImagePath: staged.path().to_string_lossy().to_string(),
-                ..Default::default()
-            })
-            .expect("should be ok");
-
-        assert_eq!(
-            apex_info_list,
-            ApexInfoList {
-                list: vec![
-                    // factory apex isn't touched
-                    factory_apex,
-                    // update active one
-                    ApexInfo {
-                        version: 3,
-                        path: staged.path().to_owned(),
-                        last_update_seconds: last_updated(staged.path()).unwrap(),
-                        ..active_apex
-                    },
-                ],
-            }
-        );
-    }
-}
diff --git a/virtualizationservice/src/selinux.rs b/virtualizationservice/src/selinux.rs
deleted file mode 100644
index 0485943..0000000
--- a/virtualizationservice/src/selinux.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-// 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.
-
-//! Wrapper to libselinux
-
-use anyhow::{anyhow, bail, Context, Result};
-use std::ffi::{CStr, CString};
-use std::fmt;
-use std::fs::File;
-use std::io;
-use std::ops::Deref;
-use std::os::raw::c_char;
-use std::os::unix::io::AsRawFd;
-use std::ptr;
-
-// Partially copied from system/security/keystore2/selinux/src/lib.rs
-/// SeContext represents an SELinux context string. It can take ownership of a raw
-/// s-string as allocated by `getcon` or `selabel_lookup`. In this case it uses
-/// `freecon` to free the resources when dropped. In its second variant it stores
-/// an `std::ffi::CString` that can be initialized from a Rust string slice.
-#[derive(Debug)]
-#[allow(dead_code)] // CString variant is used in tests
-pub enum SeContext {
-    /// Wraps a raw context c-string as returned by libselinux.
-    Raw(*mut ::std::os::raw::c_char),
-    /// Stores a context string as `std::ffi::CString`.
-    CString(CString),
-}
-
-impl PartialEq for SeContext {
-    fn eq(&self, other: &Self) -> bool {
-        // We dereference both and thereby delegate the comparison
-        // to `CStr`'s implementation of `PartialEq`.
-        **self == **other
-    }
-}
-
-impl Eq for SeContext {}
-
-impl fmt::Display for SeContext {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.to_str().unwrap_or("Invalid context"))
-    }
-}
-
-impl Drop for SeContext {
-    fn drop(&mut self) {
-        if let Self::Raw(p) = self {
-            // SAFETY: SeContext::Raw is created only with a pointer that is set by libselinux and
-            // has to be freed with freecon.
-            unsafe { selinux_bindgen::freecon(*p) };
-        }
-    }
-}
-
-impl Deref for SeContext {
-    type Target = CStr;
-
-    fn deref(&self) -> &Self::Target {
-        match self {
-            // SAFETY: the non-owned C string pointed by `p` is guaranteed to be valid (non-null
-            // and shorter than i32::MAX). It is freed when SeContext is dropped.
-            Self::Raw(p) => unsafe { CStr::from_ptr(*p) },
-            Self::CString(cstr) => cstr,
-        }
-    }
-}
-
-impl SeContext {
-    /// Initializes the `SeContext::CString` variant from a Rust string slice.
-    #[allow(dead_code)] // Used in tests
-    pub fn new(con: &str) -> Result<Self> {
-        Ok(Self::CString(
-            CString::new(con)
-                .with_context(|| format!("Failed to create SeContext with \"{}\"", con))?,
-        ))
-    }
-
-    pub fn selinux_type(&self) -> Result<&str> {
-        let context = self.deref().to_str().context("Label is not valid UTF8")?;
-
-        // The syntax is user:role:type:sensitivity[:category,...],
-        // ignoring security level ranges, which don't occur on Android. See
-        // https://github.com/SELinuxProject/selinux-notebook/blob/main/src/security_context.md
-        // We only want the type.
-        let fields: Vec<_> = context.split(':').collect();
-        if fields.len() < 4 || fields.len() > 5 {
-            bail!("Syntactically invalid label {}", self);
-        }
-        Ok(fields[2])
-    }
-}
-
-pub fn getfilecon(file: &File) -> Result<SeContext> {
-    let fd = file.as_raw_fd();
-    let mut con: *mut c_char = ptr::null_mut();
-    // SAFETY: the returned pointer `con` is wrapped in SeContext::Raw which is freed with
-    // `freecon` when it is dropped.
-    match unsafe { selinux_bindgen::fgetfilecon(fd, &mut con) } {
-        1.. => {
-            if !con.is_null() {
-                Ok(SeContext::Raw(con))
-            } else {
-                Err(anyhow!("fgetfilecon returned a NULL context"))
-            }
-        }
-        _ => Err(anyhow!(io::Error::last_os_error())).context("fgetfilecon failed"),
-    }
-}
diff --git a/virtualizationservice/src/virtmgr.rs b/virtualizationservice/src/virtmgr.rs
deleted file mode 100644
index dca64cb..0000000
--- a/virtualizationservice/src/virtmgr.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2022, 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.
-
-//! Android Virtualization Manager
-
-mod aidl;
-mod atom;
-mod composite;
-mod crosvm;
-mod payload;
-mod selinux;
-
-use crate::aidl::{GLOBAL_SERVICE, VirtualizationService};
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::BnVirtualizationService;
-use anyhow::{bail, Context};
-use binder::{BinderFeatures, ProcessState};
-use lazy_static::lazy_static;
-use log::{info, Level};
-use rpcbinder::{FileDescriptorTransportMode, RpcServer};
-use std::os::unix::io::{FromRawFd, OwnedFd, RawFd};
-use clap::Parser;
-use nix::fcntl::{fcntl, F_GETFD, F_SETFD, FdFlag};
-use nix::unistd::{Pid, Uid};
-use std::os::unix::raw::{pid_t, uid_t};
-use rustutils::system_properties;
-
-const LOG_TAG: &str = "virtmgr";
-
-lazy_static! {
-    static ref PID_PARENT: Pid = Pid::parent();
-    static ref UID_CURRENT: Uid = Uid::current();
-}
-
-fn get_calling_pid() -> pid_t {
-    // The caller is the parent of this process.
-    PID_PARENT.as_raw()
-}
-
-fn get_calling_uid() -> uid_t {
-    // The caller and this process share the same UID.
-    UID_CURRENT.as_raw()
-}
-
-#[derive(Parser)]
-struct Args {
-    /// File descriptor inherited from the caller to run RpcBinder server on.
-    /// This should be one end of a socketpair() compatible with RpcBinder's
-    /// UDS bootstrap transport.
-    #[clap(long)]
-    rpc_server_fd: RawFd,
-    /// File descriptor inherited from the caller to signal RpcBinder server
-    /// readiness. This should be one end of pipe() and the caller should be
-    /// waiting for HUP on the other end.
-    #[clap(long)]
-    ready_fd: RawFd,
-}
-
-fn take_fd_ownership(raw_fd: RawFd, owned_fds: &mut Vec<RawFd>) -> Result<OwnedFd, anyhow::Error> {
-    // Basic check that the integer value does correspond to a file descriptor.
-    fcntl(raw_fd, F_GETFD).with_context(|| format!("Invalid file descriptor {raw_fd}"))?;
-
-    // The file descriptor had CLOEXEC disabled to be inherited from the parent.
-    // Re-enable it to make sure it is not accidentally inherited further.
-    fcntl(raw_fd, F_SETFD(FdFlag::FD_CLOEXEC))
-        .with_context(|| format!("Could not set CLOEXEC on file descriptor {raw_fd}"))?;
-
-    // Creating OwnedFd for stdio FDs is not safe.
-    if [libc::STDIN_FILENO, libc::STDOUT_FILENO, libc::STDERR_FILENO].contains(&raw_fd) {
-        bail!("File descriptor {raw_fd} is standard I/O descriptor");
-    }
-
-    // Reject RawFds that already have a corresponding OwnedFd.
-    if owned_fds.contains(&raw_fd) {
-        bail!("File descriptor {raw_fd} already owned");
-    }
-    owned_fds.push(raw_fd);
-
-    // SAFETY - Initializing OwnedFd for a RawFd provided in cmdline arguments.
-    // We checked that the integer value corresponds to a valid FD and that this
-    // is the first argument to claim its ownership.
-    Ok(unsafe { OwnedFd::from_raw_fd(raw_fd) })
-}
-
-fn is_property_set(name: &str) -> bool {
-    system_properties::read_bool(name, false)
-        .unwrap_or_else(|e| panic!("Failed to read {name}: {e:?}"))
-}
-
-fn main() {
-    android_logger::init_once(
-        android_logger::Config::default()
-            .with_tag(LOG_TAG)
-            .with_min_level(Level::Info)
-            .with_log_id(android_logger::LogId::System),
-    );
-
-    let non_protected_vm_supported = is_property_set("ro.boot.hypervisor.vm.supported");
-    let protected_vm_supported = is_property_set("ro.boot.hypervisor.protected_vm.supported");
-    if !non_protected_vm_supported && !protected_vm_supported {
-        // This should never happen, it indicates a misconfigured device where the virt APEX
-        // is present but VMs are not supported. If it does happen, fail fast to avoid wasting
-        // resources trying.
-        panic!("Device doesn't support protected or unprotected VMs");
-    }
-
-    let args = Args::parse();
-
-    let mut owned_fds = vec![];
-    let rpc_server_fd = take_fd_ownership(args.rpc_server_fd, &mut owned_fds)
-        .expect("Failed to take ownership of rpc_server_fd");
-    let ready_fd = take_fd_ownership(args.ready_fd, &mut owned_fds)
-        .expect("Failed to take ownership of ready_fd");
-
-    // Start thread pool for kernel Binder connection to VirtualizationServiceInternal.
-    ProcessState::start_thread_pool();
-
-    GLOBAL_SERVICE.removeMemlockRlimit().expect("Failed to remove memlock rlimit");
-
-    let service = VirtualizationService::init();
-    let service =
-        BnVirtualizationService::new_binder(service, BinderFeatures::default()).as_binder();
-
-    let server = RpcServer::new_unix_domain_bootstrap(service, rpc_server_fd)
-        .expect("Failed to start RpcServer");
-    server.set_supported_file_descriptor_transport_modes(&[FileDescriptorTransportMode::Unix]);
-
-    info!("Started VirtualizationService RpcServer. Ready to accept connections");
-
-    // Signal readiness to the caller by closing our end of the pipe.
-    drop(ready_fd);
-
-    server.join();
-    info!("Shutting down VirtualizationService RpcServer");
-}
