Support multiple files per partition.

Bug: 190503456
Test: Ran microdroid
Change-Id: I0461120a3eb9c7e8c70ebc61a170d686f9f8b0ea
diff --git a/virtualizationservice/src/composite.rs b/virtualizationservice/src/composite.rs
index fb8e783..5f792fd 100644
--- a/virtualizationservice/src/composite.rs
+++ b/virtualizationservice/src/composite.rs
@@ -50,13 +50,20 @@
 const LINUX_FILESYSTEM_GUID: Uuid = Uuid::from_u128(0x0FC63DAF_8483_4772_8E79_3D69D8477DE4);
 const EFI_SYSTEM_PARTITION_GUID: Uuid = Uuid::from_u128(0xC12A7328_F81F_11D2_BA4B_00A0C93EC93B);
 
+/// Information about a single image file to be included in a partition.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct PartitionFileInfo {
+    path: PathBuf,
+    size: u64,
+}
+
+/// Information about a partition to create, including the set of image files which make it up.
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub struct PartitionInfo {
     label: String,
-    path: PathBuf,
+    files: Vec<PartitionFileInfo>,
     partition_type: ImagePartitionType,
     writable: bool,
-    size: u64,
 }
 
 /// Round `val` up to the next multiple of 2**`align_log`.
@@ -67,7 +74,7 @@
 
 impl PartitionInfo {
     fn aligned_size(&self) -> u64 {
-        align_to_power_of_2(self.size, PARTITION_SIZE_SHIFT)
+        align_to_power_of_2(self.files.iter().map(|file| file.size).sum(), PARTITION_SIZE_SHIFT)
     }
 }
 
@@ -160,18 +167,26 @@
 ) -> Result<Vec<ComponentDisk>, Error> {
     let aligned_size = partition.aligned_size();
 
-    let mut component_disks = vec![ComponentDisk {
-        offset,
-        file_path: partition.path.to_str().context("Invalid partition path")?.to_string(),
-        read_write_capability: if partition.writable {
-            ReadWriteCapability::READ_WRITE
-        } else {
-            ReadWriteCapability::READ_ONLY
-        },
-        ..ComponentDisk::new()
-    }];
+    if partition.files.is_empty() {
+        bail!("No image files for partition {:?}", partition);
+    }
+    let mut file_size_sum = 0;
+    let mut component_disks = vec![];
+    for file in &partition.files {
+        component_disks.push(ComponentDisk {
+            offset: offset + file_size_sum,
+            file_path: file.path.to_str().context("Invalid partition path")?.to_string(),
+            read_write_capability: if partition.writable {
+                ReadWriteCapability::READ_WRITE
+            } else {
+                ReadWriteCapability::READ_ONLY
+            },
+            ..ComponentDisk::new()
+        });
+        file_size_sum += file.size;
+    }
 
-    if partition.size != aligned_size {
+    if file_size_sum != aligned_size {
         if partition.writable {
             bail!(
                 "Read-write partition {:?} size is not a multiple of {}.",
@@ -187,7 +202,7 @@
                 1 << PARTITION_SIZE_SHIFT
             );
             component_disks.push(ComponentDisk {
-                offset: offset + partition.size,
+                offset: offset + file_size_sum,
                 file_path: header_path.to_owned(),
                 read_write_capability: ReadWriteCapability::READ_ONLY,
                 ..ComponentDisk::new()
@@ -345,10 +360,12 @@
 
             Ok(PartitionInfo {
                 label: partition.label.to_owned(),
-                path: format!("/proc/self/fd/{}", fd).into(),
+                files: vec![PartitionFileInfo {
+                    path: format!("/proc/self/fd/{}", fd).into(),
+                    size,
+                }],
                 partition_type: ImagePartitionType::LinuxFilesystem,
                 writable: partition.writable,
-                size,
             })
         })
         .collect::<Result<_, Error>>()?;