Enable debug mode

When the debug mode is enabled, an extra bootconfig partition for the
debug mode is used. The bootconfig partition currently disables Selinux.

Bug: 185211964
Test: vm /data/local/tmp/MicrodroidTestApp.apk
/data/local/tmp/MicrodroidApp.apk.idsig assets/config.json --debug

Change-Id: I25a20b75b6d216395fe7579729a61bcbdb8dd395
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
index 5b270a3..4dcfb88 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
@@ -25,4 +25,7 @@
 
     /** Path to a configuration in an APK. This is the actual configuration for a VM. */
     @utf8InCpp String configPath;
+
+    /** Whether to run the VM in debug mode or not */
+    boolean debug;
 }
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 5c0c3b8..dc22e99 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -44,7 +44,7 @@
 use std::os::unix::io::AsRawFd;
 use std::path::{Path, PathBuf};
 use std::sync::{Arc, Mutex, Weak};
-use vmconfig::VmConfig;
+use vmconfig::{VmConfig, Partition};
 use zip::ZipArchive;
 
 pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservice";
@@ -319,7 +319,7 @@
     let vm_config_file = File::open(vm_config_path)?;
     let mut vm_config = VmConfig::load(&vm_config_file)?;
 
-    // Microdroid requires additional payload disk image
+    // Microdroid requires additional payload disk image and the bootconfig partition
     if os_name == "microdroid" {
         let mut apexes = vm_payload_config.apexes.clone();
         apexes.extend(
@@ -335,6 +335,16 @@
             &apexes,
             temporary_directory,
         )?);
+
+        if config.debug {
+            vm_config.disks[1].partitions.push(Partition {
+                label: "bootconfig".to_owned(),
+                paths: vec![PathBuf::from(
+                    "/apex/com.android.virt/etc/microdroid_bootconfig.debug",
+                )],
+                writable: false,
+            });
+        }
     }
 
     vm_config.to_parcelable()
diff --git a/vm/src/main.rs b/vm/src/main.rs
index d7bae30..9ca0ea6 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -53,6 +53,10 @@
         /// Path to file for VM log output.
         #[structopt(short, long)]
         log: Option<PathBuf>,
+
+        /// Whether to run VM in debug mode.
+        #[structopt(short, long)]
+        debug: bool,
     },
     /// Run a virtual machine
     Run {
@@ -97,8 +101,8 @@
         .context("Failed to find VirtualizationService")?;
 
     match opt {
-        Opt::RunApp { apk, idsig, config_path, daemonize, log } => {
-            command_run_app(service, &apk, &idsig, &config_path, daemonize, log.as_deref())
+        Opt::RunApp { apk, idsig, config_path, daemonize, log, debug } => {
+            command_run_app(service, &apk, &idsig, &config_path, daemonize, log.as_deref(), debug)
         }
         Opt::Run { config, daemonize, log } => {
             command_run(service, &config, daemonize, log.as_deref())
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 96ce745..01fc724 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -43,6 +43,7 @@
     config_path: &str,
     daemonize: bool,
     log_path: Option<&Path>,
+    debug: bool,
 ) -> Result<(), Error> {
     let apk_file = File::open(apk).context("Failed to open APK file")?;
     let idsig_file = File::open(idsig).context("Failed to open idsig file")?;
@@ -50,6 +51,7 @@
         apk: ParcelFileDescriptor::new(apk_file).into(),
         idsig: ParcelFileDescriptor::new(idsig_file).into(),
         configPath: config_path.to_owned(),
+        debug,
     });
     run(service, &config, &format!("{:?}!{:?}", apk, config_path), daemonize, log_path)
 }