summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2018-06-06 07:28:00 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2018-06-06 07:28:00 +0000
commitcd7219e5899e47133cee5388b10969c1dc547fe4 (patch)
tree11425c153feb0687eec876d751641e4b536ee6e6
parent44ce37c41307a8bdbb9583bf2703b2d74d708cff (diff)
parent2b2979e93eb8b5a46e72142c2a90d9b302c27600 (diff)
downloadcuttlefish_common-pie-cts-release.tar.gz
Snap for 4824048 from 2b2979e93eb8b5a46e72142c2a90d9b302c27600 to pi-releaseandroid-wear-9.0.0_r9android-wear-9.0.0_r8android-wear-9.0.0_r7android-wear-9.0.0_r6android-wear-9.0.0_r5android-wear-9.0.0_r4android-wear-9.0.0_r34android-wear-9.0.0_r33android-wear-9.0.0_r32android-wear-9.0.0_r31android-wear-9.0.0_r30android-wear-9.0.0_r3android-wear-9.0.0_r29android-wear-9.0.0_r28android-wear-9.0.0_r27android-wear-9.0.0_r26android-wear-9.0.0_r25android-wear-9.0.0_r24android-wear-9.0.0_r23android-wear-9.0.0_r22android-wear-9.0.0_r21android-wear-9.0.0_r20android-wear-9.0.0_r2android-wear-9.0.0_r19android-wear-9.0.0_r18android-wear-9.0.0_r17android-wear-9.0.0_r16android-wear-9.0.0_r15android-wear-9.0.0_r14android-wear-9.0.0_r13android-wear-9.0.0_r12android-wear-9.0.0_r11android-wear-9.0.0_r10android-wear-9.0.0_r1android-vts-9.0_r9android-vts-9.0_r8android-vts-9.0_r7android-vts-9.0_r6android-vts-9.0_r5android-vts-9.0_r4android-vts-9.0_r19android-vts-9.0_r18android-vts-9.0_r17android-vts-9.0_r16android-vts-9.0_r15android-vts-9.0_r14android-vts-9.0_r13android-vts-9.0_r12android-vts-9.0_r11android-vts-9.0_r10android-security-9.0.0_r76android-security-9.0.0_r75android-security-9.0.0_r74android-security-9.0.0_r73android-security-9.0.0_r72android-security-9.0.0_r71android-security-9.0.0_r70android-security-9.0.0_r69android-security-9.0.0_r68android-security-9.0.0_r67android-security-9.0.0_r66android-security-9.0.0_r65android-security-9.0.0_r64android-security-9.0.0_r63android-security-9.0.0_r62android-cts-9.0_r9android-cts-9.0_r8android-cts-9.0_r7android-cts-9.0_r6android-cts-9.0_r5android-cts-9.0_r4android-cts-9.0_r3android-cts-9.0_r20android-cts-9.0_r2android-cts-9.0_r19android-cts-9.0_r18android-cts-9.0_r17android-cts-9.0_r16android-cts-9.0_r15android-cts-9.0_r14android-cts-9.0_r13android-cts-9.0_r12android-cts-9.0_r11android-cts-9.0_r10android-cts-9.0_r1android-9.0.0_r9android-9.0.0_r8android-9.0.0_r7android-9.0.0_r61android-9.0.0_r60android-9.0.0_r6android-9.0.0_r59android-9.0.0_r58android-9.0.0_r57android-9.0.0_r56android-9.0.0_r55android-9.0.0_r54android-9.0.0_r53android-9.0.0_r52android-9.0.0_r51android-9.0.0_r50android-9.0.0_r5android-9.0.0_r49android-9.0.0_r48android-9.0.0_r3android-9.0.0_r2android-9.0.0_r18android-9.0.0_r17android-9.0.0_r10android-9.0.0_r1security-pi-releasepie-vts-releasepie-security-releasepie-s2-releasepie-release-2pie-releasepie-r2-s2-releasepie-r2-s1-releasepie-r2-releasepie-cts-release
Change-Id: I4e0f32ceec3bcf60846413ab9ab3c336db6f4562
-rw-r--r--Android.bp2
-rw-r--r--common/commands/wifi_relay/Android.bp1
-rw-r--r--common/commands/wifi_relay/wifi_relay.cpp2
-rw-r--r--common/frontend/socket_forward_proxy/Android.bp1
-rw-r--r--common/frontend/socket_forward_proxy/main.cpp2
-rw-r--r--common/vsoc/lib/screen_region_view_test.cpp2
-rw-r--r--host/commands/launch/Android.bp1
-rw-r--r--host/commands/launch/main.cc491
-rw-r--r--host/commands/launch/ril_region_handler.cc160
-rw-r--r--host/commands/launch/screen_region_handler.cc20
-rw-r--r--host/commands/launch/wifi_region_handler.cc42
-rw-r--r--host/commands/record_audio/Android.bp1
-rw-r--r--host/commands/record_audio/main.cc2
-rw-r--r--host/commands/stop_cvd/Android.bp6
-rw-r--r--host/commands/stop_cvd/main.cc44
-rw-r--r--host/frontend/vnc_server/Android.bp1
-rw-r--r--host/frontend/vnc_server/main.cpp2
-rw-r--r--host/frontend/vnc_server/simulated_hw_composer.cpp2
-rw-r--r--host/frontend/vnc_server/vnc_utils.h2
-rw-r--r--host/libs/Android.bp1
-rw-r--r--host/libs/config/Android.bp5
-rw-r--r--host/libs/config/cuttlefish_config.cpp433
-rw-r--r--host/libs/config/cuttlefish_config.h182
-rw-r--r--host/libs/config/file_partition.cpp90
-rw-r--r--host/libs/config/file_partition.h58
-rw-r--r--host/libs/config/guest_config.h184
-rw-r--r--host/libs/config/host_config.cpp78
-rw-r--r--host/libs/vm_manager/Android.bp37
-rw-r--r--host/libs/vm_manager/libvirt_manager.cpp (renamed from host/libs/config/guest_config.cpp)141
-rw-r--r--host/libs/vm_manager/libvirt_manager.h (renamed from host/libs/config/host_config.h)31
-rw-r--r--host/vsoc/lib/host_region_e2e_test.cpp2
31 files changed, 1164 insertions, 862 deletions
diff --git a/Android.bp b/Android.bp
index 7945e358..0dc83d0c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -155,6 +155,7 @@ cc_binary_host {
],
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
"libgflags",
],
shared_libs: [
@@ -206,6 +207,7 @@ cc_binary_host {
],
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
"libgtest_host",
"libgflags",
],
diff --git a/common/commands/wifi_relay/Android.bp b/common/commands/wifi_relay/Android.bp
index c496ef09..5393d4af 100644
--- a/common/commands/wifi_relay/Android.bp
+++ b/common/commands/wifi_relay/Android.bp
@@ -39,6 +39,7 @@ cc_binary {
host: {
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
],
},
},
diff --git a/common/commands/wifi_relay/wifi_relay.cpp b/common/commands/wifi_relay/wifi_relay.cpp
index 2b217650..4d862b0d 100644
--- a/common/commands/wifi_relay/wifi_relay.cpp
+++ b/common/commands/wifi_relay/wifi_relay.cpp
@@ -20,7 +20,7 @@
#include "common/commands/wifi_relay/nl_client.h"
#if defined(CUTTLEFISH_HOST)
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#endif
#include <linux/netdevice.h>
diff --git a/common/frontend/socket_forward_proxy/Android.bp b/common/frontend/socket_forward_proxy/Android.bp
index 4def7bfd..3eba53ff 100644
--- a/common/frontend/socket_forward_proxy/Android.bp
+++ b/common/frontend/socket_forward_proxy/Android.bp
@@ -36,6 +36,7 @@ cc_binary {
host: {
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
"libadb_connection_maintainer",
],
},
diff --git a/common/frontend/socket_forward_proxy/main.cpp b/common/frontend/socket_forward_proxy/main.cpp
index a04c6012..e361059c 100644
--- a/common/frontend/socket_forward_proxy/main.cpp
+++ b/common/frontend/socket_forward_proxy/main.cpp
@@ -33,7 +33,7 @@
#include "common/vsoc/lib/socket_forward_region_view.h"
#ifdef CUTTLEFISH_HOST
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h"
#endif
diff --git a/common/vsoc/lib/screen_region_view_test.cpp b/common/vsoc/lib/screen_region_view_test.cpp
index b192c67e..cc02baac 100644
--- a/common/vsoc/lib/screen_region_view_test.cpp
+++ b/common/vsoc/lib/screen_region_view_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "screen_region_view.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#include <stdio.h>
using vsoc::screen::ScreenRegionView;
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index e9789b86..650ccb9a 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -35,6 +35,7 @@ cc_binary_host {
],
static_libs: [
"libcuttlefish_host_config",
+ "libcuttlefish_vm_manager",
"libivserver",
"libvadb",
"libusbip",
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index c3b21517..9605049b 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -38,14 +38,13 @@
#include "common/vsoc/lib/vsoc_memory.h"
#include "common/vsoc/shm/screen_layout.h"
#include "host/commands/launch/pre_launch_initializers.h"
-#include "host/libs/config/file_partition.h"
-#include "host/libs/config/guest_config.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#include "host/libs/ivserver/ivserver.h"
#include "host/libs/ivserver/options.h"
#include "host/libs/monitor/kernel_log_server.h"
#include "host/libs/usbip/server.h"
#include "host/libs/vadb/virtual_adb_server.h"
+#include "host/libs/vm_manager/libvirt_manager.h"
namespace {
std::string StringFromEnv(const char* varname, std::string defval) {
@@ -55,13 +54,20 @@ std::string StringFromEnv(const char* varname, std::string defval) {
}
return valstr;
}
-} // namespace
-#define VIRSH_OPTIONS_PLACEHOLDER "<virsh_options>"
+std::string DefaultHostArtifactsPath(const char* file_name) {
+ return (StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) + "/") +
+ file_name;
+}
+
+} // namespace
using vsoc::GetPerInstanceDefault;
-using vsoc::GetDefaultPerInstancePath;
+DEFINE_string(
+ system_image, "",
+ "Path to the system image, if empty it is assumed to be a file named "
+ "system.img in the directory specified by -system_image_dir");
DEFINE_string(cache_image, "", "Location of the cache partition image.");
DEFINE_int32(cpus, 2, "Virtual CPU count.");
DEFINE_string(data_image, "", "Location of the data partition image.");
@@ -72,10 +78,11 @@ DEFINE_int32(blank_data_image_mb, 0,
DEFINE_string(blank_data_image_fmt, "ext4",
"The fs format for the blank data image. Used with mkfs.");
-DECLARE_int32(dpi);
-DECLARE_int32(x_res);
-DECLARE_int32(y_res);
-DECLARE_int32(num_screen_buffers);
+DEFINE_int32(x_res, 720, "Width of the screen in pixels");
+DEFINE_int32(y_res, 1280, "Height of the screen in pixels");
+DEFINE_int32(dpi, 160, "Pixels per inch for the screen");
+DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz");
+DEFINE_int32(num_screen_buffers, 3, "The number of screen buffers");
DEFINE_bool(disable_app_armor_security, false,
"Disable AppArmor security in libvirt. For debug only.");
@@ -83,17 +90,10 @@ DEFINE_bool(disable_dac_security, false,
"Disable DAC security in libvirt. For debug only.");
DEFINE_string(extra_kernel_command_line, "",
"Additional flags to put on the kernel command line");
-DECLARE_int32(instance);
DEFINE_string(initrd, "", "Location of cuttlefish initrd file.");
DEFINE_string(kernel, "", "Location of cuttlefish kernel file.");
DEFINE_string(kernel_command_line, "",
"Location of a text file with the kernel command line.");
-DEFINE_string(hypervisor_uri, "qemu:///system", "Hypervisor cannonical uri.");
-DEFINE_string(launch_command,
- "virsh " VIRSH_OPTIONS_PLACEHOLDER " create /dev/fd/0",
- "Command to start an instance. If <virsh_options> is present it "
- "will be replaced by options to the virsh command");
-DEFINE_bool(log_xml, false, "Log the XML machine configuration");
DEFINE_int32(memory_mb, 2048,
"Total amount of memory available for guest, MB.");
std::string g_default_mempath{GetPerInstanceDefault("/var/run/shm/cvd-")};
@@ -102,11 +102,13 @@ DEFINE_string(mempath, g_default_mempath.c_str(),
std::string g_default_mobile_interface{GetPerInstanceDefault("cvd-mobile-")};
DEFINE_string(mobile_interface, g_default_mobile_interface.c_str(),
"Network interface to use for mobile networking");
-std::string g_default_qemusocket = GetDefaultPerInstancePath("ivshmem_socket_qemu");
-DEFINE_string(qemusocket, g_default_qemusocket.c_str(), "QEmu socket path");
+DEFINE_string(mobile_tap_name, GetPerInstanceDefault("amobile"),
+ "The name of the tap interface to use for mobile");
std::string g_default_serial_number{GetPerInstanceDefault("CUTTLEFISHCVD")};
DEFINE_string(serial_number, g_default_serial_number.c_str(),
"Serial number to use for the device");
+DEFINE_string(instance_dir, vsoc::GetDefaultPerInstanceDir(),
+ "A directory to put all instance specific files");
DEFINE_string(system_image_dir,
StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", ".")),
"Location of the system partition images.");
@@ -117,27 +119,40 @@ DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
" Will be deprecated soon.");
DEFINE_bool(start_vnc_server, true, "Whether to start the vnc server process.");
DEFINE_string(vnc_server_binary,
- StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
- "/bin/vnc_server",
+ DefaultHostArtifactsPath("/bin/vnc_server"),
"Location of the vnc server binary.");
DEFINE_int32(vnc_server_port, GetPerInstanceDefault(6444),
"The port on which the vnc server should listen");
DEFINE_string(socket_forward_proxy_binary,
- StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
- "/bin/socket_forward_proxy",
+ DefaultHostArtifactsPath("/bin/socket_forward_proxy"),
"Location of the socket_forward_proxy binary.");
DEFINE_string(adb_mode, "tunnel",
"Mode for adb connection. Can be usb for usb forwarding, or "
"tunnel for tcp connection. If using tunnel, you may have to "
"run 'adb kill-server' to get the device to show up.");
DEFINE_int32(vhci_port, GetPerInstanceDefault(0), "VHCI port to use for usb");
+DEFINE_string(guest_mac_address,
+ GetPerInstanceDefault("00:43:56:44:80:"), // 00:43:56:44:80:0x
+ "MAC address of the wifi interface to be created on the guest.");
+DEFINE_string(host_mac_address,
+ "42:00:00:00:00:00",
+ "MAC address of the wifi interface running on the host.");
DEFINE_bool(start_wifi_relay, true, "Whether to start the wifi_relay process.");
DEFINE_string(wifi_relay_binary,
- StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
- "/bin/wifi_relay",
+ DefaultHostArtifactsPath("/bin/wifi_relay"),
"Location of the wifi_relay binary.");
+std::string g_default_wifi_interface{GetPerInstanceDefault("cvd-wifi-")};
+DEFINE_string(wifi_interface, g_default_wifi_interface.c_str(),
+ "Network interface to use for wifi");
+// TODO(b/72969289) This should be generated
+DEFINE_string(dtb, DefaultHostArtifactsPath("config/cuttlefish.dtb"),
+ "Path to the cuttlefish.dtb file");
-DECLARE_string(uuid);
+constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
+DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
+ "UUID to use for the device. Random if not specified");
+
+DECLARE_string(config_file);
namespace {
const std::string kDataPolicyUseExisting = "use_existing";
@@ -147,10 +162,6 @@ const std::string kDataPolicyAlwaysCreate = "always_create";
constexpr char kAdbModeTunnel[] = "tunnel";
constexpr char kAdbModeUsb[] = "usb";
-std::string GetVirshOptions() {
- return std::string("-c ").append(FLAGS_hypervisor_uri);
-}
-
// VirtualUSBManager manages virtual USB device presence for Cuttlefish.
class VirtualUSBManager {
public:
@@ -196,9 +207,8 @@ class VirtualUSBManager {
// Cuttlefish and host-side daemons.
class IVServerManager {
public:
- IVServerManager()
- : server_(ivserver::IVServerOptions(FLAGS_mempath,
- FLAGS_qemusocket,
+ IVServerManager(const std::string& mempath, const std::string& qemu_socket)
+ : server_(ivserver::IVServerOptions(mempath, qemu_socket,
vsoc::GetDomain())) {}
~IVServerManager() = default;
@@ -256,8 +266,16 @@ void subprocess(const char* const* command,
bool wait_for_child = true) {
pid_t pid = fork();
if (!pid) {
- int rval = execve(command[0], const_cast<char* const*>(command),
- const_cast<char* const*>(envp));
+ int rval;
+ // If envp is NULL, the current process's environment is used as the
+ // environment of the child process. To force an empty emvironment for the
+ // child process pass the address of a pointer to NULL
+ if (envp == NULL) {
+ rval = execv(command[0], const_cast<char* const*>(command));
+ } else {
+ rval = execve(command[0], const_cast<char* const*>(command),
+ const_cast<char* const*>(envp));
+ }
// No need for an if: if exec worked it wouldn't have returned
LOG(ERROR) << "exec of " << command[0] << " failed (" << strerror(errno)
<< ")";
@@ -276,6 +294,11 @@ void subprocess(const char* const* command,
}
}
+bool FileExists(const char* path) {
+ struct stat unused;
+ return stat(path, &unused) != -1 || errno != ENOENT;
+}
+
void CreateBlankImage(
const std::string& image, int image_mb, const std::string& image_fmt) {
LOG(INFO) << "Creating " << image;
@@ -299,6 +322,84 @@ void RemoveFile(const std::string& file) {
subprocess(rm_command, NULL);
}
+bool ApplyDataImagePolicy(const char* data_image) {
+ bool data_exists = FileExists(data_image);
+ bool remove{};
+ bool create{};
+
+ if (FLAGS_data_policy == kDataPolicyUseExisting) {
+ if (!data_exists) {
+ LOG(FATAL) << "Specified data image file does not exists: " << data_image;
+ return false;
+ }
+ if (FLAGS_blank_data_image_mb > 0) {
+ LOG(FATAL) << "You should NOT use -blank_data_image_mb with -data_policy="
+ << kDataPolicyUseExisting;
+ return false;
+ }
+ create = false;
+ remove = false;
+ } else if (FLAGS_data_policy == kDataPolicyAlwaysCreate) {
+ remove = data_exists;
+ create = true;
+ } else if (FLAGS_data_policy == kDataPolicyCreateIfMissing) {
+ create = !data_exists;
+ remove = false;
+ } else {
+ LOG(FATAL) << "Invalid data_policy: " << FLAGS_data_policy;
+ }
+
+ if (remove) {
+ RemoveFile(data_image);
+ }
+
+ if (create) {
+ if (FLAGS_blank_data_image_mb <= 0) {
+ LOG(FATAL) << "-blank_data_image_mb is required to create data image";
+ }
+ CreateBlankImage(
+ data_image, FLAGS_blank_data_image_mb, FLAGS_blank_data_image_fmt);
+ } else {
+ LOG(INFO) << data_image << " exists. Not creating it.";
+ }
+
+ return true;
+}
+
+bool EnsureDirExists(const char* dir) {
+ if (!FileExists(dir)) {
+ LOG(INFO) << "Setting up " << dir;
+ if (mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) {
+ if (errno == EACCES) {
+ // TODO(79170615) Don't use sudo once libvirt is replaced
+ LOG(WARNING) << "Not enough permission to create " << dir
+ << " retrying with sudo";
+ const char* mkdir_command[]{"/usr/bin/sudo", "/bin/mkdir", "-m",
+ "0775", dir, NULL};
+ subprocess(mkdir_command, NULL);
+
+ // When created with sudo the owner and group is root.
+ std::string user_group = getenv("USER");
+ user_group += ":libvirt-qemu";
+ const char* chown_cmd[] = {"/usr/bin/sudo", "/bin/chown",
+ user_group.c_str(), dir, NULL};
+ subprocess(chown_cmd, NULL);
+ } else {
+ LOG(FATAL) << "Unable to create " << dir << ". Error: " << errno;
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+std::string GetConfigFile() {
+ return vsoc::CuttlefishConfig::Get()->PerInstancePath(
+ "cuttlefish_config.json");
+}
+
+std::string GetConfigFileArg() { return "-config_file=" + GetConfigFile(); }
+
std::string GetGuestPortArg() {
constexpr int kEmulatorPort = 5555;
return std::string{"--guest_ports="} + std::to_string(kEmulatorPort);
@@ -310,14 +411,6 @@ std::string GetHostPortArg() {
std::to_string(vsoc::GetPerInstanceDefault(kFirstHostPort));
}
-std::string GetDomainArg() {
- return std::string{"--domain="} + vsoc::GetDomain();
-}
-
-std::string GetInstanceArg() {
- return std::string{"--instance="} + std::to_string(FLAGS_instance);
-}
-
void ValidateAdbModeFlag() {
CHECK(FLAGS_adb_mode == kAdbModeUsb ||
FLAGS_adb_mode == kAdbModeTunnel) << "invalid --adb_mode";
@@ -335,15 +428,13 @@ void LaunchSocketForwardProxyIfEnabled() {
if (AdbTunnelEnabled()) {
auto guest_port_arg = GetGuestPortArg();
auto host_port_arg = GetHostPortArg();
- auto domain_arg = GetDomainArg();
- auto instance_arg = GetInstanceArg();
+ auto config_arg = GetConfigFileArg();
const char* const socket_proxy[] = {
FLAGS_socket_forward_proxy_binary.c_str(),
guest_port_arg.c_str(),
host_port_arg.c_str(),
- domain_arg.c_str(),
- instance_arg.c_str(),
+ config_arg.c_str(),
NULL
};
subprocess(socket_proxy, nullptr, false);
@@ -354,13 +445,11 @@ void LaunchVNCServerIfEnabled() {
if (FLAGS_start_vnc_server) {
// Launch the vnc server, don't wait for it to complete
auto port_options = "-port=" + std::to_string(FLAGS_vnc_server_port);
- auto domain_arg = GetDomainArg();
- auto instance_arg = GetInstanceArg();
+ auto config_arg = GetConfigFileArg();
const char* vnc_command[] = {
FLAGS_vnc_server_binary.c_str(),
port_options.c_str(),
- domain_arg.c_str(),
- instance_arg.c_str(),
+ config_arg.c_str(),
NULL
};
subprocess(vnc_command, NULL, false);
@@ -370,45 +459,22 @@ void LaunchVNCServerIfEnabled() {
void LaunchWifiRelayIfEnabled() {
if (FLAGS_start_wifi_relay) {
// Launch the wifi relay, don't wait for it to complete
- auto domain_arg = GetDomainArg();
- auto instance_arg = GetInstanceArg();
-
+ auto config_arg = GetConfigFileArg();
const char* relay_command[] = {
"/usr/bin/sudo",
+ "-E",
FLAGS_wifi_relay_binary.c_str(),
- domain_arg.c_str(),
- instance_arg.c_str(),
+ config_arg.c_str(),
NULL
};
subprocess(relay_command, NULL /* envp */, false /* wait_for_child */);
}
}
-
-} // anonymous namespace
-
-int main(int argc, char** argv) {
- ::android::base::InitLogging(argv, android::base::StderrLogger);
- google::ParseCommandLineFlags(&argc, &argv, true);
- ValidateAdbModeFlag();
-
- LOG_IF(FATAL, FLAGS_system_image_dir.empty())
- << "--system_image_dir must be specified.";
-
- std::string per_instance_dir = vsoc::GetDefaultPerInstanceDir();
- struct stat unused;
- if ((stat(per_instance_dir.c_str(), &unused) == -1) && (errno == ENOENT)) {
- LOG(INFO) << "Setting up " << per_instance_dir;
- const char* mkdir_command[]{
- "/usr/bin/sudo", "/bin/mkdir", "-m", "0775",
- per_instance_dir.c_str(), NULL};
- subprocess(mkdir_command, NULL);
- std::string owner_group{getenv("USER")};
- owner_group += ":libvirt-qemu";
- const char* chown_command[]{"/usr/bin/sudo", "/bin/chown",
- owner_group.c_str(), per_instance_dir.c_str(),
- NULL};
- subprocess(chown_command, NULL);
+bool ResolveInstanceFiles() {
+ if (FLAGS_system_image_dir.empty()) {
+ LOG(FATAL) << "--system_image_dir must be specified.";
+ return false;
}
// If user did not specify location of either of these files, expect them to
@@ -416,165 +482,186 @@ int main(int argc, char** argv) {
if (FLAGS_kernel.empty()) {
FLAGS_kernel = FLAGS_system_image_dir + "/kernel";
}
-
if (FLAGS_kernel_command_line.empty()) {
FLAGS_kernel_command_line = FLAGS_system_image_dir + "/cmdline";
}
-
+ if (FLAGS_system_image.empty()) {
+ FLAGS_system_image = FLAGS_system_image_dir + "/system.img";
+ }
if (FLAGS_initrd.empty()) {
FLAGS_initrd = FLAGS_system_image_dir + "/ramdisk.img";
}
-
if (FLAGS_cache_image.empty()) {
FLAGS_cache_image = FLAGS_system_image_dir + "/cache.img";
}
-
- if (FLAGS_data_policy == kDataPolicyCreateIfMissing) {
- FLAGS_data_image = FLAGS_system_image_dir + "/userdata_blank.img";
- if (FLAGS_blank_data_image_mb <= 0) {
- LOG(FATAL) << "You should use -blank_data_image_mb with -data_policy="
- << kDataPolicyCreateIfMissing;
- }
- // Create a blank data image if the image doesn't exist yet
- if ((stat(FLAGS_data_image.c_str(), &unused) == -1) && (errno == ENOENT)) {
- CreateBlankImage(
- FLAGS_data_image, FLAGS_blank_data_image_mb, FLAGS_blank_data_image_fmt);
- } else {
- LOG(INFO) << FLAGS_data_image << " exists. Not creating it.";
- }
- } else if (FLAGS_data_policy == kDataPolicyAlwaysCreate) {
- FLAGS_data_image = FLAGS_system_image_dir + "/userdata_blank.img";
- if (FLAGS_blank_data_image_mb <= 0) {
- LOG(FATAL) << "You should use -blank_data_image_mb with -data_policy="
- << kDataPolicyAlwaysCreate;
- }
- RemoveFile(FLAGS_data_image);
- CreateBlankImage(
- FLAGS_data_image, FLAGS_blank_data_image_mb, FLAGS_blank_data_image_fmt);
- } else if (FLAGS_data_policy == kDataPolicyUseExisting) {
- // Do nothing. Use FLAGS_data_image.
- if (FLAGS_blank_data_image_mb > 0) {
- LOG(FATAL) << "You should NOT use -blank_data_image_mb with -data_policy="
- << kDataPolicyUseExisting;
- }
- } else {
- LOG(FATAL) << "Invalid data_policy: " << FLAGS_data_policy;
- }
-
if (FLAGS_data_image.empty()) {
FLAGS_data_image = FLAGS_system_image_dir + "/userdata.img";
}
-
if (FLAGS_vendor_image.empty()) {
FLAGS_vendor_image = FLAGS_system_image_dir + "/vendor.img";
}
- // Each of these calls is free to fail and terminate launch if file does not
- // exist or could not be created.
- auto system_partition = config::FilePartition::ReuseExistingFile(
- FLAGS_system_image_dir + "/system.img");
- auto data_partition =
- config::FilePartition::ReuseExistingFile(FLAGS_data_image);
- auto cache_partition =
- config::FilePartition::ReuseExistingFile(FLAGS_cache_image);
- auto vendor_partition =
- config::FilePartition::ReuseExistingFile(FLAGS_vendor_image);
-
- std::ostringstream cmdline;
- std::ifstream t(FLAGS_kernel_command_line);
- if (!t) {
- LOG(FATAL) << "Unable to open " << FLAGS_kernel_command_line;
- }
- cmdline << t.rdbuf();
- t.close();
- cmdline << " androidboot.serialno=" << FLAGS_serial_number;
- cmdline << " androidboot.lcd_density=" << FLAGS_dpi;
- if (FLAGS_extra_kernel_command_line.size()) {
- cmdline << " " << FLAGS_extra_kernel_command_line;
+ // Create data if necessary
+ if (!ApplyDataImagePolicy(FLAGS_data_image.c_str())) {
+ return false;
+ }
+
+ // Check that the files exist
+ for (const auto& file :
+ {FLAGS_system_image, FLAGS_vendor_image, FLAGS_cache_image, FLAGS_kernel,
+ FLAGS_initrd, FLAGS_data_image, FLAGS_kernel_command_line}) {
+ if (!FileExists(file.c_str())) {
+ LOG(FATAL) << "File not found: " << file;
+ return false;
+ }
}
+ return true;
+}
- std::string entropy_source = "/dev/urandom";
+bool SetUpGlobalConfiguration() {
+ if (!ResolveInstanceFiles()) {
+ return false;
+ }
auto& memory_layout = *vsoc::VSoCMemoryLayout::Get();
+ auto config = vsoc::CuttlefishConfig::Get();
+ // Set this first so that calls to PerInstancePath below are correct
+ config->set_instance_dir(FLAGS_instance_dir);
+ if (!EnsureDirExists(FLAGS_instance_dir.c_str())) {
+ return false;
+ }
- config::GuestConfig cfg;
- cfg.SetID(FLAGS_instance)
- .SetVCPUs(FLAGS_cpus)
- .SetMemoryMB(FLAGS_memory_mb)
- .SetKernelName(FLAGS_kernel)
- .SetInitRDName(FLAGS_initrd)
- .SetKernelArgs(cmdline.str())
- .SetIVShMemSocketPath(FLAGS_qemusocket)
- .SetIVShMemVectorCount(memory_layout.GetRegions().size())
- .SetSystemPartitionPath(system_partition->GetName())
- .SetCachePartitionPath(cache_partition->GetName())
- .SetDataPartitionPath(data_partition->GetName())
- .SetVendorPartitionPath(vendor_partition->GetName())
- .SetMobileBridgeName(FLAGS_mobile_interface)
- .SetEntropySource(entropy_source)
- .SetDisableDACSecurity(FLAGS_disable_dac_security)
- .SetDisableAppArmorSecurity(FLAGS_disable_app_armor_security)
- .SetUUID(FLAGS_uuid);
- if(AdbUsbEnabled()) {
- cfg.SetUSBV1SocketName(
- GetDefaultPerInstancePath(cfg.GetInstanceName() + "-usb"));
- }
- cfg.SetKernelLogSocketName(
- GetDefaultPerInstancePath(cfg.GetInstanceName() + "-kernel-log"));
-
- std::string xml = cfg.Build();
- if (FLAGS_log_xml) {
- LOG(INFO) << "Using XML:\n" << xml;
- }
-
- VirtualUSBManager vadb(cfg.GetUSBV1SocketName(), FLAGS_vhci_port,
- GetPerInstanceDefault("android_usbip"));
- vadb.Start();
+ config->set_serial_number(FLAGS_serial_number);
+
+ config->set_cpus(FLAGS_cpus);
+ config->set_memory_mb(FLAGS_memory_mb);
+
+ config->set_dpi(FLAGS_dpi);
+ config->set_x_res(FLAGS_x_res);
+ config->set_y_res(FLAGS_y_res);
+ config->set_refresh_rate_hz(FLAGS_refresh_rate_hz);
+
+ config->set_kernel_image_path(FLAGS_kernel);
+ std::ostringstream extra_cmdline;
+ extra_cmdline << " androidboot.serialno=" << FLAGS_serial_number;
+ extra_cmdline << " androidboot.lcd_density=" << FLAGS_dpi;
+ if (FLAGS_extra_kernel_command_line.size()) {
+ extra_cmdline << " " << FLAGS_extra_kernel_command_line;
+ }
+ config->ReadKernelArgs(FLAGS_kernel_command_line.c_str(),
+ extra_cmdline.str());
+
+ config->set_ramdisk_image_path(FLAGS_initrd);
+ config->set_system_image_path(FLAGS_system_image);
+ config->set_cache_image_path(FLAGS_cache_image);
+ config->set_data_image_path(FLAGS_data_image);
+ config->set_vendor_image_path(FLAGS_vendor_image);
+ config->set_dtb_path(FLAGS_dtb);
+
+ config->set_mempath(FLAGS_mempath);
+ config->set_ivshmem_qemu_socket_path(
+ config->PerInstancePath("ivshmem_socket_qemu"));
+ config->set_ivshmem_client_socket_path(
+ config->PerInstancePath("ivshmem_socket_client"));
+ config->set_ivshmem_vector_count(memory_layout.GetRegions().size());
+
+ config->set_usb_v1_socket_name(config->PerInstancePath("usb-v1"));
+ config->set_vhci_port(FLAGS_vhci_port);
+ config->set_usb_ip_socket_name(config->PerInstancePath("usb-ip"));
+
+ config->set_kernel_log_socket_name(config->PerInstancePath("kernel-log"));
+ config->set_console_path(config->PerInstancePath("console"));
+ config->set_logcat_path(config->PerInstancePath("logcat"));
+
+ config->set_mobile_bridge_name(FLAGS_mobile_interface);
+ config->set_mobile_tap_name(FLAGS_mobile_tap_name);
+ config->set_wifi_guest_mac_addr(FLAGS_guest_mac_address);
+ config->set_wifi_host_mac_addr(FLAGS_host_mac_address);
+
+ config->set_entropy_source("/dev/urandom");
+ config->set_uuid(FLAGS_uuid);
+
+ config->set_disable_dac_security(FLAGS_disable_dac_security);
+ config->set_disable_app_armor_security(FLAGS_disable_app_armor_security);
+
+ if(!AdbUsbEnabled()) {
+ config->disable_usb_adb();
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+namespace launch_cvd {
+void ParseCommandLineFlags(int argc, char** argv) {
+ // The config_file is created by the launcher, so the launcher is the only
+ // host process that doesn't use the flag.
+ // Set the default to empty.
+ google::SetCommandLineOptionWithMode("config_file", "",
+ gflags::SET_FLAGS_DEFAULT);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+ // Set the flag value to empty (in case the caller passed a value for it).
+ FLAGS_config_file = "";
+
+ ValidateAdbModeFlag();
+}
+} // namespace launch_cvd
+
+int main(int argc, char** argv) {
+ ::android::base::InitLogging(argv, android::base::StderrLogger);
+ launch_cvd::ParseCommandLineFlags(argc, argv);
+
+ // Do this early so that the config object is ready for anything that needs it
+ if (!SetUpGlobalConfiguration()) {
+ return -1;
+ }
+
+ auto& memory_layout = *vsoc::VSoCMemoryLayout::Get();
// TODO(b/79170615) These values need to go to the config object/file and the
// region resizing be done by the ivserver process (or maybe the config
// library to ensure all processes have the correct value?)
- size_t screen_size =
+ size_t screen_region_size =
memory_layout
.GetRegionByName(vsoc::layout::screen::ScreenLayout::region_name)
->region_size();
auto actual_width = ((FLAGS_x_res * 4) + 15) & ~15; // aligned to 16
- screen_size += FLAGS_num_screen_buffers *
+ screen_region_size += FLAGS_num_screen_buffers *
(actual_width * FLAGS_y_res + 16 /* padding */);
- screen_size += (FLAGS_num_screen_buffers - 1) * 4096; /* Guard pages */
+ screen_region_size += (FLAGS_num_screen_buffers - 1) * 4096; /* Guard pages */
memory_layout.ResizeRegion(vsoc::layout::screen::ScreenLayout::region_name,
- screen_size);
+ screen_region_size);
// TODO(b/79170615) Resize gralloc region too.
- IVServerManager ivshmem;
+
+ auto config = vsoc::CuttlefishConfig::Get();
+ // Save the config object before starting any host process
+ if (!config->SaveToFile(GetConfigFile())) {
+ return -1;
+ }
+
+ // Start the usb manager
+ VirtualUSBManager vadb(config->usb_v1_socket_name(), config->vhci_port(),
+ config->usb_ip_socket_name());
+ vadb.Start();
+
+ // Start IVServer
+ IVServerManager ivshmem(config->mempath(), config->ivshmem_qemu_socket_path());
ivshmem.Start();
- KernelLogMonitor kmon(cfg.GetKernelLogSocketName(),
- GetDefaultPerInstancePath("kernel.log"),
+
+ KernelLogMonitor kmon(config->kernel_log_socket_name(),
+ config->PerInstancePath("kernel.log"),
FLAGS_deprecated_boot_completed);
kmon.Start();
- sleep(1);
-
- // Initialize the regions that require it before the VM starts.
+ // Initialize the regions that require so before the VM starts.
PreLaunchInitializers::Initialize();
- std::string launch_command = FLAGS_launch_command;
- auto pos = launch_command.find(VIRSH_OPTIONS_PLACEHOLDER);
- if (pos != std::string::npos) {
- launch_command.replace(
- pos, sizeof(VIRSH_OPTIONS_PLACEHOLDER) - 1, GetVirshOptions());
- }
-
- FILE* launch = popen(launch_command.c_str(), "w");
- if (!launch) {
- LOG(FATAL) << "Unable to execute " << launch_command;
- }
- int rval = fputs(xml.c_str(), launch);
- if (rval == EOF) {
- LOG(FATAL) << "Launch command exited while accepting XML";
- }
- int exit_code = pclose(launch);
- if (exit_code) {
- LOG(FATAL) << "Launch command exited with status " << exit_code;
+ // Start the guest VM
+ vm_manager::LibvirtManager libvirt;
+ if (!libvirt.Start()) {
+ LOG(FATAL) << "Unable to start libvirt";
+ return -1;
}
LaunchSocketForwardProxyIfEnabled();
diff --git a/host/commands/launch/ril_region_handler.cc b/host/commands/launch/ril_region_handler.cc
index e122e291..31f5107f 100644
--- a/host/commands/launch/ril_region_handler.cc
+++ b/host/commands/launch/ril_region_handler.cc
@@ -22,21 +22,13 @@
#include <memory>
#include <string>
-#include <gflags/gflags.h>
-#include <glog/logging.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
#include "common/vsoc/lib/ril_region_view.h"
#include "host/commands/launch/pre_launch_initializers.h"
-#include "host/libs/config/host_config.h"
-
-DECLARE_string(hypervisor_uri);
-DECLARE_string(mobile_interface);
+#include "host/libs/config/cuttlefish_config.h"
namespace {
-int number_of_ones(int val) {
+int number_of_ones(unsigned long val) {
int ret = 0;
while (val) {
ret += val % 2;
@@ -54,7 +46,7 @@ class NetConfig {
std::string ril_broadcast;
bool ObtainConfig(const std::string& interface) {
- bool ret = ParseLibvirtXml(interface) && GetBroadcastAddr(interface);
+ bool ret = ParseIntefaceAttributes(interface);
LOG(INFO) << "Network config:";
LOG(INFO) << "ipaddr = " << ril_ipaddr;
LOG(INFO) << "gateway = " << ril_gateway;
@@ -65,102 +57,74 @@ class NetConfig {
}
private:
- bool GetBroadcastAddr(const std::string& interface) {
- struct ifaddrs *ifap{}, *ifa{};
- struct sockaddr_in *sa{};
- char *addr{};
- getifaddrs (&ifap);
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (ifa->ifa_addr && ifa->ifa_addr->sa_family==AF_INET) {
- if (strcmp(ifa->ifa_name, interface.c_str())) continue;
- sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_ifu.ifu_broadaddr);
- addr = inet_ntoa(sa->sin_addr);
- this->ril_broadcast = strtok(addr, "\n");
+ bool ParseIntefaceAttributes(struct ifaddrs* ifa) {
+ // if (ifa->ifa_addr->sa_family != AF_INET) {
+ // LOG(ERROR) << "The " << ifa->ifa_name << " interface is not IPv4";
+ // return false;
+ // }
+ struct sockaddr_in* sa;
+ char* addr_str;
+
+ // Gateway
+ sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_addr);
+ addr_str = inet_ntoa(sa->sin_addr);
+ this->ril_gateway = strtok(addr_str, "\n");
+ auto gateway_s_addr = ntohl(sa->sin_addr.s_addr);
+
+ // Broadcast
+ sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_broadaddr);
+ addr_str = inet_ntoa(sa->sin_addr);
+ this->ril_broadcast = strtok(addr_str, "\n");
+ auto broadcast_s_addr = ntohl(sa->sin_addr.s_addr);
+
+ // Netmask
+ sa = reinterpret_cast<sockaddr_in*>(ifa->ifa_netmask);
+ this->ril_prefixlen = number_of_ones(sa->sin_addr.s_addr);
+ auto netmask_s_addr = ntohl(sa->sin_addr.s_addr);
+
+ // Address (Find an address in the network different than the network, the
+ // gateway and the broadcast)
+ auto network = gateway_s_addr & netmask_s_addr;
+ auto s_addr = network + 1;
+ // s_addr & ~netmask_s_addr is zero when s_addr wraps around the network
+ while (s_addr & ~netmask_s_addr) {
+ if (s_addr != gateway_s_addr && s_addr != broadcast_s_addr) {
+ break;
}
+ ++s_addr;
}
-
- freeifaddrs(ifap);
- return (this->ril_broadcast.size() > 0);
- }
-
- bool ParseLibvirtXml(const std::string& interface) {
- std::string net_dump_command =
- "virsh -c " + FLAGS_hypervisor_uri + " net-dumpxml " + interface;
- std::shared_ptr<FILE> net_xml_file(popen(net_dump_command.c_str(), "r"),
- pclose);
- if (!net_xml_file) {
- LOG(ERROR) << "Unable to popen virsh...";
+ if (s_addr == network) {
+ LOG(ERROR) << "No available address found in interface " << ifa->ifa_name;
return false;
}
- std::shared_ptr<xmlDoc> doc(
- xmlReadFd(fileno(net_xml_file.get()), NULL, NULL, 0), xmlFreeDoc);
- if (!doc) {
- LOG(ERROR) << "Unable to parse network xml";
- return false;
- }
-
- xmlNode* element = xmlDocGetRootElement(doc.get());
- element = element->xmlChildrenNode;
- while (element) {
- if (strcmp(reinterpret_cast<const char*>(element->name), "ip") == 0) {
- return ProcessIpNode(element);
- }
- element = element->next;
- }
- LOG(ERROR) << "ip node not found in network xml spec";
- return false;
- }
-
- bool ParseIpAttributes(xmlNode* ip_node) {
- // The gateway is the host ip address
- this->ril_gateway = reinterpret_cast<const char*>(
- xmlGetProp(ip_node, reinterpret_cast<const xmlChar*>("address")));
-
- // The prefix length need to be obtained from the network mask
- auto* netmask = reinterpret_cast<const char*>(
- xmlGetProp(ip_node, reinterpret_cast<const xmlChar*>("netmask")));
- int byte1, byte2, byte3, byte4;
- sscanf(netmask, "%d.%d.%d.%d", &byte1, &byte2, &byte3, &byte4);
- this->ril_prefixlen = 0;
- this->ril_prefixlen += number_of_ones(byte1);
- this->ril_prefixlen += number_of_ones(byte2);
- this->ril_prefixlen += number_of_ones(byte3);
- this->ril_prefixlen += number_of_ones(byte4);
+ struct in_addr addr;
+ addr.s_addr = htonl(s_addr);
+ addr_str = inet_ntoa(addr);
+ this->ril_ipaddr = strtok(addr_str, "\n");
return true;
}
- bool ProcessDhcpNode(xmlNode* dhcp_node) {
- xmlNode* child = dhcp_node->xmlChildrenNode;
- while (child) {
- if (strcmp(reinterpret_cast<const char*>(child->name), "range") == 0) {
- this->ril_ipaddr = reinterpret_cast<const char*>(
- xmlGetProp(child, reinterpret_cast<const xmlChar*>("start")));
- return true;
- }
- child = child->next;
- }
- LOG(ERROR) << "range node not found in network xml spec";
- return false;
- }
-
- bool ProcessIpNode(xmlNode* ip_node) {
- ParseIpAttributes(ip_node);
- xmlNode* child = ip_node->xmlChildrenNode;
- while (child) {
- if (strcmp(reinterpret_cast<const char*>(child->name), "dhcp") == 0) {
- return ProcessDhcpNode(child);
+ bool ParseIntefaceAttributes(const std::string& interface) {
+ struct ifaddrs *ifa_list{}, *ifa{};
+ bool ret = false;
+ getifaddrs(&ifa_list);
+ for (ifa = ifa_list; ifa; ifa = ifa->ifa_next) {
+ if (strcmp(ifa->ifa_name, interface.c_str()) == 0 &&
+ ifa->ifa_addr->sa_family == AF_INET) {
+ ret = ParseIntefaceAttributes(ifa);
+ break;
}
- child = child->next;
}
- LOG(ERROR) << "dhcp node not found in network xml spec";
- return false;
+ freeifaddrs(ifa_list);
+ return ret;
}
};
} // namespace
void InitializeRilRegion() {
NetConfig netconfig;
- if (!netconfig.ObtainConfig(FLAGS_mobile_interface)) {
+ auto config = vsoc::CuttlefishConfig::Get();
+ if (!netconfig.ObtainConfig(config->mobile_bridge_name())) {
LOG(ERROR) << "Unable to obtain the network configuration";
return;
}
@@ -175,16 +139,12 @@ void InitializeRilRegion() {
auto dest = region->data();
- snprintf(
- dest->ipaddr, sizeof(dest->ipaddr), "%s", netconfig.ril_ipaddr.c_str());
- snprintf(dest->gateway,
- sizeof(dest->gateway),
- "%s",
+ snprintf(dest->ipaddr, sizeof(dest->ipaddr), "%s",
+ netconfig.ril_ipaddr.c_str());
+ snprintf(dest->gateway, sizeof(dest->gateway), "%s",
netconfig.ril_gateway.c_str());
snprintf(dest->dns, sizeof(dest->dns), "%s", netconfig.ril_dns.c_str());
- snprintf(dest->broadcast,
- sizeof(dest->broadcast),
- "%s",
+ snprintf(dest->broadcast, sizeof(dest->broadcast), "%s",
netconfig.ril_broadcast.c_str());
dest->prefixlen = netconfig.ril_prefixlen;
}
diff --git a/host/commands/launch/screen_region_handler.cc b/host/commands/launch/screen_region_handler.cc
index 4214482b..6e19ca11 100644
--- a/host/commands/launch/screen_region_handler.cc
+++ b/host/commands/launch/screen_region_handler.cc
@@ -14,29 +14,23 @@
* limitations under the License.
*/
-#include <gflags/gflags.h>
#include <glog/logging.h>
#include "common/vsoc/lib/screen_region_view.h"
#include "host/commands/launch/pre_launch_initializers.h"
-#include "host/libs/config/host_config.h"
-
-DEFINE_int32(x_res, 720, "Width of the screen in pixels");
-DEFINE_int32(y_res, 1280, "Height of the screen in pixels");
-DEFINE_int32(dpi, 160, "Pixels per inch for the screen");
-DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz");
-DEFINE_int32(num_screen_buffers, 3, "The number of screen buffers");
+#include "host/libs/config/cuttlefish_config.h"
void InitializeScreenRegion() {
auto region =
vsoc::screen::ScreenRegionView::GetInstance(vsoc::GetDomain().c_str());
+ auto config = vsoc::CuttlefishConfig::Get();
if (!region) {
- LOG(ERROR) << "Screen region was not found";
+ LOG(FATAL) << "Screen region was not found";
return;
}
auto dest = region->data();
- dest->x_res = FLAGS_x_res;
- dest->y_res = FLAGS_y_res;
- dest->dpi = FLAGS_dpi;
- dest->refresh_rate_hz = FLAGS_refresh_rate_hz;
+ dest->x_res = config->x_res();
+ dest->y_res = config->y_res();
+ dest->dpi = config->dpi();
+ dest->refresh_rate_hz = config->refresh_rate_hz();
}
diff --git a/host/commands/launch/wifi_region_handler.cc b/host/commands/launch/wifi_region_handler.cc
index 7f82c6a0..9d87c648 100644
--- a/host/commands/launch/wifi_region_handler.cc
+++ b/host/commands/launch/wifi_region_handler.cc
@@ -14,60 +14,38 @@
* limitations under the License.
*/
-#include <cassert>
#include <string>
-#include <gflags/gflags.h>
#include <glog/logging.h>
#include "common/vsoc/lib/wifi_exchange_view.h"
#include "host/commands/launch/pre_launch_initializers.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
using vsoc::wifi::WifiExchangeView;
-namespace {
-
-std::string GetPerInstanceDefaultMacAddress(const char* base_mac) {
- WifiExchangeView::MacAddress addr;
- if (!WifiExchangeView::ParseMACAddress(base_mac, &addr)) {
- LOG(FATAL) << "Unable to parse MAC address: " << base_mac;
- return "";
- }
- // Modify the last byte of the mac address to make it different for every cvd
- addr.back() = static_cast<uint8_t>(vsoc::GetPerInstanceDefault(addr.back()));
- return WifiExchangeView::MacAddressToString(addr);
-}
-
-} // namespace
-
-DEFINE_string(guest_mac_address,
- GetPerInstanceDefaultMacAddress("00:43:56:44:80:01"),
- "MAC address of the wifi interface to be created on the guest.");
-
-DEFINE_string(host_mac_address,
- "42:00:00:00:00:00",
- "MAC address of the wifi interface running on the host.");
-
void InitializeWifiRegion() {
auto region = WifiExchangeView::GetInstance(vsoc::GetDomain().c_str());
+ auto config = vsoc::CuttlefishConfig::Get();
if (!region) {
LOG(FATAL) << "Wifi region not found";
return;
}
WifiExchangeView::MacAddress guest_mac, host_mac;
- if (!WifiExchangeView::ParseMACAddress(FLAGS_guest_mac_address, &guest_mac)) {
+ if (!WifiExchangeView::ParseMACAddress(config->wifi_guest_mac_addr(),
+ &guest_mac)) {
LOG(FATAL) << "Unable to parse guest mac address: "
- << FLAGS_guest_mac_address;
+ << config->wifi_guest_mac_addr();
return;
}
- LOG(INFO) << "Setting guest mac to " << FLAGS_guest_mac_address;
+ LOG(INFO) << "Setting guest mac to " << config->wifi_guest_mac_addr();
region->SetGuestMACAddress(guest_mac);
- if (!WifiExchangeView::ParseMACAddress(FLAGS_host_mac_address, &host_mac)) {
+ if (!WifiExchangeView::ParseMACAddress(config->wifi_host_mac_addr(),
+ &host_mac)) {
LOG(FATAL) << "Unable to parse guest mac address: "
- << FLAGS_guest_mac_address;
+ << config->wifi_guest_mac_addr();
return;
}
- LOG(INFO) << "Setting host mac to " << FLAGS_host_mac_address;
+ LOG(INFO) << "Setting host mac to " << config->wifi_host_mac_addr();
region->SetHostMACAddress(host_mac);
}
diff --git a/host/commands/record_audio/Android.bp b/host/commands/record_audio/Android.bp
index d380e239..b7bfe928 100644
--- a/host/commands/record_audio/Android.bp
+++ b/host/commands/record_audio/Android.bp
@@ -27,6 +27,7 @@ cc_binary_host {
],
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
"libgflags",
],
defaults: ["cuttlefish_host_only"],
diff --git a/host/commands/record_audio/main.cc b/host/commands/record_audio/main.cc
index 26558386..18466f3e 100644
--- a/host/commands/record_audio/main.cc
+++ b/host/commands/record_audio/main.cc
@@ -17,7 +17,7 @@
#include "common/vsoc/lib/audio_data_region_view.h"
#include "common/vsoc/lib/circqueue_impl.h"
#include "common/vsoc/lib/vsoc_audio_message.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#include "WaveWriter.h"
diff --git a/host/commands/stop_cvd/Android.bp b/host/commands/stop_cvd/Android.bp
index 429fd6c4..3607e8ed 100644
--- a/host/commands/stop_cvd/Android.bp
+++ b/host/commands/stop_cvd/Android.bp
@@ -23,10 +23,16 @@ cc_binary_host {
],
shared_libs: [
"libbase",
+ "libcuttlefish_fs",
+ "cuttlefish_auto_resources",
+ "libicuuc",
],
static_libs: [
"libcuttlefish_host_config",
+ "libcuttlefish_vm_manager",
+ "libjsoncpp",
"libgflags",
+ "libxml2",
],
defaults: ["cuttlefish_host_only"],
}
diff --git a/host/commands/stop_cvd/main.cc b/host/commands/stop_cvd/main.cc
index 2c2baf7c..08648b16 100644
--- a/host/commands/stop_cvd/main.cc
+++ b/host/commands/stop_cvd/main.cc
@@ -35,26 +35,15 @@
#include <gflags/gflags.h>
#include <glog/logging.h>
-#include "host/libs/config/host_config.h"
-
-using vsoc::GetDefaultPerInstancePath;
-using vsoc::GetPerInstanceDefault;
-
-DECLARE_int32(instance);
-// TODO(b/78512938): These parameters should go away when the launcher work is
-// completed and the process monitor handles the shutdown.
-DEFINE_string(hypervisor_uri, "qemu:///system", "Hypervisor cannonical uri.");
-std::string g_default_mempath{GetPerInstanceDefault("/var/run/shm/cvd-")};
-DEFINE_string(mempath,
- g_default_mempath.c_str(),
- "Target location for the shmem file.");
+#include "host/libs/config/cuttlefish_config.h"
+#include "host/libs/vm_manager/libvirt_manager.h"
namespace {
void RunCommand(const char* command) {
- LOG(INFO) << "Running: " << command;
int rval = std::system(command);
if (rval) {
- LOG(ERROR) << "Unable to execute command: " << command;
+ LOG(ERROR) << "Unable to execute command: " << command
+ << ". Exit code: " << rval;
}
}
} // anonymous namespace
@@ -63,25 +52,28 @@ int main(int argc, char** argv) {
::android::base::InitLogging(argv, android::base::StderrLogger);
google::ParseCommandLineFlags(&argc, &argv, true);
+ int exit_code = 0;
+
// TODO(b/78512938): Should ask the monitor to do the shutdown instead
- std::ostringstream cvd_strm;
- cvd_strm << "cvd-" << std::setfill('0') << std::setw(2) << FLAGS_instance;
- auto cvd = cvd_strm.str();
- std::string destroy_cmd = "virsh ";
- destroy_cmd += "-c ";
- destroy_cmd += FLAGS_hypervisor_uri;
- destroy_cmd += " destroy ";
- destroy_cmd += cvd;
- RunCommand(destroy_cmd.c_str());
+ vm_manager::LibvirtManager libvirt_manager;
+ if (!libvirt_manager.Stop()) {
+ LOG(ERROR)
+ << "Error when stopping guest virtual machine. Is it still running?";
+ exit_code = 1;
+ }
+
+ auto config = vsoc::CuttlefishConfig::Get();
// TODO(b/78512938): Shouldn't need sudo to shut down
- std::string run_files = vsoc::GetDefaultPerInstanceDir() + "/*";
+ std::string run_files = config->PerInstancePath("*");
std::string fuser_cmd = "sudo fuser -k ";
fuser_cmd += run_files;
fuser_cmd += " ";
- fuser_cmd += FLAGS_mempath;
+ fuser_cmd += config->mempath();
RunCommand(fuser_cmd.c_str());
std::string delete_cmd = "rm -f ";
delete_cmd += run_files;
RunCommand(delete_cmd.c_str());
+
+ return exit_code;
}
diff --git a/host/frontend/vnc_server/Android.bp b/host/frontend/vnc_server/Android.bp
index cf8a2c41..6508945a 100644
--- a/host/frontend/vnc_server/Android.bp
+++ b/host/frontend/vnc_server/Android.bp
@@ -37,6 +37,7 @@ cc_binary_host {
],
static_libs: [
"libcuttlefish_host_config",
+ "libjsoncpp",
"libjpeg",
"libgflags",
],
diff --git a/host/frontend/vnc_server/main.cpp b/host/frontend/vnc_server/main.cpp
index 26162025..eab7011d 100644
--- a/host/frontend/vnc_server/main.cpp
+++ b/host/frontend/vnc_server/main.cpp
@@ -22,7 +22,7 @@
#include "common/libs/glog/logging.h"
#include "host/frontend/vnc_server/vnc_server.h"
#include "host/frontend/vnc_server/vnc_utils.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
DEFINE_bool(agressive, false, "Whether to use agressive server");
DEFINE_int32(port, 6444, "Port where to listen for connections");
diff --git a/host/frontend/vnc_server/simulated_hw_composer.cpp b/host/frontend/vnc_server/simulated_hw_composer.cpp
index 7141bd16..c8b7f036 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.cpp
+++ b/host/frontend/vnc_server/simulated_hw_composer.cpp
@@ -17,7 +17,7 @@
#include "host/frontend/vnc_server/simulated_hw_composer.h"
#include "host/frontend/vnc_server/vnc_utils.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
#include "common/vsoc/lib/screen_region_view.h"
using cvd::vnc::SimulatedHWComposer;
diff --git a/host/frontend/vnc_server/vnc_utils.h b/host/frontend/vnc_server/vnc_utils.h
index 558aa57f..3eac9f35 100644
--- a/host/frontend/vnc_server/vnc_utils.h
+++ b/host/frontend/vnc_server/vnc_utils.h
@@ -23,7 +23,7 @@
#include "common/libs/tcp_socket/tcp_socket.h"
#include "common/vsoc/lib/screen_region_view.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
namespace cvd {
namespace vnc {
diff --git a/host/libs/Android.bp b/host/libs/Android.bp
index 12fde972..540b9b41 100644
--- a/host/libs/Android.bp
+++ b/host/libs/Android.bp
@@ -20,4 +20,5 @@ subdirs = [
"ivserver",
"vadb",
"usbip",
+ "vm_manager",
]
diff --git a/host/libs/config/Android.bp b/host/libs/config/Android.bp
index df9f99b7..9b70a07d 100644
--- a/host/libs/config/Android.bp
+++ b/host/libs/config/Android.bp
@@ -16,9 +16,7 @@
cc_library_host_static {
name: "libcuttlefish_host_config",
srcs: [
- "file_partition.cpp",
- "guest_config.cpp",
- "host_config.cpp",
+ "cuttlefish_config.cpp"
],
header_libs: [
"cuttlefish_glog",
@@ -31,6 +29,7 @@ cc_library_host_static {
static_libs: [
"libxml2",
"libgflags",
+ "libjsoncpp",
],
defaults: ["cuttlefish_host_only"],
}
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
new file mode 100644
index 00000000..bd70a958
--- /dev/null
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -0,0 +1,433 @@
+/*
+ * 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/config/cuttlefish_config.h"
+
+#include <climits>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+#include <json/json.h>
+
+DEFINE_string(config_file,
+ vsoc::GetDefaultPerInstanceDir() + "/cuttlefish_config.json",
+ "A file from where to load the config values. This flag is "
+ "ignored by the launcher");
+
+namespace {
+
+constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
+
+int InstanceFromEnvironment() {
+ static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE";
+ static constexpr char kVsocUserPrefix[] = "vsoc-";
+ static constexpr int kDefaultInstance = 1;
+
+ // CUTTLEFISH_INSTANCE environment variable
+ const char* instance_str = std::getenv(kInstanceEnvironmentVariable);
+ if (!instance_str) {
+ // Try to get it from the user instead
+ instance_str = std::getenv("USER");
+ if (!instance_str || std::strncmp(instance_str, kVsocUserPrefix,
+ sizeof(kVsocUserPrefix) - 1)) {
+ // No user or we don't recognize this user
+ return kDefaultInstance;
+ }
+ instance_str += sizeof(kVsocUserPrefix) - 1;
+ // Set the environment variable so that child processes see it
+ setenv(kInstanceEnvironmentVariable, instance_str, 0);
+ }
+
+ int instance = std::atoi(instance_str);
+ if (instance <= 0) {
+ instance = kDefaultInstance;
+ }
+
+ return instance;
+}
+const char* kSerialNumber = "serial_number";
+const char* kInstanceDir = "instance_dir";
+
+const char* kCpus = "cpus";
+const char* kMemoryMb = "memory_mb";
+const char* kDpi = "dpi";
+const char* kXRes = "x_res";
+const char* kYRes = "y_res";
+const char* kRefreshRateHz = "refresh_rate_hz";
+
+const char* kKernelImagePath = "kernel_image_path";
+const char* kKernelArgs = "kernel_args";
+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* kUsbV1SocketName = "usb_v1_socket_name";
+const char* kVhciPort = "vhci_port";
+const char* kUsbIpSocketName = "usb_ip_socket_name";
+const char* kKernelLogSocketName = "kernel_log_socket_name";
+const char* kConsolePath = "console_path";
+const char* kLogcatPath = "logcat_path";
+const char* kDtbPath = "dtb_path";
+
+const char* kMempath = "mempath";
+const char* kIvshmemQemuSocketPath = "ivshmem_qemu_socket_path";
+const char* kIvshmemClientSocketPath = "ivshmem_client_socket_path";
+const char* kIvshmemVectorCount = "ivshmem_vector_count";
+
+const char* kMobileBridgeName = "mobile_bridge_name";
+const char* kMobileTapName = "mobile_tap_name";
+const char* kWifiGuestMacAddr = "wifi_guest_mac_addr";
+const char* kWifiHostMacAddr = "wifi_host_mac_addr";
+const char* kEntropySource = "entropy_source";
+
+const char* kUuid = "uuid";
+const char* kDisableDacSecurity = "disable_dac_security";
+const char* kDisableAppArmorSecurity = "disable_app_armor_security";
+} // namespace
+
+namespace vsoc {
+
+std::string CuttlefishConfig::instance_dir() const {
+ return (*dictionary_)[kInstanceDir].asString();
+}
+void CuttlefishConfig::set_instance_dir(const std::string& instance_dir) {
+ (*dictionary_)[kInstanceDir] = instance_dir;
+}
+
+std::string CuttlefishConfig::serial_number() const {
+ return (*dictionary_)[kSerialNumber].asString();
+}
+void CuttlefishConfig::set_serial_number(const std::string& serial_number) {
+ (*dictionary_)[kSerialNumber] = serial_number;
+}
+
+int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); }
+void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; }
+
+int CuttlefishConfig::memory_mb() const {
+ return (*dictionary_)[kMemoryMb].asInt();
+}
+void CuttlefishConfig::set_memory_mb(int memory_mb) {
+ (*dictionary_)[kMemoryMb] = memory_mb;
+}
+
+int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); }
+void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; }
+
+int CuttlefishConfig::x_res() const { return (*dictionary_)[kXRes].asInt(); }
+void CuttlefishConfig::set_x_res(int x_res) { (*dictionary_)[kXRes] = x_res; }
+
+int CuttlefishConfig::y_res() const { return (*dictionary_)[kYRes].asInt(); }
+void CuttlefishConfig::set_y_res(int y_res) { (*dictionary_)[kYRes] = y_res; }
+
+int CuttlefishConfig::refresh_rate_hz() const {
+ return (*dictionary_)[kRefreshRateHz].asInt();
+}
+void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) {
+ (*dictionary_)[kRefreshRateHz] = refresh_rate_hz;
+}
+
+std::string CuttlefishConfig::kernel_image_path() const {
+ return (*dictionary_)[kKernelImagePath].asString();
+}
+void CuttlefishConfig::set_kernel_image_path(
+ const std::string& kernel_image_path) {
+ (*dictionary_)[kKernelImagePath] = kernel_image_path;
+}
+
+std::string CuttlefishConfig::kernel_args() const {
+ return (*dictionary_)[kKernelArgs].asString();
+}
+void CuttlefishConfig::set_kernel_args(const std::string& kernel_args) {
+ (*dictionary_)[kKernelArgs] = kernel_args;
+}
+
+std::string CuttlefishConfig::ramdisk_image_path() const {
+ return (*dictionary_)[kRamdiskImagePath].asString();
+}
+void CuttlefishConfig::set_ramdisk_image_path(
+ const std::string& ramdisk_image_path) {
+ (*dictionary_)[kRamdiskImagePath] = ramdisk_image_path;
+}
+
+std::string CuttlefishConfig::system_image_path() const {
+ return (*dictionary_)[kSystemImagePath].asString();
+}
+void CuttlefishConfig::set_system_image_path(
+ const std::string& system_image_path) {
+ (*dictionary_)[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) {
+ (*dictionary_)[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) {
+ (*dictionary_)[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) {
+ (*dictionary_)[kVendorImagePath] = vendor_image_path;
+}
+
+std::string CuttlefishConfig::dtb_path() const {
+ return (*dictionary_)[kDtbPath].asString();
+}
+void CuttlefishConfig::set_dtb_path(const std::string& dtb_path) {
+ (*dictionary_)[kDtbPath] = dtb_path;
+}
+
+std::string CuttlefishConfig::mempath() const {
+ return (*dictionary_)[kMempath].asString();
+}
+void CuttlefishConfig::set_mempath(const std::string& mempath) {
+ (*dictionary_)[kMempath] = mempath;
+}
+
+std::string CuttlefishConfig::ivshmem_qemu_socket_path() const {
+ return (*dictionary_)[kIvshmemQemuSocketPath].asString();
+}
+void CuttlefishConfig::set_ivshmem_qemu_socket_path(
+ const std::string& ivshmem_qemu_socket_path) {
+ (*dictionary_)[kIvshmemQemuSocketPath] = ivshmem_qemu_socket_path;
+}
+
+std::string CuttlefishConfig::ivshmem_client_socket_path() const {
+ return (*dictionary_)[kIvshmemClientSocketPath].asString();
+}
+void CuttlefishConfig::set_ivshmem_client_socket_path(
+ const std::string& ivshmem_client_socket_path) {
+ (*dictionary_)[kIvshmemClientSocketPath] = ivshmem_client_socket_path;
+}
+
+int CuttlefishConfig::ivshmem_vector_count() const {
+ return (*dictionary_)[kIvshmemVectorCount].asInt();
+}
+void CuttlefishConfig::set_ivshmem_vector_count(int ivshmem_vector_count) {
+ (*dictionary_)[kIvshmemVectorCount] = ivshmem_vector_count;
+}
+
+std::string CuttlefishConfig::usb_v1_socket_name() const {
+ return (*dictionary_)[kUsbV1SocketName].asString();
+}
+void CuttlefishConfig::set_usb_v1_socket_name(
+ const std::string& usb_v1_socket_name) {
+ (*dictionary_)[kUsbV1SocketName] = usb_v1_socket_name;
+}
+
+int CuttlefishConfig::vhci_port() const {
+ return (*dictionary_)[kVhciPort].asInt();
+}
+void CuttlefishConfig::set_vhci_port(int vhci_port) {
+ (*dictionary_)[kVhciPort] = vhci_port;
+}
+
+std::string CuttlefishConfig::usb_ip_socket_name() const {
+ return (*dictionary_)[kUsbIpSocketName].asString();
+}
+void CuttlefishConfig::set_usb_ip_socket_name(
+ const std::string& usb_ip_socket_name) {
+ (*dictionary_)[kUsbIpSocketName] = usb_ip_socket_name;
+}
+
+std::string CuttlefishConfig::kernel_log_socket_name() const {
+ return (*dictionary_)[kKernelLogSocketName].asString();
+}
+void CuttlefishConfig::set_kernel_log_socket_name(
+ const std::string& kernel_log_socket_name) {
+ (*dictionary_)[kKernelLogSocketName] = kernel_log_socket_name;
+}
+
+std::string CuttlefishConfig::console_path() const {
+ return (*dictionary_)[kConsolePath].asString();
+}
+void CuttlefishConfig::set_console_path(const std::string& console_path) {
+ (*dictionary_)[kConsolePath] = console_path;
+}
+
+std::string CuttlefishConfig::logcat_path() const {
+ return (*dictionary_)[kLogcatPath].asString();
+}
+void CuttlefishConfig::set_logcat_path(const std::string& logcat_path) {
+ (*dictionary_)[kLogcatPath] = logcat_path;
+}
+
+std::string CuttlefishConfig::mobile_bridge_name() const {
+ return (*dictionary_)[kMobileBridgeName].asString();
+}
+void CuttlefishConfig::set_mobile_bridge_name(
+ const std::string& mobile_bridge_name) {
+ (*dictionary_)[kMobileBridgeName] = mobile_bridge_name;
+}
+
+std::string CuttlefishConfig::wifi_guest_mac_addr() const {
+ return (*dictionary_)[kWifiGuestMacAddr].asString();
+}
+void CuttlefishConfig::set_wifi_guest_mac_addr(
+ const std::string& wifi_guest_mac_addr) {
+ (*dictionary_)[kWifiGuestMacAddr] = wifi_guest_mac_addr;
+}
+
+std::string CuttlefishConfig::wifi_host_mac_addr() const {
+ return (*dictionary_)[kWifiHostMacAddr].asString();
+}
+void CuttlefishConfig::set_wifi_host_mac_addr(
+ const std::string& wifi_host_mac_addr) {
+ (*dictionary_)[kWifiHostMacAddr] = wifi_host_mac_addr;
+}
+
+std::string CuttlefishConfig::mobile_tap_name() const {
+ return (*dictionary_)[kMobileTapName].asString();
+}
+void CuttlefishConfig::set_mobile_tap_name(const std::string& mobile_tap_name) {
+ (*dictionary_)[kMobileTapName] = mobile_tap_name;
+}
+
+std::string CuttlefishConfig::entropy_source() const {
+ return (*dictionary_)[kEntropySource].asString();
+}
+void CuttlefishConfig::set_entropy_source(const std::string& entropy_source) {
+ (*dictionary_)[kEntropySource] = entropy_source;
+}
+
+std::string CuttlefishConfig::uuid() const {
+ return (*dictionary_)[kUuid].asString();
+}
+void CuttlefishConfig::set_uuid(const std::string& uuid) {
+ (*dictionary_)[kUuid] = uuid;
+}
+
+bool CuttlefishConfig::disable_dac_security() const {
+ return (*dictionary_)[kDisableDacSecurity].asBool();
+}
+void CuttlefishConfig::set_disable_dac_security(bool disable_dac_security) {
+ (*dictionary_)[kDisableDacSecurity] = disable_dac_security;
+}
+
+bool CuttlefishConfig::disable_app_armor_security() const {
+ return (*dictionary_)[kDisableAppArmorSecurity].asBool();
+}
+void CuttlefishConfig::set_disable_app_armor_security(
+ bool disable_app_armor_security) {
+ (*dictionary_)[kDisableAppArmorSecurity] = disable_app_armor_security;
+}
+
+/*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());
+ }
+}
+
+void CuttlefishConfig::LoadFromFile(const char* file) {
+ char real_file_path[PATH_MAX];
+ if (realpath(file, real_file_path) == nullptr) {
+ LOG(FATAL) << "Could not get real path for file " << file << ": "
+ << strerror(errno);
+ }
+
+ Json::Reader reader;
+ std::ifstream ifs(real_file_path);
+ if (!reader.parse(ifs, *dictionary_)) {
+ LOG(FATAL) << "Could not read config file " << file << ": "
+ << reader.getFormattedErrorMessages();
+ }
+}
+bool CuttlefishConfig::SaveToFile(const std::string& file) const {
+ std::ofstream ofs(file);
+ if (!ofs.is_open()) {
+ LOG(ERROR) << "Unable to write to file " << file;
+ return false;
+ }
+ ofs << *dictionary_;
+ return !ofs.fail();
+}
+
+std::string CuttlefishConfig::PerInstancePath(const char* file_name) const {
+ return (instance_dir() + "/") + file_name;
+}
+
+std::string CuttlefishConfig::instance_name() const {
+ return GetPerInstanceDefault("cvd-");
+}
+
+bool CuttlefishConfig::ReadKernelArgs(const std::string& cmdline_file,
+ const std::string& extra_args) {
+ std::ostringstream kernel_args;
+ std::ifstream cmd_stream(cmdline_file);
+ if (!cmd_stream) {
+ LOG(WARNING) << "Unable to open " << cmdline_file;
+ return false;
+ } else {
+ kernel_args << cmd_stream.rdbuf();
+ cmd_stream.close();
+ }
+ if (!extra_args.empty()) {
+ kernel_args << " " << extra_args;
+ }
+ set_kernel_args(kernel_args.str());
+ return true;
+}
+
+int GetInstance() {
+ static int instance_id = InstanceFromEnvironment();
+ return instance_id;
+}
+
+std::string GetDomain() {
+ return CuttlefishConfig::Get()->ivshmem_client_socket_path();
+}
+
+std::string GetPerInstanceDefault(const char* prefix) {
+ std::ostringstream stream;
+ stream << prefix << std::setfill('0') << std::setw(2) << GetInstance();
+ return stream.str();
+}
+int GetPerInstanceDefault(int base) { return base + GetInstance() - 1; }
+
+std::string GetDefaultPerInstanceDir() {
+ // TODO(79170615): Change to a directory in home once libvirt is no longer
+ // default.
+ std::ostringstream stream;
+ stream << "/var/run/libvirt-" << kDefaultUuidPrefix << std::setfill('0')
+ << std::setw(2) << GetInstance();
+ return stream.str();
+}
+
+} // namespace vsoc
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
new file mode 100644
index 00000000..50e8616a
--- /dev/null
+++ b/host/libs/config/cuttlefish_config.h
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+
+namespace Json {
+class Value;
+}
+
+namespace vsoc {
+
+// Holds the configuration of the cuttlefish instances.
+class CuttlefishConfig {
+ public:
+ static CuttlefishConfig* Get();
+ ~CuttlefishConfig() = default;
+
+ // Saves the configuration object in a file, it can then be read in other
+ // processes by passing the --config_file option.
+ bool SaveToFile(const std::string& file) const ;
+
+ // Returns the path to a file with the given name in the instance directory..
+ std::string PerInstancePath(const char* file_name) const;
+
+ std::string instance_name() const;
+
+ void disable_usb_adb() {
+ // This seems to be the way usb is being disbled in the launcher
+ set_usb_v1_socket_name("");
+ }
+
+ // Reads the kernel command line from a file and appends extra arguments.
+ bool ReadKernelArgs(const std::string& cmdline_file,
+ const std::string& extra_args);
+
+ std::string instance_dir() const;
+ void set_instance_dir(const std::string& instance_dir);
+
+ std::string serial_number() const;
+ void set_serial_number(const std::string& serial_number);
+
+ int cpus() const;
+ void set_cpus(int cpus);
+
+ int memory_mb() const;
+ void set_memory_mb(int memory_mb);
+
+ int dpi() const;
+ void set_dpi(int dpi);
+
+ int x_res() const;
+ void set_x_res(int x_res);
+
+ int y_res() const;
+ void set_y_res(int y_res);
+
+ int refresh_rate_hz() const;
+ void set_refresh_rate_hz(int refresh_rate_hz);
+
+ std::string kernel_image_path() const;
+ void set_kernel_image_path(const std::string& kernel_image_path);
+
+ std::string kernel_args() const;
+ void set_kernel_args(const std::string& kernel_args);
+
+ 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 dtb_path() const;
+ void set_dtb_path(const std::string& dtb_path);
+
+ std::string mempath() const;
+ void set_mempath(const std::string& mempath);
+
+ std::string ivshmem_qemu_socket_path() const;
+ void set_ivshmem_qemu_socket_path(
+ const std::string& ivshmem_qemu_socket_path);
+
+ std::string ivshmem_client_socket_path() const;
+ void set_ivshmem_client_socket_path(
+ const std::string& ivshmem_client_socket_path);
+
+ int ivshmem_vector_count() const;
+ void set_ivshmem_vector_count(int ivshmem_vector_count);
+
+ // The name of the socket that will be used to forward access to USB gadget.
+ // This is for V1 of the USB bus.
+ std::string usb_v1_socket_name() const;
+ void set_usb_v1_socket_name(const std::string& usb_v1_socket_name);
+
+ int vhci_port() const;
+ void set_vhci_port(int vhci_port);
+
+ std::string usb_ip_socket_name() const;
+ void set_usb_ip_socket_name(const std::string& usb_ip_socket_name);
+
+ std::string kernel_log_socket_name() const;
+ void set_kernel_log_socket_name(const std::string& kernel_log_socket_name);
+
+ std::string console_path() const;
+ void set_console_path(const std::string& console_path);
+
+ std::string logcat_path() const;
+ void set_logcat_path(const std::string& logcat_path);
+
+ std::string mobile_bridge_name() const;
+ void set_mobile_bridge_name(const std::string& mobile_bridge_name);
+
+ std::string mobile_tap_name() const;
+ void set_mobile_tap_name(const std::string& mobile_tap_name);
+
+ std::string wifi_guest_mac_addr() const;
+ void set_wifi_guest_mac_addr(const std::string& wifi_guest_mac_addr);
+
+ std::string wifi_host_mac_addr() const;
+ void set_wifi_host_mac_addr(const std::string& wifi_host_mac_addr);
+
+ std::string entropy_source() const;
+ void set_entropy_source(const std::string& entropy_source);
+
+ std::string uuid() const;
+ void set_uuid(const std::string& uuid);
+
+ bool disable_dac_security() const;
+ void set_disable_dac_security(bool disable_dac_security);
+
+ bool disable_app_armor_security() const;
+ void set_disable_app_armor_security(bool disable_app_armor_security);
+
+ private:
+ std::unique_ptr<Json::Value> dictionary_;
+
+ void LoadFromFile(const char* file);
+
+ CuttlefishConfig();
+ CuttlefishConfig(const CuttlefishConfig&) = delete;
+ CuttlefishConfig& operator=(const CuttlefishConfig&) = delete;
+};
+
+// Returns the instance number as obtained from the CUTTLEFISH_INSTANCE
+// environment variable or the username.
+int GetInstance();
+
+// Returns the path to the ivserver's client socket.
+std::string GetDomain();
+
+// These functions modify a given base value to make it different accross
+// different instances by appending the instance id in case of strings or adding
+// it in case of integers.
+std::string GetPerInstanceDefault(const char* prefix);
+int GetPerInstanceDefault(int base);
+
+std::string GetDefaultPerInstanceDir();
+
+} // namespace vsoc
diff --git a/host/libs/config/file_partition.cpp b/host/libs/config/file_partition.cpp
deleted file mode 100644
index ede4870b..00000000
--- a/host/libs/config/file_partition.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2017 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 <errno.h>
-#include <limits.h>
-
-#include <sstream>
-
-#include <glog/logging.h>
-
-#include "common/libs/fs/shared_fd.h"
-#include "host/libs/config/file_partition.h"
-
-namespace config {
-namespace {
-constexpr char kTempFileSuffix[] = ".img";
-
-void Initialize(const std::string& path) {
- std::string command = "/sbin/mkfs.ext4 -F '" + path + "' &>/dev/null";
- CHECK(system(command.c_str()) == 0)
- << "Could not initialize filesystem on partition image " << path << ": "
- << strerror(errno);
-}
-} // namespace
-
-FilePartition::~FilePartition() {
- if (should_delete_) {
- LOG(INFO) << "Deleting partition image file " << name_;
- errno = 0;
- unlink(name_.c_str());
- if (errno != 0) {
- LOG(WARNING) << "Could not delete partition image file: "
- << strerror(errno);
- }
- }
-}
-
-std::unique_ptr<FilePartition> FilePartition::ReuseExistingFile(
- const std::string& path) {
- return std::unique_ptr<FilePartition>(new FilePartition(path, false));
-}
-
-std::unique_ptr<FilePartition> FilePartition::CreateNewFile(
- const std::string& path, int size_mb) {
- {
- cvd::SharedFD fd(cvd::SharedFD::Open(path.c_str(), O_CREAT | O_RDWR, 0600));
- CHECK(fd->IsOpen()) << "Could not open file: " << path << ": "
- << fd->StrError();
- CHECK(fd->Truncate(size_mb << 20) == 0)
- << "Could not truncate file " << path << ": " << fd->StrError();
- }
-
- Initialize(path);
- return std::unique_ptr<FilePartition>(new FilePartition(path, false));
-}
-
-// Create temporary FilePartition object using supplied prefix.
-// Newly created file will be deleted after this instance is destroyed.
-std::unique_ptr<FilePartition> FilePartition::CreateTemporaryFile(
- const std::string& prefix, int size_mb) {
- std::stringstream ss;
- ss << prefix << "-XXXXXX" << kTempFileSuffix;
- char path[PATH_MAX];
- strncpy(&path[0], ss.str().c_str(), sizeof(path));
-
- {
- int raw_fd = mkostemps(&path[0], strlen(kTempFileSuffix), O_RDWR | O_CREAT);
- CHECK(raw_fd > 0) << "Could not create temporary file: " << strerror(errno);
- CHECK(ftruncate(raw_fd, size_mb << 20) == 0)
- << "Could not truncate file " << path << ": " << strerror(errno);
- close(raw_fd);
- }
-
- Initialize(path);
- return std::unique_ptr<FilePartition>(new FilePartition(path, true));
-}
-
-} // namespace config
diff --git a/host/libs/config/file_partition.h b/host/libs/config/file_partition.h
deleted file mode 100644
index 3c8e55b3..00000000
--- a/host/libs/config/file_partition.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 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 <memory>
-#include <string>
-
-namespace config {
-// FilePartition class manages partition image files.
-// Partition image files can be reused or created on demand. Temporary images
-// are deleted when corresponding instances of FilePartition object are
-// destroyed.
-class FilePartition {
- public:
- ~FilePartition();
-
- // Create FilePartition object from existing file.
- // Specified file will not be disposed of after this instance is destroyed.
- static std::unique_ptr<FilePartition> ReuseExistingFile(
- const std::string& path);
-
- // Create FilePartition object at specified location and initialize content.
- // Specified file will not be disposed of after this instance is destroyed.
- static std::unique_ptr<FilePartition> CreateNewFile(const std::string& path,
- int size_mb);
-
- // Create temporary FilePartition object using supplied prefix.
- // Newly created file will be deleted after this instance is destroyed.
- static std::unique_ptr<FilePartition> CreateTemporaryFile(
- const std::string& prefix, int size_mb);
-
- const std::string& GetName() const { return name_; }
-
- private:
- std::string name_;
- bool should_delete_ = false;
-
- FilePartition(const std::string& name, bool should_delete)
- : name_(name), should_delete_(should_delete) {}
-
- FilePartition(const FilePartition&) = delete;
- FilePartition& operator=(const FilePartition&) = delete;
-};
-
-} // namespace config
diff --git a/host/libs/config/guest_config.h b/host/libs/config/guest_config.h
deleted file mode 100644
index ff7432fb..00000000
--- a/host/libs/config/guest_config.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2017 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 <memory>
-#include <string>
-
-namespace config {
-// GuestConfig builds XML document describing target VM.
-// Documents built by GuestConfig can be directly used by libvirt to instantiate
-// new virtual machine.
-class GuestConfig {
- public:
- GuestConfig() = default;
- ~GuestConfig() = default;
-
- // Set instance ID.
- GuestConfig& SetID(int id) {
- id_ = id;
- return *this;
- }
-
- // Set number of virtual CPUs.
- GuestConfig& SetVCPUs(int vcpus) {
- vcpus_ = vcpus;
- return *this;
- }
-
- // Set total memory amount it MB.
- GuestConfig& SetMemoryMB(int mem_mb) {
- memory_mb_ = mem_mb;
- return *this;
- }
-
- // Set kernel path.
- GuestConfig& SetKernelName(const std::string& kernel) {
- kernel_name_ = kernel;
- return *this;
- }
-
- // Set kernel cmdline arguments.
- GuestConfig& SetKernelArgs(const std::string& args) {
- kernel_args_ = args;
- return *this;
- }
-
- // Set initrd path.
- GuestConfig& SetInitRDName(const std::string& initrd) {
- initrd_name_ = initrd;
- return *this;
- }
-
- // Set Android system partition image path.
- GuestConfig& SetSystemPartitionPath(const std::string& path) {
- system_partition_path_ = path;
- return *this;
- }
-
- // Set Android data partition image path.
- GuestConfig& SetCachePartitionPath(const std::string& path) {
- cache_partition_path_ = path;
- return *this;
- }
-
- // Set Android data partition image path.
- GuestConfig& SetDataPartitionPath(const std::string& path) {
- data_partition_path_ = path;
- return *this;
- }
-
- // Set Android vendor partition image path.
- GuestConfig& SetVendorPartitionPath(const std::string& path) {
- vendor_partition_path_ = path;
- return *this;
- }
-
- // Set ivshmem server socket path.
- GuestConfig& SetIVShMemSocketPath(const std::string& path) {
- ivshmem_socket_path_ = path;
- return *this;
- }
-
- // Set number of vectors supplied by ivserver.
- GuestConfig& SetIVShMemVectorCount(int count) {
- ivshmem_vector_count_ = count;
- return *this;
- }
-
- // Set name of the mobile bridge, eg. br0
- GuestConfig& SetMobileBridgeName(const std::string& name) {
- mobile_bridge_name_ = name;
- return *this;
- }
-
- // Set source of entropy, eg. /dev/urandom.
- GuestConfig& SetEntropySource(const std::string& source) {
- entropy_source_ = source;
- return *this;
- }
-
- // Flags to disable the AppArmor security features of libvirt
- GuestConfig& SetDisableAppArmorSecurity(bool value) {
- disable_app_armor_security_ = value;
- return *this;
- }
-
- // Flags to disable the DAC security features of libvirt
- GuestConfig& SetDisableDACSecurity(bool value) {
- disable_dac_security_ = value;
- return *this;
- }
-
- // The UUID that libvirt uses to identify the instance
- GuestConfig& SetUUID(const std::string& uuid) {
- uuid_ = uuid;
- return *this;
- }
-
- // GetInstanceName returns name of this newly created instance.
- std::string GetInstanceName() const;
-
- // GetUSBSocketName returns name of the USB socket that will be used to
- // forward access to USB gadget. This is for V1 of the USB bus.
- std::string GetUSBV1SocketName() const { return usb_v1_socket_name_; }
-
- GuestConfig& SetUSBV1SocketName(const std::string& source) {
- usb_v1_socket_name_ = source;
- return *this;
- }
-
- std::string GetKernelLogSocketName() const { return kernel_log_socket_name_; }
-
- GuestConfig& SetKernelLogSocketName(const std::string& source) {
- kernel_log_socket_name_ = source;
- return *this;
- }
-
- // Build document as formatted XML string.
- std::string Build() const;
-
- private:
- int id_;
- int vcpus_;
- int memory_mb_;
-
- std::string kernel_name_;
- std::string kernel_args_;
- std::string initrd_name_;
-
- std::string system_partition_path_;
- std::string cache_partition_path_;
- std::string data_partition_path_;
- std::string vendor_partition_path_;
- std::string usb_v1_socket_name_;
- std::string kernel_log_socket_name_;
-
- std::string ivshmem_socket_path_;
- int ivshmem_vector_count_;
-
- std::string mobile_bridge_name_;
- std::string entropy_source_;
-
- std::string uuid_;
- bool disable_dac_security_;
- bool disable_app_armor_security_;
-
- GuestConfig(const GuestConfig&) = delete;
- GuestConfig& operator=(const GuestConfig&) = delete;
-};
-
-} // namespace config
diff --git a/host/libs/config/host_config.cpp b/host/libs/config/host_config.cpp
deleted file mode 100644
index df39bb6a..00000000
--- a/host/libs/config/host_config.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 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/config/host_config.h"
-
-#include <cstdlib>
-#include <cstring>
-#include <string>
-#include <iomanip>
-#include <sstream>
-
-#include <gflags/gflags.h>
-
-constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
-
-DEFINE_string(domain, vsoc::GetDefaultShmClientSocketPath(),
- "Path to the ivshmem client socket");
-DEFINE_int32(instance, vsoc::GetDefaultInstance(),
- "Instance number. Must be unique.");
-DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
- "UUID to use for the device. Random if not specified");
-
-int vsoc::GetDefaultInstance() {
- static constexpr char kVsocUserPrefix[] = "vsoc-";
- const char* user = std::getenv("USER");
- if (user && !std::strncmp(user, kVsocUserPrefix,
- sizeof(kVsocUserPrefix) - 1)) {
- int temp = std::atoi(user + sizeof(kVsocUserPrefix) - 1);
- if (temp > 0) {
- return temp;
- }
- }
- return 1;
-}
-
-std::string vsoc::GetPerInstanceDefault(const char* prefix) {
- std::ostringstream stream;
- stream << prefix << std::setfill('0') << std::setw(2)
- << GetDefaultInstance();
- return stream.str();
-}
-
-int vsoc::GetPerInstanceDefault(int base) {
- return base + GetDefaultInstance() - 1;
-}
-
-std::string vsoc::GetDefaultPerInstanceDir() {
- std::ostringstream stream;
- stream << "/var/run/libvirt-" << kDefaultUuidPrefix;
- return vsoc::GetPerInstanceDefault(stream.str().c_str());
-}
-
-std::string vsoc::GetDefaultPerInstancePath(const std::string& basename) {
- std::ostringstream stream;
- stream << GetDefaultPerInstanceDir() << "/" << basename;
- return stream.str();
-}
-
-std::string vsoc::GetDefaultShmClientSocketPath() {
- return vsoc::GetDefaultPerInstancePath("ivshmem_socket_client");
-}
-
-std::string vsoc::GetDomain() {
- return FLAGS_domain;
-}
diff --git a/host/libs/vm_manager/Android.bp b/host/libs/vm_manager/Android.bp
new file mode 100644
index 00000000..1c23f0a8
--- /dev/null
+++ b/host/libs/vm_manager/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2017 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.
+
+cc_library_host_static {
+ name: "libcuttlefish_vm_manager",
+ srcs: [
+ "libvirt_manager.cpp",
+ ],
+ header_libs: [
+ "cuttlefish_glog",
+ ],
+ shared_libs: [
+ "libcuttlefish_fs",
+ "cuttlefish_auto_resources",
+ "libbase",
+ "libicuuc",
+ ],
+ static_libs: [
+ "libxml2",
+ "libgflags",
+ "libcuttlefish_host_config",
+ "libjsoncpp",
+ ],
+ defaults: ["cuttlefish_host_only"],
+} \ No newline at end of file
diff --git a/host/libs/config/guest_config.cpp b/host/libs/vm_manager/libvirt_manager.cpp
index a812966d..6c6f4a1c 100644
--- a/host/libs/config/guest_config.cpp
+++ b/host/libs/vm_manager/libvirt_manager.cpp
@@ -14,41 +14,26 @@
* limitations under the License.
*/
-#include "host/libs/config/guest_config.h"
+#include "host/libs/vm_manager/libvirt_manager.h"
+
+#include <stdio.h>
+#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <libxml/tree.h>
-#include "host/libs/config/host_config.h"
-
-namespace {
-std::string StringFromEnv(const char* varname, std::string defval) {
- const char* const valstr = getenv(varname);
- if (!valstr) {
- return defval;
- }
- return valstr;
-}
-} // namespace
+DEFINE_string(hypervisor_uri, "qemu:///system", "Hypervisor cannonical uri.");
+DEFINE_bool(log_xml, false, "Log the XML machine configuration");
-std::string g_default_libvirt_domain{vsoc::GetPerInstanceDefault("cvd-")};
-//TODO(b/72969289) This should be generated
-DEFINE_string(dtb,
- StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) +
- "/config/cuttlefish.dtb",
- "Location of the cuttlefish.dtb file.");
-DEFINE_string(libvirt_domain, g_default_libvirt_domain.c_str(),
- "Domain name to use with libvirt");
-
-// This class represents libvirt guest configuration.
// A lot of useful information about the document created here can be found on
// these websites:
// - https://libvirt.org/formatdomain.html
// - https://wiki.libvirt.org/page/Virtio
-namespace config {
+namespace vm_manager {
+
namespace {
// This trivial no-op helper function serves purpose of making libxml2 happy.
// Apparently, *most* (not all!) string literals in libxml2 have to be of
@@ -120,7 +105,7 @@ void ConfigureVMFeatures(xmlNode* root,
// This section configures target os (<os>).
void ConfigureOperatingSystem(xmlNode* root, const std::string& kernel,
const std::string& initrd,
- const std::string& args) {
+ const std::string& args, const std::string& dtb) {
auto os = xmlNewChild(root, nullptr, xc("os"), nullptr);
auto type = xmlNewChild(os, nullptr, xc("type"), xc("hvm"));
@@ -130,7 +115,7 @@ void ConfigureOperatingSystem(xmlNode* root, const std::string& kernel,
xmlNewChild(os, nullptr, xc("kernel"), xc(kernel.c_str()));
xmlNewChild(os, nullptr, xc("initrd"), xc(initrd.c_str()));
xmlNewChild(os, nullptr, xc("cmdline"), xc(args.c_str()));
- xmlNewChild(os, nullptr, xc("dtb"), xc(FLAGS_dtb.c_str()));
+ xmlNewChild(os, nullptr, xc("dtb"), xc(dtb.c_str()));
}
// Configure QEmu specific arguments.
@@ -210,7 +195,9 @@ void ConfigureDisk(xmlNode* devices, const std::string& name,
// This section adds <channel> elements to <devices> node.
void ConfigureVirtioChannel(xmlNode* devices, int port, const std::string& name,
DeviceSourceType type, const std::string& path) {
- if (path.empty()) { return; }
+ if (path.empty()) {
+ return;
+ }
auto vch = xmlNewChild(devices, nullptr, xc("channel"), nullptr);
ConfigureDeviceSource(vch, type, path);
@@ -262,14 +249,19 @@ void ConfigureHWRNG(xmlNode* devices, const std::string& entsrc) {
xmlNewProp(bend, xc("model"), xc("random"));
}
-} // namespace
-
-std::string GuestConfig::GetInstanceName() const {
- return FLAGS_libvirt_domain;
+std::string GetLibvirtCommand() {
+ std::string cmd = "virsh";
+ if (!FLAGS_hypervisor_uri.empty()) {
+ cmd += " -c " + FLAGS_hypervisor_uri;
+ }
+ return cmd;
}
-std::string GuestConfig::Build() const {
- std::string instance_name = GetInstanceName();
+} // namespace
+
+std::string LibvirtManager::BuildXmlConfig() const {
+ auto config = vsoc::CuttlefishConfig::Get();
+ std::string instance_name = config->instance_name();
std::unique_ptr<xmlDoc, void (*)(xmlDocPtr)> xml{xmlNewDoc(xc("1.0")),
xmlFreeDoc};
@@ -277,23 +269,27 @@ std::string GuestConfig::Build() const {
xmlDocSetRootElement(xml.get(), root);
xmlNewProp(root, xc("type"), xc("kvm"));
- ConfigureVM(root, instance_name, vcpus_, memory_mb_, uuid_);
+ ConfigureVM(root, instance_name, config->cpus(), config->memory_mb(),
+ config->uuid());
ConfigureVMFeatures(root, {"acpi", "apic", "hap"});
- ConfigureOperatingSystem(root, kernel_name_, initrd_name_, kernel_args_);
+ ConfigureOperatingSystem(root, config->kernel_image_path(),
+ config->ramdisk_image_path(), config->kernel_args(),
+ config->dtb_path());
ConfigureQEmuSpecificOptions(
- root,
- {"-chardev", concat("socket,path=", ivshmem_socket_path_, ",id=ivsocket"),
- "-device",
- concat("ivshmem-doorbell,chardev=ivsocket,vectors=",
- ivshmem_vector_count_),
- "-cpu", "host"});
-
- if (disable_app_armor_security_) {
+ root, {"-chardev",
+ concat("socket,path=", config->ivshmem_qemu_socket_path(),
+ ",id=ivsocket"),
+ "-device",
+ concat("ivshmem-doorbell,chardev=ivsocket,vectors=",
+ config->ivshmem_vector_count()),
+ "-cpu", "host"});
+
+ if (config->disable_app_armor_security()) {
auto seclabel = xmlNewChild(root, nullptr, xc("seclabel"), nullptr);
xmlNewProp(seclabel, xc("type"), xc("none"));
xmlNewProp(seclabel, xc("model"), xc("apparmor"));
}
- if (disable_dac_security_) {
+ if (config->disable_dac_security()) {
auto seclabel = xmlNewChild(root, nullptr, xc("seclabel"), nullptr);
xmlNewProp(seclabel, xc("type"), xc("none"));
xmlNewProp(seclabel, xc("model"), xc("dac"));
@@ -302,30 +298,65 @@ std::string GuestConfig::Build() const {
auto devices = xmlNewChild(root, nullptr, xc("devices"), nullptr);
ConfigureSerialPort(devices, 0, DeviceSourceType::kUnixSocketClient,
- GetKernelLogSocketName());
+ config->kernel_log_socket_name());
ConfigureSerialPort(devices, 1, DeviceSourceType::kUnixSocketServer,
- vsoc::GetDefaultPerInstancePath("console"));
+ config->console_path());
ConfigureVirtioChannel(devices, 1, "cf-logcat", DeviceSourceType::kFile,
- vsoc::GetDefaultPerInstancePath("logcat"));
+ config->logcat_path());
ConfigureVirtioChannel(devices, 2, "cf-gadget-usb-v1",
DeviceSourceType::kUnixSocketClient,
- GetUSBV1SocketName());
+ config->usb_v1_socket_name());
- ConfigureDisk(devices, "vda", system_partition_path_);
- ConfigureDisk(devices, "vdb", data_partition_path_);
- ConfigureDisk(devices, "vdc", cache_partition_path_);
- ConfigureDisk(devices, "vdd", vendor_partition_path_);
+ ConfigureDisk(devices, "vda", config->system_image_path());
+ ConfigureDisk(devices, "vdb", config->data_image_path());
+ ConfigureDisk(devices, "vdc", config->cache_image_path());
+ ConfigureDisk(devices, "vdd", config->vendor_image_path());
- ConfigureNIC(devices, concat("amobile", id_), mobile_bridge_name_, id_, 1);
- ConfigureHWRNG(devices, entropy_source_);
+ ConfigureNIC(devices, config->mobile_tap_name(), config->mobile_bridge_name(),
+ vsoc::GetInstance(), 1);
+ ConfigureHWRNG(devices, config->entropy_source());
xmlChar* tgt;
int tgt_len;
xmlDocDumpFormatMemoryEnc(xml.get(), &tgt, &tgt_len, "utf-8", true);
- std::string out(reinterpret_cast<const char*>(tgt), tgt_len);
+ std::string out((const char*)(tgt), tgt_len);
xmlFree(tgt);
return out;
}
-} // namespace config
+bool LibvirtManager::Start() const {
+ std::string start_command = GetLibvirtCommand();
+ start_command += " create /dev/fd/0";
+
+ std::string xml = BuildXmlConfig();
+ if (FLAGS_log_xml) {
+ LOG(INFO) << "Using XML:\n" << xml;
+ }
+
+ FILE* launch = popen(start_command.c_str(), "w");
+ if (!launch) {
+ LOG(FATAL) << "Unable to execute " << start_command;
+ return false;
+ }
+ int rval = fputs(xml.c_str(), launch);
+ if (rval == EOF) {
+ LOG(FATAL) << "Launch command exited while accepting XML";
+ return false;
+ }
+ int exit_code = pclose(launch);
+ if (exit_code != 0) {
+ LOG(FATAL) << "Launch command exited with status " << exit_code;
+ return false;
+ }
+ return true;
+}
+
+bool LibvirtManager::Stop() const {
+ auto config = vsoc::CuttlefishConfig::Get();
+ auto stop_command = GetLibvirtCommand();
+ stop_command += " destroy " + config->instance_name();
+ return std::system(stop_command.c_str()) == 0;
+}
+
+} // namespace vm_manager
diff --git a/host/libs/config/host_config.h b/host/libs/vm_manager/libvirt_manager.h
index 15d20591..dbe7dcfc 100644
--- a/host/libs/config/host_config.h
+++ b/host/libs/vm_manager/libvirt_manager.h
@@ -1,5 +1,3 @@
-#pragma once
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -15,17 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/* Host-specific values associated with RegionControl. */
+#pragma once
#include <string>
-namespace vsoc {
-int GetDefaultInstance();
-std::string GetPerInstanceDefault(const char* prefix);
-int GetPerInstanceDefault(int base);
-std::string GetDefaultPerInstanceDir();
-std::string GetDefaultPerInstancePath(const std::string& basename);
-std::string GetDefaultShmClientSocketPath();
-std::string GetDomain();
-} // namespace vsoc
+#include "host/libs/config/cuttlefish_config.h"
+
+namespace vm_manager {
+
+class LibvirtManager {
+ public:
+ LibvirtManager() = default;
+ ~LibvirtManager() = default;
+
+ bool Start() const;
+ bool Stop() const;
+
+ protected:
+ std::string BuildXmlConfig() const;
+};
+
+} // namespace vm_manager
diff --git a/host/vsoc/lib/host_region_e2e_test.cpp b/host/vsoc/lib/host_region_e2e_test.cpp
index cab1bc7e..13668381 100644
--- a/host/vsoc/lib/host_region_e2e_test.cpp
+++ b/host/vsoc/lib/host_region_e2e_test.cpp
@@ -20,7 +20,7 @@
#include <gtest/gtest.h>
#include "common/vsoc/lib/e2e_test_region_view.h"
-#include "host/libs/config/host_config.h"
+#include "host/libs/config/cuttlefish_config.h"
// Here is a summary of the two regions interrupt and write test:
// 1. Write our strings to the first region