Add persistent backing for encrypted storage in VM

Virtualization service will allow clients to pass the file that will
back the (encrypted) storage inside VM.

This patch:
1. Exposes (optional) encryptedStorageImage in VirtualMachineAppConfig.
2. Expose it as a block device to VM (by including it as partition in a
   writable disk).

Test: bin/vm run-app --storage -> inspect the block device in vm
Bug: 241543632
Change-Id: I9adbe832bda2c5f5a749d8614f056f51244ae52c
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 21cc74b..3b887d3 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -58,6 +58,16 @@
         #[clap(short, long)]
         daemonize: bool,
 
+        /// Path to the file backing the storage.
+        /// Created if the option is used but the path does not exist in the device.
+        #[clap(long)]
+        storage: Option<PathBuf>,
+
+        /// Size of the storage. Used only if --storage is supplied but path does not exist
+        /// Default size is 10*1024*1024
+        #[clap(long)]
+        storage_size: Option<u64>,
+
         /// Path to file for VM console output.
         #[clap(long)]
         console: Option<PathBuf>,
@@ -188,6 +198,8 @@
             apk,
             idsig,
             instance,
+            storage,
+            storage_size,
             config_path,
             daemonize,
             console,
@@ -205,6 +217,8 @@
             &apk,
             &idsig,
             &instance,
+            storage.as_deref(),
+            storage_size,
             config_path.as_deref().unwrap_or(""),
             daemonize,
             console.as_deref(),
diff --git a/vm/src/run.rs b/vm/src/run.rs
index c524c59..967314b 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -41,6 +41,8 @@
     apk: &Path,
     idsig: &Path,
     instance: &Path,
+    storage: Option<&Path>,
+    storage_size: Option<u64>,
     config_path: &str,
     daemonize: bool,
     console_path: Option<&Path>,
@@ -88,6 +90,20 @@
         )?;
     }
 
+    let storage = if let Some(path) = storage {
+        if !path.exists() {
+            command_create_partition(
+                service,
+                path,
+                storage_size.unwrap_or(10 * 1024 * 1024),
+                PartitionType::RAW,
+            )?;
+        }
+        Some(open_parcel_file(path, true)?)
+    } else {
+        None
+    };
+
     let extra_idsig_files: Result<Vec<File>, _> = extra_idsigs.iter().map(File::open).collect();
     let extra_idsig_fds = extra_idsig_files?.into_iter().map(ParcelFileDescriptor::new).collect();
 
@@ -97,6 +113,7 @@
         idsig: idsig_fd.into(),
         extraIdsigs: extra_idsig_fds,
         instanceImage: open_parcel_file(instance, true /* writable */)?.into(),
+        encryptedStorageImage: storage,
         payload: Payload::ConfigPath(config_path.to_owned()),
         debugLevel: debug_level,
         protectedVm: protected,