Lift composite disk assembly to the launcher binary

This is an incremental step towards putting the composite disk assembly
into a separate binary from launch_cvd.

The config and vm managers are now no longer aware of the individual
disk images / partitions, and the config passes an ordered list.

Bug: 135293952
Test: launch_cvd [-vm_manager=qemu_cli] [-composite_disk=composite.img]
Change-Id: I00c4c15c811273b0d0524e870ec5a9436cf7229b
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index b41cf77..bdac2db 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -24,6 +24,7 @@
         "launch.cc",
         "data_image.cc",
         "flags.cc",
+        "image_aggregator.cc",
     ],
     header_libs: [
         "cuttlefish_glog",
@@ -47,3 +48,9 @@
     ],
     defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"],
 }
+
+cc_prebuilt_binary {
+    name: "cf_bpttool",
+    srcs: ["cf_bpttool"],
+    defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/libs/vm_manager/cf_bpttool b/host/commands/launch/cf_bpttool
similarity index 100%
rename from host/libs/vm_manager/cf_bpttool
rename to host/commands/launch/cf_bpttool
diff --git a/host/commands/launch/data_image.cc b/host/commands/launch/data_image.cc
index 9bdc421..dad88d8 100644
--- a/host/commands/launch/data_image.cc
+++ b/host/commands/launch/data_image.cc
@@ -74,8 +74,8 @@
   }
 }
 
-bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config) {
-  std::string data_image = config.data_image_path();
+bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config,
+                          const std::string& data_image) {
   bool data_exists = cvd::FileHasContent(data_image.c_str());
   bool remove{};
   bool create{};
diff --git a/host/commands/launch/data_image.h b/host/commands/launch/data_image.h
index 1cf9ca2..664467e 100644
--- a/host/commands/launch/data_image.h
+++ b/host/commands/launch/data_image.h
@@ -4,6 +4,7 @@
 
 #include "host/libs/config/cuttlefish_config.h"
 
-bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config);
+bool ApplyDataImagePolicy(const vsoc::CuttlefishConfig& config,
+                          const std::string& path);
 void CreateBlankImage(
     const std::string& image, int image_mb, const std::string& image_fmt);
diff --git a/host/commands/launch/flags.cc b/host/commands/launch/flags.cc
index a3cb812..f591cf6 100644
--- a/host/commands/launch/flags.cc
+++ b/host/commands/launch/flags.cc
@@ -11,6 +11,7 @@
 #include "common/vsoc/lib/vsoc_memory.h"
 #include "host/commands/launch/boot_image_unpacker.h"
 #include "host/commands/launch/data_image.h"
+#include "host/commands/launch/image_aggregator.h"
 #include "host/commands/launch/launch.h"
 #include "host/commands/launch/launcher_defs.h"
 #include "host/libs/vm_manager/crosvm_manager.h"
@@ -420,27 +421,34 @@
   }
 
   if (FLAGS_super_image.empty()) {
-    tmp_config_obj.set_system_image_path(FLAGS_system_image);
-    tmp_config_obj.set_vendor_image_path(FLAGS_vendor_image);
-    tmp_config_obj.set_product_image_path(FLAGS_product_image);
-    tmp_config_obj.set_super_image_path("");
     tmp_config_obj.set_dtb_path(FLAGS_dtb);
     tmp_config_obj.set_gsi_fstab_path(FLAGS_gsi_fstab);
   } else {
-    tmp_config_obj.set_system_image_path("");
-    tmp_config_obj.set_vendor_image_path("");
-    tmp_config_obj.set_product_image_path("");
-    tmp_config_obj.set_super_image_path(FLAGS_super_image);
     tmp_config_obj.set_dtb_path("");
     tmp_config_obj.set_gsi_fstab_path("");
   }
 
+  if (!FLAGS_composite_disk.empty()) {
+    tmp_config_obj.set_virtual_disk_paths({FLAGS_composite_disk});
+  } else if(!FLAGS_super_image.empty()) {
+    tmp_config_obj.set_virtual_disk_paths({
+      FLAGS_super_image,
+      FLAGS_data_image,
+      FLAGS_cache_image,
+      FLAGS_metadata_image,
+    });
+  } else {
+    tmp_config_obj.set_virtual_disk_paths({
+      FLAGS_system_image,
+      FLAGS_data_image,
+      FLAGS_cache_image,
+      FLAGS_metadata_image,
+      FLAGS_vendor_image,
+      FLAGS_product_image,
+    });
+  }
+
   tmp_config_obj.set_ramdisk_image_path(ramdisk_path);
-  tmp_config_obj.set_cache_image_path(FLAGS_cache_image);
-  tmp_config_obj.set_data_image_path(FLAGS_data_image);
-  tmp_config_obj.set_metadata_image_path(FLAGS_metadata_image);
-  tmp_config_obj.set_boot_image_path(FLAGS_boot_image);
-  tmp_config_obj.set_composite_disk_path(FLAGS_composite_disk);
 
   tmp_config_obj.set_mempath(FLAGS_mempath);
   tmp_config_obj.set_ivshmem_qemu_socket_path(
@@ -683,6 +691,75 @@
 }
 } // namespace
 
+namespace {
+
+std::vector<ImagePartition> disk_config() {
+  std::vector<ImagePartition> partitions;
+  if (FLAGS_super_image.empty()) {
+    partitions.push_back(ImagePartition {
+      .label = "system",
+      .image_file_path = FLAGS_system_image,
+    });
+  } else {
+    partitions.push_back(ImagePartition {
+      .label = "super",
+      .image_file_path = FLAGS_super_image,
+    });
+  }
+  partitions.push_back(ImagePartition {
+    .label = "userdata",
+    .image_file_path = FLAGS_data_image,
+  });
+  partitions.push_back(ImagePartition {
+    .label = "cache",
+    .image_file_path = FLAGS_cache_image,
+  });
+  partitions.push_back(ImagePartition {
+    .label = "metadata",
+    .image_file_path = FLAGS_metadata_image,
+  });
+  if (FLAGS_super_image.empty()) {
+    partitions.push_back(ImagePartition {
+      .label = "product",
+      .image_file_path = FLAGS_product_image,
+    });
+    partitions.push_back(ImagePartition {
+      .label = "vendor",
+      .image_file_path = FLAGS_vendor_image,
+    });
+  }
+  partitions.push_back(ImagePartition {
+    .label = "boot",
+    .image_file_path = FLAGS_boot_image,
+  });
+  return partitions;
+}
+
+bool ShouldCreateCompositeDisk() {
+  if (FLAGS_composite_disk.empty()) {
+    return false;
+  }
+  auto composite_age = cvd::FileModificationTime(FLAGS_composite_disk);
+  for (auto& partition : disk_config()) {
+    auto partition_age = cvd::FileModificationTime(partition.image_file_path);
+    if (partition_age >= composite_age) {
+      LOG(INFO) << "composite disk age was \"" << std::chrono::system_clock::to_time_t(composite_age) << "\", "
+                << "partition age was \"" << std::chrono::system_clock::to_time_t(partition_age) << "\"";
+      return true;
+    }
+  }
+  return false;
+}
+
+void CreateCompositeDisk() {
+  if (FLAGS_composite_disk.empty()) {
+    LOG(FATAL) << "asked to create composite disk, but path was empty";
+  }
+  aggregate_image(disk_config(), FLAGS_composite_disk);
+}
+
+} // namespace
+
 vsoc::CuttlefishConfig* InitFilesystemAndCreateConfig(int* argc, char*** argv) {
   if (!ParseCommandLineFlags(argc, argv)) {
     LOG(ERROR) << "Failed to parse command arguments";
@@ -742,7 +819,7 @@
   ValidateAdbModeFlag(*config);
 
   // Create data if necessary
-  if (!ApplyDataImagePolicy(*config)) {
+  if (!ApplyDataImagePolicy(*config, FLAGS_data_image)) {
     exit(cvd::kCuttlefishConfigurationInitError);
   }
 
@@ -750,12 +827,12 @@
     CreateBlankImage(FLAGS_metadata_image, FLAGS_blank_metadata_image_mb, "none");
   }
 
+  if (ShouldCreateCompositeDisk()) {
+    CreateCompositeDisk();
+  }
+
   // Check that the files exist
-  for (const auto& file :
-       {config->system_image_path(), config->cache_image_path(),
-        config->data_image_path(), config->vendor_image_path(),
-        config->metadata_image_path(),  config->product_image_path(),
-        config->super_image_path(), config->boot_image_path()}) {
+  for (const auto& file : config->virtual_disk_paths()) {
     if (!file.empty() && !cvd::FileHasContent(file.c_str())) {
       LOG(ERROR) << "File not found: " << file;
       exit(cvd::kCuttlefishConfigurationInitError);
diff --git a/host/libs/vm_manager/image_aggregator.cpp b/host/commands/launch/image_aggregator.cc
similarity index 96%
rename from host/libs/vm_manager/image_aggregator.cpp
rename to host/commands/launch/image_aggregator.cc
index edc0268..2ff0b84 100644
--- a/host/libs/vm_manager/image_aggregator.cpp
+++ b/host/commands/launch/image_aggregator.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "host/libs/vm_manager/image_aggregator.h"
+#include "host/commands/launch/image_aggregator.h"
 
 #include <string>
 #include <vector>
@@ -27,8 +27,6 @@
 #include "common/libs/utils/subprocess.h"
 #include "host/libs/config/cuttlefish_config.h"
 
-namespace vm_manager {
-
 namespace {
 
 const std::string BPTTOOL_FILE_PATH = "bin/cf_bpttool";
@@ -118,5 +116,3 @@
   auto table_fd = bpttool_make_table(input_json_fd);
   bpttool_make_disk_image(partitions, table_fd, output_path);
 };
-
-} // namespace vm_manager
diff --git a/host/libs/vm_manager/image_aggregator.h b/host/commands/launch/image_aggregator.h
similarity index 93%
rename from host/libs/vm_manager/image_aggregator.h
rename to host/commands/launch/image_aggregator.h
index fd1a9f6..2534323 100644
--- a/host/libs/vm_manager/image_aggregator.h
+++ b/host/commands/launch/image_aggregator.h
@@ -19,8 +19,6 @@
 #include <string>
 #include <vector>
 
-namespace vm_manager {
-
 struct ImagePartition {
   std::string label;
   std::string image_file_path;
@@ -28,6 +26,3 @@
 
 void aggregate_image(const std::vector<ImagePartition>& partitions,
                      const std::string& output_path);
-
-} // namespace vm_manager
-
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 37a578d..279720a 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -90,15 +90,7 @@
 const char* kKernelCmdline = "kernel_cmdline";
 const char* kRamdiskImagePath = "ramdisk_image_path";
 
-const char* kSystemImagePath = "system_image_path";
-const char* kCacheImagePath = "cache_image_path";
-const char* kDataImagePath = "data_image_path";
-const char* kVendorImagePath = "vendor_image_path";
-const char* kMetadataImagePath = "metadata_image_path";
-const char* kProductImagePath = "product_image_path";
-const char* kSuperImagePath = "super_image_path";
-const char* kBootImagePath = "boot_image_path";
-const char* kCompositeDiskPath = "composite_disk_path";
+const char* kVirtualDiskPaths = "virtual_disk_paths";
 const char* kUsbV1SocketName = "usb_v1_socket_name";
 const char* kVhciPort = "vhci_port";
 const char* kUsbIpSocketName = "usb_ip_socket_name";
@@ -358,75 +350,21 @@
   SetPath(kRamdiskImagePath, ramdisk_image_path);
 }
 
-std::string CuttlefishConfig::system_image_path() const {
-  return (*dictionary_)[kSystemImagePath].asString();
+std::vector<std::string> CuttlefishConfig::virtual_disk_paths() const {
+  std::vector<std::string> virtual_disks;
+  auto virtual_disks_json_obj = (*dictionary_)[kVirtualDiskPaths];
+  for (const auto& disk : virtual_disks_json_obj) {
+    virtual_disks.push_back(disk.asString());
+  }
+  return virtual_disks;
 }
-void CuttlefishConfig::set_system_image_path(
-    const std::string& system_image_path) {
-  SetPath(kSystemImagePath, system_image_path);
-}
-
-std::string CuttlefishConfig::cache_image_path() const {
-  return (*dictionary_)[kCacheImagePath].asString();
-}
-void CuttlefishConfig::set_cache_image_path(
-    const std::string& cache_image_path) {
-  SetPath(kCacheImagePath, cache_image_path);
-}
-
-std::string CuttlefishConfig::data_image_path() const {
-  return (*dictionary_)[kDataImagePath].asString();
-}
-void CuttlefishConfig::set_data_image_path(const std::string& data_image_path) {
-  SetPath(kDataImagePath, data_image_path);
-}
-
-std::string CuttlefishConfig::vendor_image_path() const {
-  return (*dictionary_)[kVendorImagePath].asString();
-}
-void CuttlefishConfig::set_vendor_image_path(
-    const std::string& vendor_image_path) {
-  SetPath(kVendorImagePath, vendor_image_path);
-}
-
-std::string CuttlefishConfig::metadata_image_path() const {
-  return (*dictionary_)[kMetadataImagePath].asString();
-}
-void CuttlefishConfig::set_metadata_image_path(
-    const std::string& metadata_image_path) {
-  SetPath(kMetadataImagePath, metadata_image_path);
-}
-
-std::string CuttlefishConfig::super_image_path() const {
-  return (*dictionary_)[kSuperImagePath].asString();
-}
-void CuttlefishConfig::set_super_image_path(
-    const std::string& super_image_path) {
-  SetPath(kSuperImagePath, super_image_path);
-}
-
-std::string CuttlefishConfig::boot_image_path() const {
-  return (*dictionary_)[kBootImagePath].asString();
-}
-void CuttlefishConfig::set_boot_image_path(
-    const std::string& boot_image_path) {
-  SetPath(kBootImagePath, boot_image_path);
-}
-
-std::string CuttlefishConfig::composite_disk_path() const {
-  return (*dictionary_)[kCompositeDiskPath].asString();
-}
-void CuttlefishConfig::set_composite_disk_path(
-    const std::string& composite_disk_path) {
-  SetPath(kCompositeDiskPath, composite_disk_path);
-}
-
-std::string CuttlefishConfig::product_image_path() const {
-  return (*dictionary_)[kProductImagePath].asString();
-}
-void CuttlefishConfig::set_product_image_path(
-    const std::string& product_image_path) {
-  SetPath(kProductImagePath, product_image_path);
+void CuttlefishConfig::set_virtual_disk_paths(
+    const std::vector<std::string>& virtual_disk_paths) {
+  Json::Value virtual_disks_json_obj(Json::arrayValue);
+  for (const auto& arg : virtual_disk_paths) {
+    virtual_disks_json_obj.append(arg);
+  }
+  (*dictionary_)[kVirtualDiskPaths] = virtual_disks_json_obj;
 }
 
 std::string CuttlefishConfig::dtb_path() const {
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 63284b3..0a48ee0 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -135,32 +135,8 @@
   std::string ramdisk_image_path() const;
   void set_ramdisk_image_path(const std::string& ramdisk_image_path);
 
-  std::string system_image_path() const;
-  void set_system_image_path(const std::string& system_image_path);
-
-  std::string cache_image_path() const;
-  void set_cache_image_path(const std::string& cache_image_path);
-
-  std::string data_image_path() const;
-  void set_data_image_path(const std::string& data_image_path);
-
-  std::string vendor_image_path() const;
-  void set_vendor_image_path(const std::string& vendor_image_path);
-
-  std::string metadata_image_path() const;
-  void set_metadata_image_path(const std::string& metadata_image_path);
-
-  std::string product_image_path() const;
-  void set_product_image_path(const std::string& product_image_path);
-
-  std::string super_image_path() const;
-  void set_super_image_path(const std::string& super_image_path);
-
-  std::string boot_image_path() const;
-  void set_boot_image_path(const std::string& boot_image_path);
-
-  std::string composite_disk_path() const;
-  void set_composite_disk_path(const std::string& composite_disk_path);
+  std::vector<std::string> virtual_disk_paths() const;
+  void set_virtual_disk_paths(const std::vector<std::string>& disk_paths);
 
   std::string dtb_path() const;
   void set_dtb_path(const std::string& dtb_path);
diff --git a/host/libs/vm_manager/Android.bp b/host/libs/vm_manager/Android.bp
index d2f19b8..6c638ea 100644
--- a/host/libs/vm_manager/Android.bp
+++ b/host/libs/vm_manager/Android.bp
@@ -17,8 +17,6 @@
     name: "libcuttlefish_vm_manager",
     srcs: [
         "crosvm_manager.cpp",
-        "disk_config.cpp",
-        "image_aggregator.cpp",
         "qemu_manager.cpp",
         "vm_manager.cpp",
     ],
@@ -45,9 +43,3 @@
     srcs: ["cf_qemu.sh"],
     defaults: ["cuttlefish_host_only"],
 }
-
-cc_prebuilt_binary {
-    name: "cf_bpttool",
-    srcs: ["cf_bpttool"],
-    defaults: ["cuttlefish_host_only"],
-}
diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh
index e81e1de..66ad15b 100755
--- a/host/libs/vm_manager/cf_qemu.sh
+++ b/host/libs/vm_manager/cf_qemu.sh
@@ -100,42 +100,20 @@
     -device "virtio-serial-pci,id=virtio-serial0"
 )
 
-if [[ -n "${composite_disk_path}" ]]; then
-  args+=(
-    -drive "file=${composite_disk_path:-${HOME}/composite.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-    -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1"
-  )
-else
-  if [[ -n "${super_image_path}" ]]; then
-    args+=(
-      -drive "file=${super_image_path:-${HOME}/obj/PACKAGING/super.img_intermediates/super.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0"
-    )
+IFS=';' read -ra virtual_disk_array <<< "$virtual_disk_paths"
+virtual_disk_index=0
+for virtual_disk in "${virtual_disk_array[@]}"; do
+  if [[ $virtual_disk_index == 0 ]]; then
+    bootindex=",bootindex=1"
   else
-    args+=(
-      -drive "file=${system_image_path:-${HOME}/system.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1"
-    )
+    bootindex=""
   fi
-
   args+=(
-      -drive "file=${data_image_path:-${HOME}/userdata.img},format=raw,if=none,id=drive-virtio-disk1,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk1,id=virtio-disk1"
-      -drive "file=${cache_image_path:-${HOME}/cache.img},format=raw,if=none,id=drive-virtio-disk2,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk2,id=virtio-disk2"
-      -drive "file=${metadata_image_path:-${HOME}/metadata.img},format=raw,if=none,id=drive-virtio-disk3,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk3,id=virtio-disk3"
+    -drive "file=${virtual_disk},format=raw,if=none,id=drive-virtio-disk${virtual_disk_index},aio=threads"
+    -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk${virtual_disk_index},id=virtio-disk${virtual_disk_index}${bootindex}"
   )
-
-  if [[ -z "${super_image_path}" ]]; then
-    args+=(
-      -drive "file=${vendor_image_path:-${HOME}/vendor.img},format=raw,if=none,id=drive-virtio-disk4,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk4,id=virtio-disk4"
-      -drive "file=${product_image_path:-${HOME}/product.img},format=raw,if=none,id=drive-virtio-disk5,aio=threads"
-      -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk5,id=virtio-disk5"
-    )
-  fi
-fi
+  virtual_disk_index=$((virtual_disk_index + 1))
+done
 
 args+=(
     -netdev "tap,id=hostnet0,ifname=${wifi_tap_name:-${default_wifi_tap_name}},script=no,downscript=no"
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index 2aeb267..9566ba9 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -24,7 +24,6 @@
 #include "common/libs/utils/network.h"
 #include "common/libs/utils/subprocess.h"
 #include "host/libs/config/cuttlefish_config.h"
-#include "host/libs/vm_manager/disk_config.h"
 #include "host/libs/vm_manager/qemu_manager.h"
 
 namespace vm_manager {
@@ -96,24 +95,8 @@
   crosvm_cmd.AddParameter("--mem=", config_->memory_mb());
   crosvm_cmd.AddParameter("--cpus=", config_->cpus());
   crosvm_cmd.AddParameter("--params=", config_->kernel_cmdline_as_string());
-  if (config_->composite_disk_path().empty()) {
-    if (config_->super_image_path().empty()) {
-      crosvm_cmd.AddParameter("--rwdisk=", config_->system_image_path());
-    } else {
-      crosvm_cmd.AddParameter("--rwdisk=", config_->super_image_path());
-    }
-    crosvm_cmd.AddParameter("--rwdisk=", config_->data_image_path());
-    crosvm_cmd.AddParameter("--rwdisk=", config_->cache_image_path());
-    crosvm_cmd.AddParameter("--rwdisk=", config_->metadata_image_path());
-    if (config_->super_image_path().empty()) {
-      crosvm_cmd.AddParameter("--rwdisk=", config_->vendor_image_path());
-      crosvm_cmd.AddParameter("--rwdisk=", config_->product_image_path());
-    }
-  } else {
-    if (should_create_composite_disk(*config_)) {
-      create_composite_disk(*config_);
-    }
-    crosvm_cmd.AddParameter("--rwdisk=", config_->composite_disk_path());
+  for (const auto& disk : config_->virtual_disk_paths()) {
+    crosvm_cmd.AddParameter("--rwdisk=", disk);
   }
   crosvm_cmd.AddParameter("--socket=", GetControlSocketPath(config_));
   if (!config_->gsi_fstab_path().empty()) {
diff --git a/host/libs/vm_manager/disk_config.cpp b/host/libs/vm_manager/disk_config.cpp
deleted file mode 100644
index 1616d69..0000000
--- a/host/libs/vm_manager/disk_config.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "host/libs/vm_manager/disk_config.h"
-
-#include <vector>
-
-#include <glog/logging.h>
-
-#include "common/libs/utils/files.h"
-#include "host/libs/vm_manager/image_aggregator.h"
-#include "host/libs/config/cuttlefish_config.h"
-
-namespace vm_manager {
-
-namespace {
-
-std::vector<ImagePartition> disk_config(const vsoc::CuttlefishConfig& config) {
-  std::vector<ImagePartition> partitions;
-  if (config.super_image_path().empty()) {
-    partitions.push_back(ImagePartition {
-      .label = "system",
-      .image_file_path = config.system_image_path(),
-    });
-  } else {
-    partitions.push_back(ImagePartition {
-      .label = "super",
-      .image_file_path = config.super_image_path(),
-    });
-  }
-  partitions.push_back(ImagePartition {
-    .label = "userdata",
-    .image_file_path = config.data_image_path(),
-  });
-  partitions.push_back(ImagePartition {
-    .label = "cache",
-    .image_file_path = config.cache_image_path(),
-  });
-  partitions.push_back(ImagePartition {
-    .label = "metadata",
-    .image_file_path = config.metadata_image_path(),
-  });
-  if (config.super_image_path().empty()) {
-    partitions.push_back(ImagePartition {
-      .label = "product",
-      .image_file_path = config.product_image_path(),
-    });
-    partitions.push_back(ImagePartition {
-      .label = "vendor",
-      .image_file_path = config.vendor_image_path(),
-    });
-  }
-  partitions.push_back(ImagePartition {
-    .label = "boot",
-    .image_file_path = config.boot_image_path(),
-  });
-  return partitions;
-}
-
-} // namespace
-
-bool should_create_composite_disk(const vsoc::CuttlefishConfig& config) {
-  if (config.composite_disk_path().empty()) {
-    return false;
-  }
-  auto composite_age = cvd::FileModificationTime(config.composite_disk_path());
-  for (auto& partition : disk_config(config)) {
-    auto partition_age = cvd::FileModificationTime(partition.image_file_path);
-    if (partition_age >= composite_age) {
-      LOG(INFO) << "composite disk age was \"" << std::chrono::system_clock::to_time_t(composite_age) << "\", "
-                << "partition age was \"" << std::chrono::system_clock::to_time_t(partition_age) << "\"";
-      return true;
-    }
-  }
-  return false;
-}
-
-void create_composite_disk(const vsoc::CuttlefishConfig& config) {
-  if (config.composite_disk_path().empty()) {
-    LOG(FATAL) << "asked to create composite disk, but path was empty";
-  }
-  aggregate_image(disk_config(config), config.composite_disk_path());
-}
-
-} // namespace vm_manager
diff --git a/host/libs/vm_manager/disk_config.h b/host/libs/vm_manager/disk_config.h
deleted file mode 100644
index 1f577b4..0000000
--- a/host/libs/vm_manager/disk_config.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#pragma once
-
-#include <host/libs/config/cuttlefish_config.h>
-
-namespace vm_manager {
-
-bool should_create_composite_disk(const vsoc::CuttlefishConfig& config);
-void create_composite_disk(const vsoc::CuttlefishConfig& config);
-
-} // namespace vm_manager
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 85ba36c..384685a 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -37,7 +37,6 @@
 #include "common/libs/utils/subprocess.h"
 #include "common/libs/utils/users.h"
 #include "host/libs/config/cuttlefish_config.h"
-#include "host/libs/vm_manager/disk_config.h"
 
 namespace vm_manager {
 
@@ -52,6 +51,21 @@
   LOG(INFO) << key << "=" << value;
 }
 
+std::string JoinString(const std::vector<std::string>& args,
+                       const std::string& delim) {
+  bool first = true;
+  std::stringstream output;
+  for (const auto& arg : args) {
+    if (first) {
+      first = false;
+    } else {
+      output << delim;
+    }
+    output << arg;
+  }
+  return output.str();
+}
+
 }  // namespace
 
 const std::string QemuManager::name() { return "qemu_cli"; }
@@ -83,10 +97,6 @@
   : VmManager(config) {}
 
 std::vector<cvd::Command> QemuManager::StartCommands(bool /*with_frontend*/) {
-  if (should_create_composite_disk(*config_)) {
-    create_composite_disk(*config_);
-  }
-
   // Set the config values in the environment
   LogAndSetEnv("qemu_binary", config_->qemu_binary());
   LogAndSetEnv("instance_name", config_->instance_name());
@@ -99,14 +109,8 @@
   LogAndSetEnv("ramdisk_image_path", config_->ramdisk_image_path());
   LogAndSetEnv("kernel_cmdline", config_->kernel_cmdline_as_string());
   LogAndSetEnv("dtb_path", config_->dtb_path());
-  LogAndSetEnv("system_image_path", config_->system_image_path());
-  LogAndSetEnv("data_image_path", config_->data_image_path());
-  LogAndSetEnv("cache_image_path", config_->cache_image_path());
-  LogAndSetEnv("vendor_image_path", config_->vendor_image_path());
-  LogAndSetEnv("metadata_image_path", config_->metadata_image_path());
-  LogAndSetEnv("product_image_path", config_->product_image_path());
-  LogAndSetEnv("super_image_path", config_->super_image_path());
-  LogAndSetEnv("composite_disk_path", config_->composite_disk_path());
+  LogAndSetEnv("virtual_disk_paths", JoinString(config_->virtual_disk_paths(),
+                                                ";"));
   LogAndSetEnv("wifi_tap_name", config_->wifi_tap_name());
   LogAndSetEnv("mobile_tap_name", config_->mobile_tap_name());
   LogAndSetEnv("kernel_log_pipe_name",