Don't abort, return nullptr instead, when config file isn't present
Reduce the number of calls to CuttlefishConfig::Get(): We have been
abusing the singleton, which made it hard to keep track of what
happens before and after config is initialized in the launcher.
Bug: 111084325
Test: local & gce
Change-Id: I513eccacb221695fd046551d54bb8b98f7348ea8
diff --git a/host/commands/ivserver/main.cpp b/host/commands/ivserver/main.cpp
index dae1c66..16aa747 100644
--- a/host/commands/ivserver/main.cpp
+++ b/host/commands/ivserver/main.cpp
@@ -39,6 +39,10 @@
google::ParseCommandLineFlags(&argc, &argv, true);
auto config = vsoc::CuttlefishConfig::Get();
+ if (!config) {
+ LOG(ERROR) << "Unable to get cuttlefish config";
+ return 1;
+ }
ivserver::IVServer server(
ivserver::IVServerOptions(config->mempath(),
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index ca3888e..aeed54e 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -92,7 +92,7 @@
DEFINE_string(boot_image, "", "Location of cuttlefish boot image.");
DEFINE_int32(memory_mb, 2048,
"Total amount of memory available for guest, MB.");
-std::string g_default_mempath{GetPerInstanceDefault("/var/run/shm/cvd-")};
+std::string g_default_mempath{vsoc::GetDefaultMempath()};
DEFINE_string(mempath, g_default_mempath.c_str(),
"Target location for the shmem file.");
// The cvd-mobile-{tap|br}-xx interfaces are created by default, but libvirt
@@ -373,8 +373,7 @@
return FLAGS_run_adb_connector && AdbTunnelEnabled();
}
-void LaunchIvServer() {
- auto config = vsoc::CuttlefishConfig::Get();
+void LaunchIvServer(vsoc::CuttlefishConfig* config) {
// Resize gralloc region
auto actual_width = cvd::AlignToPowerOf2(FLAGS_x_res * 4, 4); // align to 16
uint32_t screen_buffers_size =
@@ -468,17 +467,19 @@
return true;
}
-bool UnpackBootImage(const cvd::BootImageUnpacker& boot_image_unpacker) {
- auto config = vsoc::CuttlefishConfig::Get();
+bool UnpackBootImage(const cvd::BootImageUnpacker& boot_image_unpacker,
+ vsoc::CuttlefishConfig* config) {
if (boot_image_unpacker.HasRamdiskImage()) {
- if (!boot_image_unpacker.ExtractRamdiskImage(config->ramdisk_image_path())) {
+ if (!boot_image_unpacker.ExtractRamdiskImage(
+ config->ramdisk_image_path())) {
LOG(ERROR) << "Error extracting ramdisk from boot image";
return false;
}
}
if (!FLAGS_kernel_path.size()) {
if (boot_image_unpacker.HasKernelImage()) {
- if (!boot_image_unpacker.ExtractKernelImage(config->kernel_image_path())) {
+ if (!boot_image_unpacker.ExtractKernelImage(
+ config->kernel_image_path())) {
LOG(ERROR) << "Error extracting kernel from boot image";
return false;
}
@@ -490,10 +491,16 @@
return true;
}
-bool InitializeCuttlefishConfiguration(
+vsoc::CuttlefishConfig* InitializeCuttlefishConfiguration(
const cvd::BootImageUnpacker& boot_image_unpacker) {
auto& memory_layout = *vsoc::VSoCMemoryLayout::Get();
auto config = vsoc::CuttlefishConfig::Get();
+ if (!config) {
+ LOG(ERROR) << "Failed to instantiate config object. Most likely because "
+ "config file was specified and doesn't exits: '"
+ << FLAGS_config_file << "'";
+ return nullptr;
+ }
// Set this first so that calls to PerInstancePath below are correct
config->set_instance_dir(FLAGS_instance_dir);
@@ -592,7 +599,7 @@
config->set_cuttlefish_env_path(cvd::StringFromEnv("HOME", ".") +
"/.cuttlefish.sh");
- return true;
+ return config;
}
bool ParseCommandLineFlags(int argc, char** argv) {
@@ -610,8 +617,7 @@
return ResolveInstanceFiles();
}
-bool WriteCuttlefishEnvironment() {
- auto config = vsoc::CuttlefishConfig::Get();
+bool WriteCuttlefishEnvironment(vsoc::CuttlefishConfig* config) {
auto env = cvd::SharedFD::Open(config->cuttlefish_env_path().c_str(),
O_CREAT | O_RDWR, 0755);
if (!env->IsOpen()) {
@@ -633,7 +639,7 @@
// Forks and returns the write end of a pipe to the child process. The parent
// process waits for boot events to come through the pipe and exits accordingly.
-cvd::SharedFD DaemonizeLauncher() {
+cvd::SharedFD DaemonizeLauncher(vsoc::CuttlefishConfig* config) {
cvd::SharedFD read_end, write_end;
if (!cvd::SharedFD::Pipe(&read_end, &write_end)) {
LOG(ERROR) << "Unable to create pipe";
@@ -669,7 +675,7 @@
std::exit(LauncherExitCodes::kDaemonizationError);
}
// Redirect standard I/O
- auto log_path = vsoc::CuttlefishConfig::Get()->launcher_log_path();
+ auto log_path = config->launcher_log_path();
auto log =
cvd::SharedFD::Open(log_path.c_str(), O_CREAT | O_WRONLY | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
@@ -702,8 +708,8 @@
// Stops the device. If this function is successful it returns on a child of the
// launcher (after it killed the laucher) and it should exit immediately
-bool StopCvd() {
- auto vm_manager = vm_manager::VmManager::Get();
+bool StopCvd(vsoc::CuttlefishConfig* config) {
+ auto vm_manager = vm_manager::VmManager::Get(config);
vm_manager->Stop();
auto pgid = getpgid(0);
auto child_pid = fork();
@@ -731,7 +737,8 @@
}
}
-void ServerLoop(cvd::SharedFD server) {
+void ServerLoop(cvd::SharedFD server,
+ vsoc::CuttlefishConfig* config) {
while (true) {
// TODO: use select to handle simultaneous connections.
auto client = cvd::SharedFD::Accept(*server);
@@ -739,7 +746,7 @@
while (client->IsOpen() && client->Read(&action, sizeof(char)) > 0) {
switch (action) {
case cvd::LauncherAction::kStop:
- if (StopCvd()) {
+ if (StopCvd(config)) {
auto response = cvd::LauncherResponse::kSuccess;
client->Write(&response, sizeof(response));
std::exit(0);
@@ -766,7 +773,12 @@
}
auto boot_img_unpacker = cvd::BootImageUnpacker::FromImage(FLAGS_boot_image);
- auto vm_manager = vm_manager::VmManager::Get();
+ // Do this early so that the config object is ready for anything that needs it
+ auto config = InitializeCuttlefishConfiguration(*boot_img_unpacker);
+ if (!config) {
+ return LauncherExitCodes::kCuttlefishConfigurationInitError;
+ }
+ auto vm_manager = vm_manager::VmManager::Get(config);
// Check host configuration
std::vector<std::string> config_commands;
@@ -781,11 +793,6 @@
return LauncherExitCodes::kInvalidHostConfiguration;
}
- // Do this early so that the config object is ready for anything that needs it
- if (!InitializeCuttlefishConfiguration(*boot_img_unpacker)) {
- return LauncherExitCodes::kCuttlefishConfigurationInitError;
- }
-
if (!vm_manager->EnsureInstanceDirExists()) {
LOG(ERROR) << "Failed to create instance directory: " << FLAGS_instance_dir;
return LauncherExitCodes::kInstanceDirCreationError;
@@ -796,16 +803,15 @@
return LauncherExitCodes::kPrioFilesCleanupError;
}
- if (!UnpackBootImage(*boot_img_unpacker)) {
+ if (!UnpackBootImage(*boot_img_unpacker, config)) {
LOG(ERROR) << "Failed to unpack boot image";
return LauncherExitCodes::kBootImageUnpackError;
}
- if (!WriteCuttlefishEnvironment()) {
+ if (!WriteCuttlefishEnvironment(config)) {
LOG(ERROR) << "Unable to write cuttlefish environment file";
}
- auto config = vsoc::CuttlefishConfig::Get();
auto config_file = GetConfigFile();
auto config_link = vsoc::GetGlobalConfigFileLink();
// Save the config object before starting any host process
@@ -848,7 +854,7 @@
new_action.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &new_action, &old_action);
- auto pipe_fd = DaemonizeLauncher();
+ auto pipe_fd = DaemonizeLauncher(config);
if (!pipe_fd->IsOpen()) {
return LauncherExitCodes::kDaemonizationError;
}
@@ -883,10 +889,10 @@
config->usb_ip_socket_name());
vadb.Start();
- LaunchIvServer();
+ LaunchIvServer(config);
// Initialize the regions that require so before the VM starts.
- PreLaunchInitializers::Initialize();
+ PreLaunchInitializers::Initialize(config);
// Start the guest VM
if (!vm_manager->Start()) {
@@ -899,7 +905,7 @@
LaunchVNCServerIfEnabled();
LaunchAdbConnectorIfEnabled();
- ServerLoop(launcher_monitor_socket); // Should not return
+ ServerLoop(launcher_monitor_socket, config); // Should not return
LOG(ERROR) << "The server loop returned, it should never happen!!";
return cvd::LauncherExitCodes::kServerError;
}
diff --git a/host/commands/launch/pre_launch_initializers.h b/host/commands/launch/pre_launch_initializers.h
index d5f44ed..91e97aa 100644
--- a/host/commands/launch/pre_launch_initializers.h
+++ b/host/commands/launch/pre_launch_initializers.h
@@ -16,19 +16,23 @@
* limitations under the License.
*/
+#include <memory>
+
+#include <host/libs/config/cuttlefish_config.h>
+
// Handles initialization of regions that require it strictly before the virtual
// machine is started.
// To add initializers for more regions declare here, implement in its own
// source file and call from PreLaunchInitializers::Initialize().
-void InitializeScreenRegion();
-void InitializeRilRegion();
-void InitializeWifiRegion();
+void InitializeScreenRegion(vsoc::CuttlefishConfig* config);
+void InitializeRilRegion(vsoc::CuttlefishConfig* config);
+void InitializeWifiRegion(vsoc::CuttlefishConfig* config);
class PreLaunchInitializers {
public:
- static void Initialize() {
- InitializeScreenRegion();
- InitializeRilRegion();
- InitializeWifiRegion();
+ static void Initialize(vsoc::CuttlefishConfig* config) {
+ InitializeScreenRegion(config);
+ InitializeRilRegion(config);
+ InitializeWifiRegion(config);
}
};
diff --git a/host/commands/launch/ril_region_handler.cc b/host/commands/launch/ril_region_handler.cc
index 31f5107..224cecd 100644
--- a/host/commands/launch/ril_region_handler.cc
+++ b/host/commands/launch/ril_region_handler.cc
@@ -121,9 +121,8 @@
};
} // namespace
-void InitializeRilRegion() {
+void InitializeRilRegion(vsoc::CuttlefishConfig* config) {
NetConfig netconfig;
- auto config = vsoc::CuttlefishConfig::Get();
if (!netconfig.ObtainConfig(config->mobile_bridge_name())) {
LOG(ERROR) << "Unable to obtain the network configuration";
return;
diff --git a/host/commands/launch/screen_region_handler.cc b/host/commands/launch/screen_region_handler.cc
index 6e19ca1..a4bc600 100644
--- a/host/commands/launch/screen_region_handler.cc
+++ b/host/commands/launch/screen_region_handler.cc
@@ -20,10 +20,9 @@
#include "host/commands/launch/pre_launch_initializers.h"
#include "host/libs/config/cuttlefish_config.h"
-void InitializeScreenRegion() {
+void InitializeScreenRegion(vsoc::CuttlefishConfig* config) {
auto region =
vsoc::screen::ScreenRegionView::GetInstance(vsoc::GetDomain().c_str());
- auto config = vsoc::CuttlefishConfig::Get();
if (!region) {
LOG(FATAL) << "Screen region was not found";
return;
diff --git a/host/commands/launch/wifi_region_handler.cc b/host/commands/launch/wifi_region_handler.cc
index 9d87c64..6b68a23 100644
--- a/host/commands/launch/wifi_region_handler.cc
+++ b/host/commands/launch/wifi_region_handler.cc
@@ -24,9 +24,8 @@
using vsoc::wifi::WifiExchangeView;
-void InitializeWifiRegion() {
+void InitializeWifiRegion(vsoc::CuttlefishConfig* config) {
auto region = WifiExchangeView::GetInstance(vsoc::GetDomain().c_str());
- auto config = vsoc::CuttlefishConfig::Get();
if (!region) {
LOG(FATAL) << "Wifi region not found";
return;
diff --git a/host/commands/stop_cvd/main.cc b/host/commands/stop_cvd/main.cc
index 01ea156..1776cf0 100644
--- a/host/commands/stop_cvd/main.cc
+++ b/host/commands/stop_cvd/main.cc
@@ -81,8 +81,8 @@
return ret;
}
-int FallBackStop() {
- auto vm_manager = vm_manager::VmManager::Get();
+int FallBackStop(vsoc::CuttlefishConfig* config) {
+ auto vm_manager = vm_manager::VmManager::Get(config);
auto exit_code = 1; // Having to fallback is an error
if (!vm_manager->Stop()) {
LOG(ERROR)
@@ -102,7 +102,17 @@
}
return exit_code;
- }
+}
+
+// Even if the config file can't be found, we still need a valid config object
+// with some defaults to be able to run the fallback stopping procedure
+vsoc::CuttlefishConfig* BuildSensibleConfig() {
+ vsoc::CuttlefishConfig* config(new vsoc::CuttlefishConfig());
+ config->set_instance_dir(vsoc::GetDefaultPerInstanceDir());
+ // This one is pretty safe to assume is there
+ config->set_mempath(vsoc::GetDefaultMempath());
+ return config;
+}
} // anonymous namespace
int main(int argc, char** argv) {
@@ -110,25 +120,29 @@
google::ParseCommandLineFlags(&argc, &argv, true);
auto config = vsoc::CuttlefishConfig::Get();
+ if (!config) {
+ LOG(ERROR) << "Failed to obtain config object";
+ return FallBackStop(BuildSensibleConfig());
+ }
auto monitor_path = config->launcher_monitor_socket_path();
if (monitor_path.empty()) {
LOG(ERROR) << "No path to launcher monitor found";
- return FallBackStop();
+ return FallBackStop(config);
}
auto monitor_socket = cvd::SharedFD::SocketLocalClient(monitor_path.c_str(),
false, SOCK_STREAM);
if (!monitor_socket->IsOpen()) {
LOG(ERROR) << "Unable to connect to launcher monitor at " << monitor_path
<< ": " << monitor_socket->StrError();
- return FallBackStop();
+ return FallBackStop(config);
}
auto request = cvd::LauncherAction::kStop;
auto bytes_sent = monitor_socket->Send(&request, sizeof(request), 0);
if (bytes_sent < 0) {
LOG(ERROR) << "Error sending launcher monitor the stop command: "
<< monitor_socket->StrError();
- return FallBackStop();
+ return FallBackStop(config);
}
// Perform a select with a timeout to guard against launcher hanging
cvd::SharedFDSet read_set;
@@ -139,23 +153,23 @@
if (selected < 0){
LOG(ERROR) << "Failed communication with the launcher monitor: "
<< strerror(errno);
- return FallBackStop();
+ return FallBackStop(config);
}
if (selected == 0) {
LOG(ERROR) << "Timeout expired waiting for launcher monitor to respond";
- return FallBackStop();
+ return FallBackStop(config);
}
cvd::LauncherResponse response;
auto bytes_recv = monitor_socket->Recv(&response, sizeof(response), 0);
if (bytes_recv < 0) {
LOG(ERROR) << "Error receiving response from launcher monitor: "
<< monitor_socket->StrError();
- return FallBackStop();
+ return FallBackStop(config);
}
if (response != cvd::LauncherResponse::kSuccess) {
LOG(ERROR) << "Received '" << static_cast<char>(response)
<< "' response from launcher monitor";
- return FallBackStop();
+ return FallBackStop(config);
}
LOG(INFO) << "Successfully stopped device";
return 0;
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 2f2fffa..ba41aed 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -417,28 +417,44 @@
(*dictionary_)[kAdbMode] = mode;
}
-/*static*/ CuttlefishConfig* CuttlefishConfig::Get() {
- static CuttlefishConfig config;
- return &config;
-}
-
-CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {
- if (!FLAGS_config_file.empty()) {
- LoadFromFile(FLAGS_config_file.c_str());
+// Creates the (initially empty) config object and populates it with values from
+// the config file if the --config_file command line argument is present.
+// Returns nullptr if there was an error loading from file
+/*static*/ CuttlefishConfig* CuttlefishConfig::BuildConfigImpl() {
+ auto ret = new CuttlefishConfig();
+ if (ret && !FLAGS_config_file.empty()) {
+ auto loaded = ret->LoadFromFile(FLAGS_config_file.c_str());
+ if (!loaded) {
+ return nullptr;
+ }
}
+ return ret;
}
-void CuttlefishConfig::LoadFromFile(const char* file) {
+/*static*/ CuttlefishConfig* CuttlefishConfig::Get() {
+ static std::shared_ptr<CuttlefishConfig> config(BuildConfigImpl());
+ return config.get();
+}
+
+CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) {}
+// Can't use '= default' on the header because the compiler complains of
+// Json::Value being an incomplete type
+CuttlefishConfig::~CuttlefishConfig() {}
+
+bool CuttlefishConfig::LoadFromFile(const char* file) {
auto real_file_path = cvd::AbsolutePath(file);
if (real_file_path.empty()) {
- LOG(FATAL) << "Could not get real path for file " << file;
+ LOG(ERROR) << "Could not get real path for file " << file;
+ return false;
}
Json::Reader reader;
std::ifstream ifs(real_file_path);
if (!reader.parse(ifs, *dictionary_)) {
- LOG(FATAL) << "Could not read config file " << file << ": "
+ LOG(ERROR) << "Could not read config file " << file << ": "
<< reader.getFormattedErrorMessages();
+ return false;
}
+ return true;
}
bool CuttlefishConfig::SaveToFile(const std::string& file) const {
std::ofstream ofs(file);
@@ -489,6 +505,10 @@
return stream.str();
}
+std::string GetDefaultMempath() {
+ return GetPerInstanceDefault("/var/run/shm/cvd-");
+}
+
std::string DefaultHostArtifactsPath(const std::string& file_name) {
return (cvd::StringFromEnv("ANDROID_HOST_OUT",
cvd::StringFromEnv("HOME", ".")) +
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 456e2ae..1516ca0 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -30,7 +30,9 @@
class CuttlefishConfig {
public:
static CuttlefishConfig* Get();
- ~CuttlefishConfig() = default;
+
+ CuttlefishConfig();
+ ~CuttlefishConfig();
// Saves the configuration object in a file, it can then be read in other
// processes by passing the --config_file option.
@@ -177,10 +179,10 @@
private:
std::unique_ptr<Json::Value> dictionary_;
- void LoadFromFile(const char* file);
void SetPath(const std::string& key, const std::string& path);
+ bool LoadFromFile(const char* file);
+ static CuttlefishConfig* BuildConfigImpl();
- CuttlefishConfig();
CuttlefishConfig(const CuttlefishConfig&) = delete;
CuttlefishConfig& operator=(const CuttlefishConfig&) = delete;
};
@@ -202,6 +204,7 @@
int GetPerInstanceDefault(int base);
std::string GetDefaultPerInstanceDir();
+std::string GetDefaultMempath();
std::string DefaultHostArtifactsPath(const std::string& file);
std::string DefaultGuestImagePath(const std::string& file);
diff --git a/host/libs/vm_manager/libvirt_manager.cpp b/host/libs/vm_manager/libvirt_manager.cpp
index 57e0cac..95f9ef0 100644
--- a/host/libs/vm_manager/libvirt_manager.cpp
+++ b/host/libs/vm_manager/libvirt_manager.cpp
@@ -269,8 +269,7 @@
return cmd;
}
-std::string BuildXmlConfig() {
- auto config = vsoc::CuttlefishConfig::Get();
+std::string BuildXmlConfig(vsoc::CuttlefishConfig* config) {
std::string instance_name = config->instance_name();
std::unique_ptr<xmlDoc, void (*)(xmlDocPtr)> xml{xmlNewDoc(xc("1.0")),
@@ -342,12 +341,14 @@
return out;
}
} // namespace
+LibvirtManager::LibvirtManager(vsoc::CuttlefishConfig* config)
+ : VmManager(config) {}
bool LibvirtManager::Start() const {
std::string start_command = GetLibvirtCommand();
start_command += " create /dev/fd/0";
- std::string xml = BuildXmlConfig();
+ std::string xml = BuildXmlConfig(config_);
if (FLAGS_log_xml) {
LOG(INFO) << "Using XML:\n" << xml;
}
@@ -371,14 +372,13 @@
}
bool LibvirtManager::Stop() const {
- auto config = vsoc::CuttlefishConfig::Get();
auto stop_command = GetLibvirtCommand();
- stop_command += " destroy " + config->instance_name();
+ stop_command += " destroy " + config_->instance_name();
return std::system(stop_command.c_str()) == 0;
}
bool LibvirtManager::EnsureInstanceDirExists() const {
- auto instance_dir = vsoc::CuttlefishConfig::Get()->instance_dir();
+ auto instance_dir = config_->instance_dir();
if (!cvd::DirectoryExists(instance_dir)) {
LOG(INFO) << "Setting up " << instance_dir;
cvd::execute({"/usr/bin/sudo", "/bin/mkdir", "-m", "0775", instance_dir});
@@ -392,10 +392,9 @@
}
bool LibvirtManager::CleanPriorFiles() const {
- auto config = vsoc::CuttlefishConfig::Get();
- std::string run_files = config->PerInstancePath("*") + " " +
- config->mempath() + " " +
- config->cuttlefish_env_path() + " " +
+ std::string run_files = config_->PerInstancePath("*") + " " +
+ config_->mempath() + " " +
+ config_->cuttlefish_env_path() + " " +
vsoc::GetGlobalConfigFileLink();
LOG(INFO) << "Assuming run files of " << run_files;
std::string fuser_cmd = "fuser " + run_files + " 2> /dev/null";
diff --git a/host/libs/vm_manager/libvirt_manager.h b/host/libs/vm_manager/libvirt_manager.h
index 2ec81af..00dfab4 100644
--- a/host/libs/vm_manager/libvirt_manager.h
+++ b/host/libs/vm_manager/libvirt_manager.h
@@ -21,7 +21,7 @@
class LibvirtManager : public VmManager {
public:
- LibvirtManager() = default;
+ LibvirtManager(vsoc::CuttlefishConfig* config);
virtual ~LibvirtManager() = default;
bool Start() const override;
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index bd7765a..91d9122 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -46,8 +46,8 @@
namespace {
-std::string GetMonitorPath() {
- return vsoc::CuttlefishConfig::Get()->PerInstancePath("qemu_monitor.sock");
+std::string GetMonitorPath(vsoc::CuttlefishConfig* config) {
+ return config->PerInstancePath("qemu_monitor.sock");
}
void LogAndSetEnv(const char* key, const std::string& value) {
@@ -55,8 +55,7 @@
LOG(INFO) << key << "=" << value;
}
-int BuildAndRunQemuCmd() {
- auto config = vsoc::CuttlefishConfig::Get();
+int BuildAndRunQemuCmd(vsoc::CuttlefishConfig* config) {
// Set the config values in the environment
LogAndSetEnv("qemu_binary", FLAGS_qemu_binary);
LogAndSetEnv("instance_name", config->instance_name());
@@ -89,13 +88,16 @@
}
} // namespace
+QemuManager::QemuManager(vsoc::CuttlefishConfig* config)
+ : VmManager(config) {}
bool QemuManager::Start() const {
// Create a thread that will make the launcher abort if the qemu process
// crashes, this avoids having the launcher waiting forever for
// VIRTUAL_DEVICE_BOOT_COMPLETED in this cases.
- std::thread waiting_thread([]() {
- int status = BuildAndRunQemuCmd();
+ auto config = this->config_;
+ std::thread waiting_thread([config]() {
+ int status = BuildAndRunQemuCmd(config);
if (status != 0) {
LOG(FATAL) << "Qemu process exited prematurely";
} else {
@@ -117,7 +119,7 @@
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- std::string monitor_path = GetMonitorPath();
+ std::string monitor_path = GetMonitorPath(config_);
strncpy(addr.sun_path, monitor_path.c_str(), sizeof(addr.sun_path) - 1);
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
@@ -146,7 +148,7 @@
}
bool QemuManager::EnsureInstanceDirExists() const {
- auto instance_dir = vsoc::CuttlefishConfig::Get()->instance_dir();
+ auto instance_dir = config_->instance_dir();
if (!cvd::DirectoryExists(instance_dir.c_str())) {
LOG(INFO) << "Setting up " << instance_dir;
if (mkdir(instance_dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
@@ -158,10 +160,9 @@
}
bool QemuManager::CleanPriorFiles() const {
- auto config = vsoc::CuttlefishConfig::Get();
- std::string run_files = config->PerInstancePath("*") + " " +
- config->mempath() + " " +
- config->cuttlefish_env_path() + " " +
+ std::string run_files = config_->PerInstancePath("*") + " " +
+ config_->mempath() + " " +
+ config_->cuttlefish_env_path() + " " +
vsoc::GetGlobalConfigFileLink();
LOG(INFO) << "Assuming run files of " << run_files;
std::string fuser_cmd = "fuser " + run_files + " 2> /dev/null";
diff --git a/host/libs/vm_manager/qemu_manager.h b/host/libs/vm_manager/qemu_manager.h
index 2c9ac14..0d5045a 100644
--- a/host/libs/vm_manager/qemu_manager.h
+++ b/host/libs/vm_manager/qemu_manager.h
@@ -23,7 +23,7 @@
// package to support the qemu-cli capability.
class QemuManager : public VmManager {
public:
- QemuManager() = default;
+ QemuManager(vsoc::CuttlefishConfig* config);
virtual ~QemuManager() = default;
bool Start() const override;
diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp
index 0fc69c5..deb73c7 100644
--- a/host/libs/vm_manager/vm_manager.cpp
+++ b/host/libs/vm_manager/vm_manager.cpp
@@ -24,11 +24,16 @@
#include "host/libs/vm_manager/qemu_manager.h"
namespace vm_manager {
-std::shared_ptr<VmManager> VmManager::Get() {
+
+VmManager::VmManager(vsoc::CuttlefishConfig* config)
+ : config_(config) {}
+
+std::shared_ptr<VmManager> VmManager::Get(
+ vsoc::CuttlefishConfig* config) {
static std::shared_ptr<VmManager> vm_manager(
vsoc::HostSupportsQemuCli()
- ? std::shared_ptr<VmManager>(new QemuManager())
- : std::shared_ptr<VmManager>(new LibvirtManager()));
+ ? std::shared_ptr<VmManager>(new QemuManager(config))
+ : std::shared_ptr<VmManager>(new LibvirtManager(config)));
return vm_manager;
}
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index 4dffba7..9eb1ffc 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -19,6 +19,8 @@
#include <string>
#include <vector>
+#include <host/libs/config/cuttlefish_config.h>
+
namespace vm_manager {
// Superclass of every guest VM manager. It provides a static getter that
@@ -27,7 +29,8 @@
class VmManager {
public:
// Returns the most suitable vm manager as a singleton.
- static std::shared_ptr<VmManager> Get();
+ static std::shared_ptr<VmManager> Get(
+ vsoc::CuttlefishConfig* config);
virtual ~VmManager() = default;
virtual bool Start() const = 0;
@@ -42,6 +45,8 @@
protected:
static bool UserInGroup(const std::string& group,
std::vector<std::string>* config_commands);
+ vsoc::CuttlefishConfig* config_;
+ VmManager(vsoc::CuttlefishConfig* config);
};
} // namespace vm_manager