aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-25 01:01:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-25 01:01:37 +0000
commitce84e3c28a257a0114ac4ddbdc81a802713993b2 (patch)
tree51a3372262bc2f440c21b5d4f63a057e798a2f0c
parentb4a2154f76d687bf5fd49df9e41a684ebdf4770e (diff)
parent53d315479d9ad006344a81f37149509b64ad741e (diff)
downloadcuttlefish-sdk-release.tar.gz
Snap for 11762235 from 53d315479d9ad006344a81f37149509b64ad741e to sdk-releasesdk-release
Change-Id: Ib80d972344546d164e1f74448d8e02bc013f8d3f
-rw-r--r--build/Android.bp31
-rw-r--r--common/libs/utils/files.cpp52
-rw-r--r--common/libs/utils/files.h2
-rw-r--r--host/commands/assemble_cvd/flags.cc2
-rw-r--r--host/commands/assemble_cvd/graphics_flags.cc8
-rw-r--r--host/commands/assemble_cvd/misc_info.cc34
-rw-r--r--host/commands/assemble_cvd/misc_info.h4
-rw-r--r--host/commands/assemble_cvd/super_image_mixer.cc260
-rw-r--r--host/libs/config/config_utils.cpp20
-rw-r--r--host/libs/config/config_utils.h5
-rw-r--r--host/libs/vm_manager/crosvm_manager.cpp15
-rw-r--r--host/libs/vm_manager/qemu_manager.cpp3
12 files changed, 276 insertions, 160 deletions
diff --git a/build/Android.bp b/build/Android.bp
index 33563de5a..1e69ce018 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -45,6 +45,33 @@ soong_config_module_type {
],
}
+// Start of generated qemu_aarch64_linux_gnu_binary
+// Generated by gen_android_bp.py
+qemu_aarch64_linux_gnu_binary = [
+ "aarch64_linux_gnu_libc++.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_libc++abi.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_libepoxy.so.0_binary_for_qemu",
+ "aarch64_linux_gnu_libgbm.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_libgfxstream_backend.so.0_binary_for_qemu",
+ "aarch64_linux_gnu_librutabaga_gfx_ffi.so.0_binary_for_qemu",
+ "aarch64_linux_gnu_libunwind.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_libvirglrenderer.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_libz.so.1_binary_for_qemu",
+ "aarch64_linux_gnu_qemu-system-aarch64_binary_for_qemu",
+ "aarch64_linux_gnu_qemu-system-riscv64_binary_for_qemu",
+ "aarch64_linux_gnu_qemu-system-x86_64_binary_for_qemu",
+]
+// End of generated qemu_aarch64_linux_gnu_binary
+
+// Start of generated qemu_aarch64_linux_gnu_resource
+// Generated by gen_android_bp.py
+qemu_aarch64_linux_gnu_resource = [
+ "aarch64_efi-virtio.rom_resource_for_qemu",
+ "aarch64_en-us_resource_for_qemu",
+ "aarch64_opensbi-riscv64-generic-fw_dynamic.bin_resource_for_qemu",
+]
+// End of generated qemu_aarch64_linux_gnu_resource
+
// Start of generated qemu_x86_64_linux_gnu_binary
// Generated by gen_android_bp.py
qemu_x86_64_linux_gnu_binary = [
@@ -247,7 +274,7 @@ cvd_host_aarch64_crosvm = [
"aarch64_linux_gnu_libwayland_client.so.0_for_crosvm",
]
-cvd_host_aarch64 = cvd_host_aarch64_crosvm + cvd_host_aarch64_graphics_detector
+cvd_host_aarch64 = cvd_host_aarch64_crosvm + cvd_host_aarch64_graphics_detector + qemu_aarch64_linux_gnu_binary
cvd_host_seccomp_policy_x86_64 = [
"9p_device.policy_x86_64",
@@ -428,7 +455,7 @@ cvd_host_package_customization {
deps: cvd_host_aarch64,
multilib: {
common: {
- deps: cvd_host_seccomp_policy_aarch64,
+ deps: cvd_host_seccomp_policy_aarch64 + qemu_aarch64_linux_gnu_resource,
},
},
},
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 5fa1e6ecf..0f9f93ec1 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -52,6 +52,7 @@
#include <numeric>
#include <ostream>
#include <ratio>
+#include <regex>
#include <string>
#include <vector>
@@ -663,6 +664,57 @@ Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec) {
return CF_ERR("This shouldn't be executed");
}
+
+Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path,
+ int timeoutSec) {
+ const auto targetTime =
+ std::chrono::system_clock::now() + std::chrono::seconds(timeoutSec);
+
+ CF_EXPECT(WaitForFile(path, timeoutSec),
+ "Waiting for socket path creation failed");
+ CF_EXPECT(FileIsSocket(path), "Specified path is not a socket");
+
+ std::regex socket_state_regex("TST=(.*)");
+
+ while (true) {
+ const auto currentTime = std::chrono::system_clock::now();
+
+ if (currentTime >= targetTime) {
+ return CF_ERR("Timed out");
+ }
+
+ Command lsof("lsof");
+ lsof.AddParameter(/*"format"*/ "-F", /*"connection state"*/ "TST");
+ lsof.AddParameter(path);
+ std::string lsof_out;
+ std::string lsof_err;
+ int rval =
+ RunWithManagedStdio(std::move(lsof), nullptr, &lsof_out, &lsof_err);
+ if (rval != 0) {
+ return CF_ERR("Failed to run `lsof`, stderr: " << lsof_err);
+ }
+
+ LOG(DEBUG) << "lsof stdout:" << lsof_out;
+
+ std::smatch socket_state_match;
+ if (!std::regex_search(lsof_out, socket_state_match, socket_state_regex)) {
+ return CF_ERR("Failed to find state in `lsof` stdout: " << lsof_out);
+ }
+ if (socket_state_match.size() != 2) {
+ return CF_ERR(
+ "Unexpected number of matches in `lsof` stdout: " << lsof_out);
+ }
+
+ const std::string& socket_state = socket_state_match[1];
+ if (socket_state == "LISTEN") {
+ return {};
+ }
+
+ sched_yield();
+ }
+
+ return CF_ERR("This shouldn't be executed");
+}
#endif
namespace {
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index cf13dea72..6e423cda4 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -84,6 +84,8 @@ Result<void> WalkDirectory(
#ifdef __linux__
Result<void> WaitForFile(const std::string& path, int timeoutSec);
Result<void> WaitForUnixSocket(const std::string& path, int timeoutSec);
+Result<void> WaitForUnixSocketListeningWithoutConnect(const std::string& path,
+ int timeoutSec);
#endif
// parameter to EmulateAbsolutePath
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index 6b86737f8..4a74ac5e7 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -543,7 +543,7 @@ Result<std::string> GetAndroidInfoConfig(
CF_EXPECT(FileExists(android_info_file_path));
std::string android_info_contents = ReadFile(android_info_file_path);
- auto android_info_map = ParseMiscInfo(android_info_contents);
+ auto android_info_map = CF_EXPECT(ParseMiscInfo(android_info_contents));
CF_EXPECT(android_info_map.find(key) != android_info_map.end());
return android_info_map[key];
}
diff --git a/host/commands/assemble_cvd/graphics_flags.cc b/host/commands/assemble_cvd/graphics_flags.cc
index bd43ff097..e5e7e4424 100644
--- a/host/commands/assemble_cvd/graphics_flags.cc
+++ b/host/commands/assemble_cvd/graphics_flags.cc
@@ -260,8 +260,8 @@ Result<std::string> SelectGpuMode(
LOG(INFO) << "GPU auto mode: detected prerequisites for accelerated "
<< "rendering support.";
- if (vm_manager == vm_manager::QemuManager::name() && !UseQemu8()) {
- LOG(INFO) << "Not using QEMU8: selecting guest swiftshader";
+ if (vm_manager == vm_manager::QemuManager::name() && !UseQemuPrebuilt()) {
+ LOG(INFO) << "Not using QEMU prebuilt (QEMU 8+): selecting guest swiftshader";
return kGpuModeGuestSwiftshader;
} else if (!guest_config.gfxstream_supported) {
LOG(INFO) << "GPU auto mode: guest does not support gfxstream, "
@@ -290,8 +290,8 @@ Result<std::string> SelectGpuMode(
"--gpu_mode=auto or --gpu_mode=guest_swiftshader.";
}
- if (vm_manager == vm_manager::QemuManager::name() && !UseQemu8()) {
- LOG(INFO) << "Not using QEMU8: selecting guest swiftshader";
+ if (vm_manager == vm_manager::QemuManager::name() && !UseQemuPrebuilt()) {
+ LOG(INFO) << "Not using QEMU prebuilt (QEMU 8+): selecting guest swiftshader";
return kGpuModeGuestSwiftshader;
}
}
diff --git a/host/commands/assemble_cvd/misc_info.cc b/host/commands/assemble_cvd/misc_info.cc
index e96099c4d..292258b96 100644
--- a/host/commands/assemble_cvd/misc_info.cc
+++ b/host/commands/assemble_cvd/misc_info.cc
@@ -16,14 +16,26 @@
#include "misc_info.h"
#include <algorithm>
+#include <string>
+#include <vector>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include "common/libs/utils/contains.h"
+#include "common/libs/utils/result.h"
+
namespace cuttlefish {
+namespace {
+
+constexpr char kDynamicPartitions[] = "dynamic_partition_list";
+constexpr char kGoogleDynamicPartitions[] = "google_dynamic_partitions";
+constexpr char kSuperPartitionGroups[] = "super_partition_groups";
+
+} // namespace
-MiscInfo ParseMiscInfo(const std::string& misc_info_contents) {
+Result<MiscInfo> ParseMiscInfo(const std::string& misc_info_contents) {
auto lines = android::base::Split(misc_info_contents, "\n");
MiscInfo misc_info;
for (auto& line : lines) {
@@ -37,13 +49,13 @@ MiscInfo ParseMiscInfo(const std::string& misc_info_contents) {
continue;
}
// Not using android::base::Split here to only capture the first =
- auto key = android::base::Trim(line.substr(0, eq_pos));
- auto value = android::base::Trim(line.substr(eq_pos + 1));
- if (misc_info.find(key) != misc_info.end() && misc_info[key] != value) {
- LOG(ERROR) << "Duplicate key: \"" << key << "\". First value: \""
- << misc_info[key] << "\", Second value: \"" << value << "\"";
- return {};
- }
+ const auto key = android::base::Trim(line.substr(0, eq_pos));
+ const auto value = android::base::Trim(line.substr(eq_pos + 1));
+ const bool duplicate = Contains(misc_info, key) && misc_info[key] != value;
+ CF_EXPECTF(!duplicate,
+ "Duplicate key with different value. key:\"{}\", previous "
+ "value:\"{}\", this value:\"{}\"",
+ key, misc_info[key], value);
misc_info[key] = value;
}
return misc_info;
@@ -57,8 +69,6 @@ std::string WriteMiscInfo(const MiscInfo& misc_info) {
return out.str();
}
-static const std::string kDynamicPartitions = "dynamic_partition_list";
-
std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) {
auto value_it = info.find(kDynamicPartitions);
if (value_it == info.end()) {
@@ -73,10 +83,6 @@ std::vector<std::string> SuperPartitionComponents(const MiscInfo& info) {
return components;
}
-static constexpr const char* kGoogleDynamicPartitions =
- "google_dynamic_partitions";
-static constexpr const char* kSuperPartitionGroups = "super_partition_groups";
-
bool SetSuperPartitionComponents(const std::vector<std::string>& components,
MiscInfo* misc_info) {
auto super_partition_groups = misc_info->find(kSuperPartitionGroups);
diff --git a/host/commands/assemble_cvd/misc_info.h b/host/commands/assemble_cvd/misc_info.h
index aa130bcc9..f832a4c5f 100644
--- a/host/commands/assemble_cvd/misc_info.h
+++ b/host/commands/assemble_cvd/misc_info.h
@@ -19,11 +19,13 @@
#include <string>
#include <vector>
+#include "common/libs/utils/result.h"
+
namespace cuttlefish {
using MiscInfo = std::map<std::string, std::string>;
-MiscInfo ParseMiscInfo(const std::string& file_contents);
+Result<MiscInfo> ParseMiscInfo(const std::string& file_contents);
std::string WriteMiscInfo(const MiscInfo& info);
std::vector<std::string> SuperPartitionComponents(const MiscInfo&);
diff --git a/host/commands/assemble_cvd/super_image_mixer.cc b/host/commands/assemble_cvd/super_image_mixer.cc
index 8f445310a..b59d163fb 100644
--- a/host/commands/assemble_cvd/super_image_mixer.cc
+++ b/host/commands/assemble_cvd/super_image_mixer.cc
@@ -30,6 +30,7 @@
#include "common/libs/utils/archive.h"
#include "common/libs/utils/contains.h"
#include "common/libs/utils/files.h"
+#include "common/libs/utils/result.h"
#include "common/libs/utils/subprocess.h"
#include "host/commands/assemble_cvd/misc_info.h"
#include "host/libs/config/config_utils.h"
@@ -37,59 +38,8 @@
#include "host/libs/config/fetcher_config.h"
namespace cuttlefish {
-
-Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config,
- const std::string& default_target_zip,
- const std::string& system_target_zip) {
- bool has_default_target_zip = false;
- bool has_system_target_zip = false;
- if (default_target_zip != "" &&
- default_target_zip != "unset") {
- has_default_target_zip = true;
- }
- if (system_target_zip != "" &&
- system_target_zip != "unset") {
- has_system_target_zip = true;
- }
- CF_EXPECT(has_default_target_zip == has_system_target_zip,
- "default_target_zip and system_target_zip "
- "flags must be specified together");
- // at this time, both should be the same, either true or false
- // therefore, I only check one variable
- if (has_default_target_zip) {
- return true;
- }
-
- bool has_default_build = false;
- bool has_system_build = false;
- for (const auto& file_iter : fetcher_config.get_cvd_files()) {
- if (file_iter.second.source == FileSource::DEFAULT_BUILD) {
- has_default_build = true;
- } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) {
- has_system_build = true;
- }
- }
- return has_default_build && has_system_build;
-}
-
namespace {
-std::string TargetFilesZip(const FetcherConfig& fetcher_config,
- FileSource source) {
- for (const auto& file_iter : fetcher_config.get_cvd_files()) {
- const auto& file_path = file_iter.first;
- const auto& file_info = file_iter.second;
- if (file_info.source != source) {
- continue;
- }
- std::string expected_filename = "target_files-" + file_iter.second.build_id;
- if (file_path.find(expected_filename) != std::string::npos) {
- return file_path;
- }
- }
- return "";
-}
-
constexpr char kMiscInfoPath[] = "META/misc_info.txt";
constexpr std::array kVendorTargetImages = {
"IMAGES/boot.img",
@@ -115,6 +65,13 @@ constexpr std::array kVendorTargetBuildProps = {
"VENDOR/etc/build.prop",
};
+struct TargetFiles {
+ Archive vendor_zip;
+ Archive system_zip;
+ std::vector<std::string> vendor_contents;
+ std::vector<std::string> system_contents;
+};
+
void FindImports(Archive* archive, const std::string& build_prop_file) {
auto contents = archive->ExtractToMemory(build_prop_file);
auto lines = android::base::Split(contents, "\n");
@@ -126,119 +83,126 @@ void FindImports(Archive* archive, const std::string& build_prop_file) {
}
}
-Result<void> CombineTargetZipFiles(const std::string& default_target_zip,
- const std::string& system_target_zip,
- const std::string& output_path) {
- Archive default_target_archive(default_target_zip);
- auto default_target_contents = default_target_archive.Contents();
- CF_EXPECT(default_target_contents.size() != 0,
- "Could not open " << default_target_zip);
-
- Archive system_target_archive(system_target_zip);
- auto system_target_contents = system_target_archive.Contents();
- CF_EXPECT(system_target_contents.size() != 0,
- "Could not open " << system_target_zip);
-
- CF_EXPECT(
- mkdir(output_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0,
- "Could not create directory " << output_path);
-
- std::string output_meta = output_path + "/META";
- CF_EXPECT(
- mkdir(output_meta.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) >= 0,
- "Could not create directory " << output_meta);
-
- CF_EXPECT(
- std::find(default_target_contents.begin(), default_target_contents.end(),
- kMiscInfoPath) != default_target_contents.end(),
- "Default target files zip does not have " << kMiscInfoPath);
-
- CF_EXPECT(
- std::find(system_target_contents.begin(), system_target_contents.end(),
- kMiscInfoPath) != system_target_contents.end(),
- "System target files zip does not have " << kMiscInfoPath);
-
- const auto default_misc =
- ParseMiscInfo(default_target_archive.ExtractToMemory(kMiscInfoPath));
- CF_EXPECT(default_misc.size() != 0,
- "Could not read the default misc_info.txt file.");
-
- const auto system_misc =
- ParseMiscInfo(system_target_archive.ExtractToMemory(kMiscInfoPath));
- CF_EXPECT(system_misc.size() != 0,
- "Could not read the system misc_info.txt file.");
+bool IsTargetFilesImage(const std::string& filename) {
+ return android::base::StartsWith(filename, "IMAGES/") &&
+ android::base::EndsWith(filename, ".img");
+}
+
+bool IsTargetFilesBuildProp(const std::string& filename) {
+ return android::base::EndsWith(filename, "build.prop");
+}
+
+Result<TargetFiles> GetTargetFiles(const std::string& vendor_zip_path,
+ const std::string& system_zip_path) {
+ auto result = TargetFiles{
+ .vendor_zip = Archive(vendor_zip_path),
+ .system_zip = Archive(system_zip_path),
+ };
+ result.vendor_contents = result.vendor_zip.Contents();
+ result.system_contents = result.system_zip.Contents();
+ CF_EXPECTF(!result.vendor_contents.empty(), "Could not open {}",
+ vendor_zip_path);
+ CF_EXPECTF(!result.system_contents.empty(), "Could not open {}",
+ system_zip_path);
+ return result;
+}
+
+Result<void> CombineMiscInfo(TargetFiles& target_files,
+ const std::string& misc_output_path) {
+ CF_EXPECTF(Contains(target_files.vendor_contents, kMiscInfoPath),
+ "Default target files zip does not contain {}", kMiscInfoPath);
+ CF_EXPECTF(Contains(target_files.system_contents, kMiscInfoPath),
+ "System target files zip does not contain {}", kMiscInfoPath);
+
+ const MiscInfo default_misc = CF_EXPECT(
+ ParseMiscInfo(target_files.vendor_zip.ExtractToMemory(kMiscInfoPath)));
+ const MiscInfo system_misc = CF_EXPECT(
+ ParseMiscInfo(target_files.system_zip.ExtractToMemory(kMiscInfoPath)));
auto output_misc = default_misc;
auto system_super_partitions = SuperPartitionComponents(system_misc);
// Ensure specific skipped partitions end up in the misc_info.txt
for (auto partition :
{"odm", "odm_dlkm", "vendor", "vendor_dlkm", "system_dlkm"}) {
- if (std::find(system_super_partitions.begin(), system_super_partitions.end(),
- partition) == system_super_partitions.end()) {
+ if (!Contains(system_super_partitions, partition)) {
system_super_partitions.push_back(partition);
}
}
CF_EXPECT(SetSuperPartitionComponents(system_super_partitions, &output_misc),
"Failed to update super partitions components for misc_info");
- auto misc_output_path = output_path + "/" + kMiscInfoPath;
- SharedFD misc_output_file =
- SharedFD::Creat(misc_output_path.c_str(), 0644);
+ SharedFD misc_output_file = SharedFD::Creat(misc_output_path.c_str(), 0644);
CF_EXPECT(misc_output_file->IsOpen(), "Failed to open output misc file: "
<< misc_output_file->StrError());
CF_EXPECT(WriteAll(misc_output_file, WriteMiscInfo(output_misc)) >= 0,
"Failed to write output misc file contents: "
<< misc_output_file->StrError());
+ return {};
+}
- for (const auto& name : default_target_contents) {
- if (!android::base::StartsWith(name, "IMAGES/")) {
- continue;
- } else if (!android::base::EndsWith(name, ".img")) {
+Result<void> ExtractTargetFiles(TargetFiles& target_files,
+ const std::string& combined_output_path) {
+ for (const auto& name : target_files.vendor_contents) {
+ if (!IsTargetFilesImage(name)) {
continue;
} else if (!Contains(kVendorTargetImages, name)) {
continue;
}
- LOG(INFO) << "Writing " << name;
- CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path),
- "Failed to extract " << name << " from the default target zip");
+ LOG(INFO) << "Writing " << name << " from vendor target";
+ CF_EXPECT(
+ target_files.vendor_zip.ExtractFiles({name}, combined_output_path),
+ "Failed to extract " << name << " from the vendor target zip");
}
- for (const auto& name : default_target_contents) {
- if (!android::base::EndsWith(name, "build.prop")) {
+ for (const auto& name : target_files.vendor_contents) {
+ if (!IsTargetFilesBuildProp(name)) {
continue;
} else if (!Contains(kVendorTargetBuildProps, name)) {
continue;
}
- FindImports(&default_target_archive, name);
- LOG(INFO) << "Writing " << name;
- CF_EXPECT(default_target_archive.ExtractFiles({name}, output_path),
- "Failed to extract " << name << " from the default target zip");
+ FindImports(&target_files.vendor_zip, name);
+ LOG(INFO) << "Writing " << name << " from vendor target";
+ CF_EXPECT(
+ target_files.vendor_zip.ExtractFiles({name}, combined_output_path),
+ "Failed to extract " << name << " from the vendor target zip");
}
- for (const auto& name : system_target_contents) {
- if (!android::base::StartsWith(name, "IMAGES/")) {
- continue;
- } else if (!android::base::EndsWith(name, ".img")) {
+ for (const auto& name : target_files.system_contents) {
+ if (!IsTargetFilesImage(name)) {
continue;
} else if (Contains(kVendorTargetImages, name)) {
continue;
}
- LOG(INFO) << "Writing " << name;
- CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path),
- "Failed to extract " << name << " from the system target zip");
+ LOG(INFO) << "Writing " << name << " from system target";
+ CF_EXPECT(
+ target_files.system_zip.ExtractFiles({name}, combined_output_path),
+ "Failed to extract " << name << " from the system target zip");
}
- for (const auto& name : system_target_contents) {
- if (!android::base::EndsWith(name, "build.prop")) {
+ for (const auto& name : target_files.system_contents) {
+ if (!IsTargetFilesBuildProp(name)) {
continue;
} else if (Contains(kVendorTargetBuildProps, name)) {
continue;
}
- FindImports(&system_target_archive, name);
- LOG(INFO) << "Writing " << name;
- CF_EXPECT(system_target_archive.ExtractFiles({name}, output_path),
- "Failed to extract " << name << " from the default target zip");
+ FindImports(&target_files.system_zip, name);
+ LOG(INFO) << "Writing " << name << " from system target";
+ CF_EXPECT(
+ target_files.system_zip.ExtractFiles({name}, combined_output_path),
+ "Failed to extract " << name << " from the system target zip");
}
+ return {};
+}
+Result<void> CombineTargetZipFiles(const std::string& vendor_zip_path,
+ const std::string& system_zip_path,
+ const std::string& output_path) {
+ CF_EXPECT(EnsureDirectoryExists(output_path));
+ CF_EXPECT(EnsureDirectoryExists(output_path + "/META"));
+ auto target_files =
+ CF_EXPECT(GetTargetFiles(vendor_zip_path, system_zip_path));
+ CF_EXPECT(ExtractTargetFiles(target_files, output_path));
+ const auto misc_output_path = output_path + "/" + kMiscInfoPath;
+ CF_EXPECT(CombineMiscInfo(target_files, misc_output_path));
return {};
}
@@ -258,6 +222,22 @@ bool BuildSuperImage(const std::string& combined_target_zip,
}) == 0;
}
+std::string TargetFilesZip(const FetcherConfig& fetcher_config,
+ FileSource source) {
+ for (const auto& file_iter : fetcher_config.get_cvd_files()) {
+ const auto& file_path = file_iter.first;
+ const auto& file_info = file_iter.second;
+ if (file_info.source != source) {
+ continue;
+ }
+ std::string expected_filename = "target_files-" + file_iter.second.build_id;
+ if (file_path.find(expected_filename) != std::string::npos) {
+ return file_path;
+ }
+ }
+ return "";
+}
+
Result<void> RebuildSuperImage(const FetcherConfig& fetcher_config,
const CuttlefishConfig& config,
const std::string& output_path) {
@@ -319,6 +299,38 @@ class SuperImageRebuilderImpl : public SuperImageRebuilder {
} // namespace
+Result<bool> SuperImageNeedsRebuilding(const FetcherConfig& fetcher_config,
+ const std::string& default_target_zip,
+ const std::string& system_target_zip) {
+ bool has_default_target_zip = false;
+ bool has_system_target_zip = false;
+ if (default_target_zip != "" && default_target_zip != "unset") {
+ has_default_target_zip = true;
+ }
+ if (system_target_zip != "" && system_target_zip != "unset") {
+ has_system_target_zip = true;
+ }
+ CF_EXPECT(has_default_target_zip == has_system_target_zip,
+ "default_target_zip and system_target_zip "
+ "flags must be specified together");
+ // at this time, both should be the same, either true or false
+ // therefore, I only check one variable
+ if (has_default_target_zip) {
+ return true;
+ }
+
+ bool has_default_build = false;
+ bool has_system_build = false;
+ for (const auto& file_iter : fetcher_config.get_cvd_files()) {
+ if (file_iter.second.source == FileSource::DEFAULT_BUILD) {
+ has_default_build = true;
+ } else if (file_iter.second.source == FileSource::SYSTEM_BUILD) {
+ has_system_build = true;
+ }
+ }
+ return has_default_build && has_system_build;
+}
+
fruit::Component<fruit::Required<const FetcherConfig, const CuttlefishConfig,
const CuttlefishConfig::InstanceSpecific>,
SuperImageRebuilder>
@@ -328,4 +340,4 @@ SuperImageRebuilderComponent() {
.addMultibinding<SetupFeature, SuperImageRebuilder>();
}
-} // namespace cuttlefish
+} // namespace cuttlefish
diff --git a/host/libs/config/config_utils.cpp b/host/libs/config/config_utils.cpp
index 9197877dc..c4fea49cc 100644
--- a/host/libs/config/config_utils.cpp
+++ b/host/libs/config/config_utils.cpp
@@ -24,8 +24,10 @@
#include <android-base/logging.h>
#include <android-base/strings.h>
+#include "common/libs/utils/contains.h"
#include "common/libs/utils/environment.h"
#include "host/libs/config/config_constants.h"
+#include "host/libs/config/cuttlefish_config.h"
namespace cuttlefish {
@@ -111,19 +113,17 @@ std::string HostBinaryDir() {
return DefaultHostArtifactsPath("bin");
}
-bool UseQemu8() {
+bool UseQemuPrebuilt() {
const std::string target_prod_str = StringFromEnv("TARGET_PRODUCT", "");
- if (HostArch() == Arch::X86_64 &&
- target_prod_str.find("arm") == std::string::npos) {
+ if (!Contains(target_prod_str, "arm")) {
return true;
}
-
return false;
}
std::string DefaultQemuBinaryDir() {
- if (UseQemu8()) {
- return HostBinaryDir();
+ if (UseQemuPrebuilt()) {
+ return HostBinaryDir() + "/" + HostArchStr() + "-linux-gnu/qemu";
}
return "/usr/bin";
}
@@ -140,6 +140,14 @@ std::string HostUsrSharePath(const std::string& binary_name) {
return DefaultHostArtifactsPath("usr/share/" + binary_name);
}
+std::string HostQemuBiosPath() {
+ if (UseQemuPrebuilt()) {
+ return DefaultHostArtifactsPath(
+ "usr/share/qemu/" + HostArchStr() + "-linux-gnu");
+ }
+ return "/usr/share/qemu";
+}
+
std::string DefaultGuestImagePath(const std::string& file_name) {
return (StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", "."))) +
file_name;
diff --git a/host/libs/config/config_utils.h b/host/libs/config/config_utils.h
index 8107f5e9b..b5058bb18 100644
--- a/host/libs/config/config_utils.h
+++ b/host/libs/config/config_utils.h
@@ -51,6 +51,7 @@ std::string DefaultHostArtifactsPath(const std::string& file);
std::string DefaultQemuBinaryDir();
std::string HostBinaryPath(const std::string& file);
std::string HostUsrSharePath(const std::string& file);
+std::string HostQemuBiosPath();
std::string DefaultGuestImagePath(const std::string& file);
std::string DefaultEnvironmentPath(const char* environment_key,
const char* default_value,
@@ -59,6 +60,6 @@ std::string DefaultEnvironmentPath(const char* environment_key,
// Whether the host supports qemu
bool HostSupportsQemuCli();
-// Whether to use QEMU8
-bool UseQemu8();
+// Whether to use our local QEMU prebuilt
+bool UseQemuPrebuilt();
}
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index fb8f4605c..c26da188e 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -212,12 +212,6 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu(
auto gpu_device_socket_path =
instance.PerInstanceInternalUdsPath("vhost-user-gpu-socket");
- auto gpu_device_socket = SharedFD::SocketLocalServer(
- gpu_device_socket_path.c_str(), false, SOCK_STREAM, 0777);
- CF_EXPECT(gpu_device_socket->IsOpen(),
- "Failed to create socket for crosvm vhost user gpu's control"
- << gpu_device_socket->StrError());
-
auto gpu_device_logs_path =
instance.PerInstanceInternalPath("crosvm_vhost_user_gpu.fifo");
auto gpu_device_logs = CF_EXPECT(SharedFD::Fifo(gpu_device_logs_path, 0666));
@@ -318,6 +312,15 @@ Result<VhostUserDeviceCommands> BuildVhostUserGpu(
// Connect device to main crosvm:
gpu_device_cmd.Cmd().AddParameter("--socket=", gpu_device_socket_path);
+
+ main_crosvm_cmd->AddPrerequisite([gpu_device_socket_path]() -> Result<void> {
+#ifdef __linux__
+ return WaitForUnixSocketListeningWithoutConnect(gpu_device_socket_path,
+ /*timeoutSec=*/30);
+#else
+ return CF_ERR("Unhandled check if vhost user gpu ready.");
+#endif
+ });
main_crosvm_cmd->AddParameter(
"--vhost-user=gpu,pci-address=", gpu_pci_address,
",socket=", gpu_device_socket_path);
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 26ff43628..0f300d41d 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -807,6 +807,9 @@ Result<std::vector<MonitorCommand>> QemuManager::StartCommands(
qemu_cmd.AddParameter("-device");
qemu_cmd.AddParameter("qemu-xhci,id=xhci");
+ qemu_cmd.AddParameter("-L");
+ qemu_cmd.AddParameter(HostQemuBiosPath());
+
if (is_riscv64) {
qemu_cmd.AddParameter("-kernel");
} else {