Use qcow files

Bug: 146236379
Test: Run with https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1956487
Change-Id: I4d759c9337701e45f253f9fea5a32eb6e69f73af
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index f9b183d..09c1e09 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -93,8 +93,8 @@
 DEFINE_string(misc_image, "",
               "Location of the misc partition image. If the image does not "
               "exist, a blank new misc partition image is created.");
-DEFINE_string(composite_disk, "", "Location of the composite disk image. "
-                                  "If empty, a composite disk is not used.");
+DEFINE_string(composite_disk, "", "Location of the composite disk image. ");
+DEFINE_string(overlay_disk, "", "Location of the overlay disk.");
 
 DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
             " host kernel. This is only used during transition of our clients."
@@ -205,6 +205,9 @@
   std::string default_composite_disk = FLAGS_system_image_dir + "/composite.img";
   SetCommandLineOptionWithMode("composite_disk", default_composite_disk.c_str(),
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
+  std::string default_overlay_disk = FLAGS_system_image_dir + "/overlay.img";
+  SetCommandLineOptionWithMode("overlay_disk", default_overlay_disk.c_str(),
+                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
   std::string default_vendor_boot_image = FLAGS_system_image_dir
                                         + "/vendor_boot.img";
   SetCommandLineOptionWithMode("vendor_boot_image",
@@ -309,7 +312,7 @@
   tmp_config_obj.set_guest_force_normal_boot(FLAGS_guest_force_normal_boot);
   tmp_config_obj.set_extra_kernel_cmdline(FLAGS_extra_kernel_cmdline);
 
-  tmp_config_obj.set_virtual_disk_paths({FLAGS_composite_disk});
+  tmp_config_obj.set_virtual_disk_paths({FLAGS_overlay_disk});
 
   tmp_config_obj.set_ramdisk_image_path(ramdisk_path);
   tmp_config_obj.set_vendor_ramdisk_image_path(vendor_ramdisk_path);
@@ -594,6 +597,9 @@
     LOG(ERROR) << "Could not ensure " << FLAGS_composite_disk << " exists";
     return false;
   }
+  if (FLAGS_overlay_disk.empty()) {
+    LOG(FATAL) << "asked to create overlay disk, but path was empty";
+  }
   if (FLAGS_vm_manager == vm_manager::CrosvmManager::name()) {
     auto existing_size = cvd::FileSize(FLAGS_data_image);
     auto available_space = AvailableSpaceAtPath(FLAGS_data_image);
@@ -606,7 +612,8 @@
     }
     std::string header_path = config.AssemblyPath("gpt_header.img");
     std::string footer_path = config.AssemblyPath("gpt_footer.img");
-    create_composite_disk(disk_config(), header_path, footer_path, FLAGS_composite_disk);
+    create_composite_disk_and_overlay(config.crosvm_binary(), disk_config(), header_path,
+                                      footer_path, FLAGS_composite_disk, FLAGS_overlay_disk);
   } else {
     auto existing_size = cvd::FileSize(FLAGS_composite_disk);
     auto available_space = AvailableSpaceAtPath(FLAGS_composite_disk);
diff --git a/host/commands/assemble_cvd/image_aggregator.cc b/host/commands/assemble_cvd/image_aggregator.cc
index 17fe9db..abe3795 100644
--- a/host/commands/assemble_cvd/image_aggregator.cc
+++ b/host/commands/assemble_cvd/image_aggregator.cc
@@ -221,6 +221,19 @@
   }
 }
 
+void CreateQcowOverlay(const std::string& crosvm_path,
+                       const std::string& backing_file,
+                       const std::string& output_overlay_path) {
+  cvd::Command crosvm_qcow2_cmd(crosvm_path);
+  crosvm_qcow2_cmd.AddParameter("create_qcow2");
+  crosvm_qcow2_cmd.AddParameter("--backing_file=", backing_file);
+  crosvm_qcow2_cmd.AddParameter(output_overlay_path);
+  int success = crosvm_qcow2_cmd.Start().Wait();
+  if (success != 0) {
+    LOG(FATAL) << "Unable to run crosvm create_qcow2. Exited with status " << success;
+  }
+}
+
 } // namespace
 
 void aggregate_image(const std::vector<ImagePartition>& partitions,
@@ -231,18 +244,21 @@
   bpttool_make_disk_image(partitions, table_fd, output_path);
 };
 
-void create_composite_disk(std::vector<ImagePartition> partitions,
-                           const std::string& header_file,
-                           const std::string& footer_file,
-                           const std::string& output_path) {
+void create_composite_disk_and_overlay(const std::string& crosvm_path,
+                                       std::vector<ImagePartition> partitions,
+                                       const std::string& header_file,
+                                       const std::string& footer_file,
+                                       const std::string& output_composite_path,
+                                       const std::string& output_overlay_path) {
   auto bpttool_input_json = bpttool_input(partitions);
   auto table_fd = bpttool_make_table(json_to_fd(bpttool_input_json));
   auto table = fd_to_json(table_fd);
   auto partition_table_fd = bpttool_make_partition_table(json_to_fd(bpttool_input_json));
   CreateGptFiles(partition_table_fd, header_file, footer_file);
   auto composite_proto = MakeCompositeDiskSpec(table, partitions, header_file, footer_file);
-  std::ofstream output(output_path.c_str(), std::ios::binary | std::ios::trunc);
-  output << "composite_disk\x1d";
-  composite_proto.SerializeToOstream(&output);
-  output.flush();
+  std::ofstream composite(output_composite_path.c_str(), std::ios::binary | std::ios::trunc);
+  composite << "composite_disk\x1d";
+  composite_proto.SerializeToOstream(&composite);
+  composite.flush();
+  CreateQcowOverlay(crosvm_path, output_composite_path, output_overlay_path);
 }
diff --git a/host/commands/assemble_cvd/image_aggregator.h b/host/commands/assemble_cvd/image_aggregator.h
index a4394e8..22e6405 100644
--- a/host/commands/assemble_cvd/image_aggregator.h
+++ b/host/commands/assemble_cvd/image_aggregator.h
@@ -26,7 +26,9 @@
 
 void aggregate_image(const std::vector<ImagePartition>& partitions,
                      const std::string& output_path);
-void create_composite_disk(std::vector<ImagePartition> partitions,
-                           const std::string& header_file,
-                           const std::string& footer_file,
-                           const std::string& output_path);
+void create_composite_disk_and_overlay(const std::string& crosvm_path,
+                                       std::vector<ImagePartition> partitions,
+                                       const std::string& header_file,
+                                       const std::string& footer_file,
+                                       const std::string& output_composite_path,
+                                       const std::string& output_overlay_path);