1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <limits.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <sys/types.h> 21#include <sys/stat.h> 22#include <sys/wait.h> 23#include <unistd.h> 24 25#include <algorithm> 26#include <fstream> 27#include <iomanip> 28#include <memory> 29#include <sstream> 30#include <string> 31#include <vector> 32 33#include <gflags/gflags.h> 34#include <glog/logging.h> 35 36#include "common/libs/fs/shared_select.h" 37#include "common/libs/strings/str_split.h" 38#include "common/vsoc/lib/vsoc_memory.h" 39#include "common/vsoc/shm/screen_layout.h" 40#include "host/commands/launch/pre_launch_initializers.h" 41#include "host/libs/config/cuttlefish_config.h" 42#include "host/libs/ivserver/ivserver.h" 43#include "host/libs/ivserver/options.h" 44#include "host/libs/monitor/kernel_log_server.h" 45#include "host/libs/usbip/server.h" 46#include "host/libs/vadb/virtual_adb_server.h" 47#include "host/libs/vm_manager/libvirt_manager.h" 48 49namespace { 50std::string StringFromEnv(const char* varname, std::string defval) { 51 const char* const valstr = getenv(varname); 52 if (!valstr) { 53 return defval; 54 } 55 return valstr; 56} 57 58std::string DefaultHostArtifactsPath(const char* file_name) { 59 return (StringFromEnv("ANDROID_HOST_OUT", StringFromEnv("HOME", ".")) + "/") + 60 file_name; 61} 62 63} // namespace 64 65using vsoc::GetPerInstanceDefault; 66 67DEFINE_string( 68 system_image, "", 69 "Path to the system image, if empty it is assumed to be a file named " 70 "system.img in the directory specified by -system_image_dir"); 71DEFINE_string(cache_image, "", "Location of the cache partition image."); 72DEFINE_int32(cpus, 2, "Virtual CPU count."); 73DEFINE_string(data_image, "", "Location of the data partition image."); 74DEFINE_string(data_policy, "use_existing", "How to handle userdata partition." 75 " Either 'use_existing', 'create_if_missing', or 'always_create'."); 76DEFINE_int32(blank_data_image_mb, 0, 77 "The size of the blank data image to generate, MB."); 78DEFINE_string(blank_data_image_fmt, "ext4", 79 "The fs format for the blank data image. Used with mkfs."); 80 81DEFINE_int32(x_res, 720, "Width of the screen in pixels"); 82DEFINE_int32(y_res, 1280, "Height of the screen in pixels"); 83DEFINE_int32(dpi, 160, "Pixels per inch for the screen"); 84DEFINE_int32(refresh_rate_hz, 60, "Screen refresh rate in Hertz"); 85DEFINE_int32(num_screen_buffers, 3, "The number of screen buffers"); 86 87DEFINE_bool(disable_app_armor_security, false, 88 "Disable AppArmor security in libvirt. For debug only."); 89DEFINE_bool(disable_dac_security, false, 90 "Disable DAC security in libvirt. For debug only."); 91DEFINE_string(extra_kernel_command_line, "", 92 "Additional flags to put on the kernel command line"); 93DEFINE_string(initrd, "", "Location of cuttlefish initrd file."); 94DEFINE_string(kernel, "", "Location of cuttlefish kernel file."); 95DEFINE_string(kernel_command_line, "", 96 "Location of a text file with the kernel command line."); 97DEFINE_int32(memory_mb, 2048, 98 "Total amount of memory available for guest, MB."); 99std::string g_default_mempath{GetPerInstanceDefault("/var/run/shm/cvd-")}; 100DEFINE_string(mempath, g_default_mempath.c_str(), 101 "Target location for the shmem file."); 102std::string g_default_mobile_interface{GetPerInstanceDefault("cvd-mobile-")}; 103DEFINE_string(mobile_interface, g_default_mobile_interface.c_str(), 104 "Network interface to use for mobile networking"); 105DEFINE_string(mobile_tap_name, GetPerInstanceDefault("amobile"), 106 "The name of the tap interface to use for mobile"); 107std::string g_default_serial_number{GetPerInstanceDefault("CUTTLEFISHCVD")}; 108DEFINE_string(serial_number, g_default_serial_number.c_str(), 109 "Serial number to use for the device"); 110DEFINE_string(instance_dir, vsoc::GetDefaultPerInstanceDir(), 111 "A directory to put all instance specific files"); 112DEFINE_string(system_image_dir, 113 StringFromEnv("ANDROID_PRODUCT_OUT", StringFromEnv("HOME", ".")), 114 "Location of the system partition images."); 115DEFINE_string(vendor_image, "", "Location of the vendor partition image."); 116 117DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to" 118 " host kernel. This is only used during transition of our clients." 119 " Will be deprecated soon."); 120DEFINE_bool(start_vnc_server, true, "Whether to start the vnc server process."); 121DEFINE_string(vnc_server_binary, 122 DefaultHostArtifactsPath("/bin/vnc_server"), 123 "Location of the vnc server binary."); 124DEFINE_int32(vnc_server_port, GetPerInstanceDefault(6444), 125 "The port on which the vnc server should listen"); 126DEFINE_string(socket_forward_proxy_binary, 127 DefaultHostArtifactsPath("/bin/socket_forward_proxy"), 128 "Location of the socket_forward_proxy binary."); 129DEFINE_string(adb_mode, "tunnel", 130 "Mode for adb connection. Can be usb for usb forwarding, or " 131 "tunnel for tcp connection. If using tunnel, you may have to " 132 "run 'adb kill-server' to get the device to show up."); 133DEFINE_int32(vhci_port, GetPerInstanceDefault(0), "VHCI port to use for usb"); 134DEFINE_string(guest_mac_address, 135 GetPerInstanceDefault("00:43:56:44:80:"), // 00:43:56:44:80:0x 136 "MAC address of the wifi interface to be created on the guest."); 137DEFINE_string(host_mac_address, 138 "42:00:00:00:00:00", 139 "MAC address of the wifi interface running on the host."); 140DEFINE_bool(start_wifi_relay, true, "Whether to start the wifi_relay process."); 141DEFINE_string(wifi_relay_binary, 142 DefaultHostArtifactsPath("/bin/wifi_relay"), 143 "Location of the wifi_relay binary."); 144std::string g_default_wifi_interface{GetPerInstanceDefault("cvd-wifi-")}; 145DEFINE_string(wifi_interface, g_default_wifi_interface.c_str(), 146 "Network interface to use for wifi"); 147// TODO(b/72969289) This should be generated 148DEFINE_string(dtb, DefaultHostArtifactsPath("config/cuttlefish.dtb"), 149 "Path to the cuttlefish.dtb file"); 150 151constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1"; 152DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(), 153 "UUID to use for the device. Random if not specified"); 154 155DECLARE_string(config_file); 156 157namespace { 158const std::string kDataPolicyUseExisting = "use_existing"; 159const std::string kDataPolicyCreateIfMissing = "create_if_missing"; 160const std::string kDataPolicyAlwaysCreate = "always_create"; 161 162constexpr char kAdbModeTunnel[] = "tunnel"; 163constexpr char kAdbModeUsb[] = "usb"; 164 165// VirtualUSBManager manages virtual USB device presence for Cuttlefish. 166class VirtualUSBManager { 167 public: 168 VirtualUSBManager(const std::string& usbsocket, int vhci_port, 169 const std::string& android_usbipsocket) 170 : adb_{usbsocket, vhci_port, android_usbipsocket}, 171 usbip_{android_usbipsocket, adb_.Pool()} {} 172 173 ~VirtualUSBManager() = default; 174 175 // Initialize Virtual USB and start USB management thread. 176 void Start() { 177 CHECK(adb_.Init()) << "Could not initialize Virtual ADB server"; 178 CHECK(usbip_.Init()) << "Could not start USB/IP server"; 179 std::thread([this] { Thread(); }).detach(); 180 } 181 182 private: 183 void Thread() { 184 for (;;) { 185 cvd::SharedFDSet fd_read; 186 fd_read.Zero(); 187 188 adb_.BeforeSelect(&fd_read); 189 usbip_.BeforeSelect(&fd_read); 190 191 int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr); 192 if (ret <= 0) continue; 193 194 adb_.AfterSelect(fd_read); 195 usbip_.AfterSelect(fd_read); 196 } 197 } 198 199 vadb::VirtualADBServer adb_; 200 vadb::usbip::Server usbip_; 201 202 VirtualUSBManager(const VirtualUSBManager&) = delete; 203 VirtualUSBManager& operator=(const VirtualUSBManager&) = delete; 204}; 205 206// IVServerManager takes care of serving shared memory segments between 207// Cuttlefish and host-side daemons. 208class IVServerManager { 209 public: 210 IVServerManager(const std::string& mempath, const std::string& qemu_socket) 211 : server_(ivserver::IVServerOptions(mempath, qemu_socket, 212 vsoc::GetDomain())) {} 213 214 ~IVServerManager() = default; 215 216 // Start IVServer thread. 217 void Start() { 218 std::thread([this] { server_.Serve(); }).detach(); 219 } 220 221 private: 222 ivserver::IVServer server_; 223 224 IVServerManager(const IVServerManager&) = delete; 225 IVServerManager& operator=(const IVServerManager&) = delete; 226}; 227 228// KernelLogMonitor receives and monitors kernel log for Cuttlefish. 229class KernelLogMonitor { 230 public: 231 KernelLogMonitor(const std::string& socket_name, 232 const std::string& log_name, 233 bool deprecated_boot_completed) 234 : klog_{socket_name, log_name, deprecated_boot_completed} {} 235 236 ~KernelLogMonitor() = default; 237 238 void Start() { 239 CHECK(klog_.Init()) << "Could not initialize kernel log server"; 240 std::thread([this] { Thread(); }).detach(); 241 } 242 243 private: 244 void Thread() { 245 for (;;) { 246 cvd::SharedFDSet fd_read; 247 fd_read.Zero(); 248 249 klog_.BeforeSelect(&fd_read); 250 251 int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr); 252 if (ret <= 0) continue; 253 254 klog_.AfterSelect(fd_read); 255 } 256 } 257 258 monitor::KernelLogServer klog_; 259 260 KernelLogMonitor(const KernelLogMonitor&) = delete; 261 KernelLogMonitor& operator=(const KernelLogMonitor&) = delete; 262}; 263 264void subprocess(const char* const* command, 265 const char* const* envp, 266 bool wait_for_child = true) { 267 pid_t pid = fork(); 268 if (!pid) { 269 int rval; 270 // If envp is NULL, the current process's environment is used as the 271 // environment of the child process. To force an empty emvironment for the 272 // child process pass the address of a pointer to NULL 273 if (envp == NULL) { 274 rval = execv(command[0], const_cast<char* const*>(command)); 275 } else { 276 rval = execve(command[0], const_cast<char* const*>(command), 277 const_cast<char* const*>(envp)); 278 } 279 // No need for an if: if exec worked it wouldn't have returned 280 LOG(ERROR) << "exec of " << command[0] << " failed (" << strerror(errno) 281 << ")"; 282 exit(rval); 283 } 284 if (pid == -1) { 285 LOG(ERROR) << "fork of " << command[0] << " failed (" << strerror(errno) 286 << ")"; 287 } 288 if (pid > 0) { 289 if (wait_for_child) { 290 waitpid(pid, 0, 0); 291 } else { 292 LOG(INFO) << "Started " << command[0] << ", pid: " << pid; 293 } 294 } 295} 296 297bool FileExists(const char* path) { 298 struct stat unused; 299 return stat(path, &unused) != -1 || errno != ENOENT; 300} 301 302void CreateBlankImage( 303 const std::string& image, int image_mb, const std::string& image_fmt) { 304 LOG(INFO) << "Creating " << image; 305 std::string of = "of="; 306 of += image; 307 std::string count = "count="; 308 count += std::to_string(image_mb); 309 const char* dd_command[]{ 310 "/bin/dd", "if=/dev/zero", of.c_str(), "bs=1M", count.c_str(), NULL}; 311 subprocess(dd_command, NULL); 312 const char* mkfs_command[]{ 313 "/sbin/mkfs", "-t", image_fmt.c_str(), image.c_str(), NULL}; 314 const char* envp[]{"PATH=/sbin", NULL}; 315 subprocess(mkfs_command, envp); 316} 317 318void RemoveFile(const std::string& file) { 319 LOG(INFO) << "Removing " << file; 320 const char* rm_command[]{ 321 "/bin/rm", "-f", file.c_str(), NULL}; 322 subprocess(rm_command, NULL); 323} 324 325bool ApplyDataImagePolicy(const char* data_image) { 326 bool data_exists = FileExists(data_image); 327 bool remove{}; 328 bool create{}; 329 330 if (FLAGS_data_policy == kDataPolicyUseExisting) { 331 if (!data_exists) { 332 LOG(FATAL) << "Specified data image file does not exists: " << data_image; 333 return false; 334 } 335 if (FLAGS_blank_data_image_mb > 0) { 336 LOG(FATAL) << "You should NOT use -blank_data_image_mb with -data_policy=" 337 << kDataPolicyUseExisting; 338 return false; 339 } 340 create = false; 341 remove = false; 342 } else if (FLAGS_data_policy == kDataPolicyAlwaysCreate) { 343 remove = data_exists; 344 create = true; 345 } else if (FLAGS_data_policy == kDataPolicyCreateIfMissing) { 346 create = !data_exists; 347 remove = false; 348 } else { 349 LOG(FATAL) << "Invalid data_policy: " << FLAGS_data_policy; 350 } 351 352 if (remove) { 353 RemoveFile(data_image); 354 } 355 356 if (create) { 357 if (FLAGS_blank_data_image_mb <= 0) { 358 LOG(FATAL) << "-blank_data_image_mb is required to create data image"; 359 } 360 CreateBlankImage( 361 data_image, FLAGS_blank_data_image_mb, FLAGS_blank_data_image_fmt); 362 } else { 363 LOG(INFO) << data_image << " exists. Not creating it."; 364 } 365 366 return true; 367} 368 369bool EnsureDirExists(const char* dir) { 370 if (!FileExists(dir)) { 371 LOG(INFO) << "Setting up " << dir; 372 if (mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0) { 373 if (errno == EACCES) { 374 // TODO(79170615) Don't use sudo once libvirt is replaced 375 LOG(WARNING) << "Not enough permission to create " << dir 376 << " retrying with sudo"; 377 const char* mkdir_command[]{"/usr/bin/sudo", "/bin/mkdir", "-m", 378 "0775", dir, NULL}; 379 subprocess(mkdir_command, NULL); 380 381 // When created with sudo the owner and group is root. 382 std::string user_group = getenv("USER"); 383 user_group += ":libvirt-qemu"; 384 const char* chown_cmd[] = {"/usr/bin/sudo", "/bin/chown", 385 user_group.c_str(), dir, NULL}; 386 subprocess(chown_cmd, NULL); 387 } else { 388 LOG(FATAL) << "Unable to create " << dir << ". Error: " << errno; 389 return false; 390 } 391 } 392 } 393 return true; 394} 395 396std::string GetConfigFile() { 397 return vsoc::CuttlefishConfig::Get()->PerInstancePath( 398 "cuttlefish_config.json"); 399} 400 401std::string GetConfigFileArg() { return "-config_file=" + GetConfigFile(); } 402 403std::string GetGuestPortArg() { 404 constexpr int kEmulatorPort = 5555; 405 return std::string{"--guest_ports="} + std::to_string(kEmulatorPort); 406} 407 408std::string GetHostPortArg() { 409 constexpr int kFirstHostPort = 6520; 410 return std::string{"--host_ports="} + 411 std::to_string(vsoc::GetPerInstanceDefault(kFirstHostPort)); 412} 413 414void ValidateAdbModeFlag() { 415 CHECK(FLAGS_adb_mode == kAdbModeUsb || 416 FLAGS_adb_mode == kAdbModeTunnel) << "invalid --adb_mode"; 417} 418 419bool AdbTunnelEnabled() { 420 return FLAGS_adb_mode == kAdbModeTunnel; 421} 422 423bool AdbUsbEnabled() { 424 return FLAGS_adb_mode == kAdbModeUsb; 425} 426 427void LaunchSocketForwardProxyIfEnabled() { 428 if (AdbTunnelEnabled()) { 429 auto guest_port_arg = GetGuestPortArg(); 430 auto host_port_arg = GetHostPortArg(); 431 auto config_arg = GetConfigFileArg(); 432 433 const char* const socket_proxy[] = { 434 FLAGS_socket_forward_proxy_binary.c_str(), 435 guest_port_arg.c_str(), 436 host_port_arg.c_str(), 437 config_arg.c_str(), 438 NULL 439 }; 440 subprocess(socket_proxy, nullptr, false); 441 } 442} 443 444void LaunchVNCServerIfEnabled() { 445 if (FLAGS_start_vnc_server) { 446 // Launch the vnc server, don't wait for it to complete 447 auto port_options = "-port=" + std::to_string(FLAGS_vnc_server_port); 448 auto config_arg = GetConfigFileArg(); 449 const char* vnc_command[] = { 450 FLAGS_vnc_server_binary.c_str(), 451 port_options.c_str(), 452 config_arg.c_str(), 453 NULL 454 }; 455 subprocess(vnc_command, NULL, false); 456 } 457} 458 459void LaunchWifiRelayIfEnabled() { 460 if (FLAGS_start_wifi_relay) { 461 // Launch the wifi relay, don't wait for it to complete 462 auto config_arg = GetConfigFileArg(); 463 const char* relay_command[] = { 464 "/usr/bin/sudo", 465 "-E", 466 FLAGS_wifi_relay_binary.c_str(), 467 config_arg.c_str(), 468 NULL 469 }; 470 471 subprocess(relay_command, NULL /* envp */, false /* wait_for_child */); 472 } 473} 474bool ResolveInstanceFiles() { 475 if (FLAGS_system_image_dir.empty()) { 476 LOG(FATAL) << "--system_image_dir must be specified."; 477 return false; 478 } 479 480 // If user did not specify location of either of these files, expect them to 481 // be placed in --system_image_dir location. 482 if (FLAGS_kernel.empty()) { 483 FLAGS_kernel = FLAGS_system_image_dir + "/kernel"; 484 } 485 if (FLAGS_kernel_command_line.empty()) { 486 FLAGS_kernel_command_line = FLAGS_system_image_dir + "/cmdline"; 487 } 488 if (FLAGS_system_image.empty()) { 489 FLAGS_system_image = FLAGS_system_image_dir + "/system.img"; 490 } 491 if (FLAGS_initrd.empty()) { 492 FLAGS_initrd = FLAGS_system_image_dir + "/ramdisk.img"; 493 } 494 if (FLAGS_cache_image.empty()) { 495 FLAGS_cache_image = FLAGS_system_image_dir + "/cache.img"; 496 } 497 if (FLAGS_data_image.empty()) { 498 FLAGS_data_image = FLAGS_system_image_dir + "/userdata.img"; 499 } 500 if (FLAGS_vendor_image.empty()) { 501 FLAGS_vendor_image = FLAGS_system_image_dir + "/vendor.img"; 502 } 503 504 // Create data if necessary 505 if (!ApplyDataImagePolicy(FLAGS_data_image.c_str())) { 506 return false; 507 } 508 509 // Check that the files exist 510 for (const auto& file : 511 {FLAGS_system_image, FLAGS_vendor_image, FLAGS_cache_image, FLAGS_kernel, 512 FLAGS_initrd, FLAGS_data_image, FLAGS_kernel_command_line}) { 513 if (!FileExists(file.c_str())) { 514 LOG(FATAL) << "File not found: " << file; 515 return false; 516 } 517 } 518 return true; 519} 520 521bool SetUpGlobalConfiguration() { 522 if (!ResolveInstanceFiles()) { 523 return false; 524 } 525 auto& memory_layout = *vsoc::VSoCMemoryLayout::Get(); 526 auto config = vsoc::CuttlefishConfig::Get(); 527 // Set this first so that calls to PerInstancePath below are correct 528 config->set_instance_dir(FLAGS_instance_dir); 529 if (!EnsureDirExists(FLAGS_instance_dir.c_str())) { 530 return false; 531 } 532 533 config->set_serial_number(FLAGS_serial_number); 534 535 config->set_cpus(FLAGS_cpus); 536 config->set_memory_mb(FLAGS_memory_mb); 537 538 config->set_dpi(FLAGS_dpi); 539 config->set_x_res(FLAGS_x_res); 540 config->set_y_res(FLAGS_y_res); 541 config->set_refresh_rate_hz(FLAGS_refresh_rate_hz); 542 543 config->set_kernel_image_path(FLAGS_kernel); 544 std::ostringstream extra_cmdline; 545 extra_cmdline << " androidboot.serialno=" << FLAGS_serial_number; 546 extra_cmdline << " androidboot.lcd_density=" << FLAGS_dpi; 547 if (FLAGS_extra_kernel_command_line.size()) { 548 extra_cmdline << " " << FLAGS_extra_kernel_command_line; 549 } 550 config->ReadKernelArgs(FLAGS_kernel_command_line.c_str(), 551 extra_cmdline.str()); 552 553 config->set_ramdisk_image_path(FLAGS_initrd); 554 config->set_system_image_path(FLAGS_system_image); 555 config->set_cache_image_path(FLAGS_cache_image); 556 config->set_data_image_path(FLAGS_data_image); 557 config->set_vendor_image_path(FLAGS_vendor_image); 558 config->set_dtb_path(FLAGS_dtb); 559 560 config->set_mempath(FLAGS_mempath); 561 config->set_ivshmem_qemu_socket_path( 562 config->PerInstancePath("ivshmem_socket_qemu")); 563 config->set_ivshmem_client_socket_path( 564 config->PerInstancePath("ivshmem_socket_client")); 565 config->set_ivshmem_vector_count(memory_layout.GetRegions().size()); 566 567 config->set_usb_v1_socket_name(config->PerInstancePath("usb-v1")); 568 config->set_vhci_port(FLAGS_vhci_port); 569 config->set_usb_ip_socket_name(config->PerInstancePath("usb-ip")); 570 571 config->set_kernel_log_socket_name(config->PerInstancePath("kernel-log")); 572 config->set_console_path(config->PerInstancePath("console")); 573 config->set_logcat_path(config->PerInstancePath("logcat")); 574 575 config->set_mobile_bridge_name(FLAGS_mobile_interface); 576 config->set_mobile_tap_name(FLAGS_mobile_tap_name); 577 578 config->set_wifi_guest_mac_addr(FLAGS_guest_mac_address); 579 config->set_wifi_host_mac_addr(FLAGS_host_mac_address); 580 581 config->set_entropy_source("/dev/urandom"); 582 config->set_uuid(FLAGS_uuid); 583 584 config->set_disable_dac_security(FLAGS_disable_dac_security); 585 config->set_disable_app_armor_security(FLAGS_disable_app_armor_security); 586 587 if(!AdbUsbEnabled()) { 588 config->disable_usb_adb(); 589 } 590 591 return true; 592} 593 594} // anonymous namespace 595 596namespace launch_cvd { 597void ParseCommandLineFlags(int argc, char** argv) { 598 // The config_file is created by the launcher, so the launcher is the only 599 // host process that doesn't use the flag. 600 // Set the default to empty. 601 google::SetCommandLineOptionWithMode("config_file", "", 602 gflags::SET_FLAGS_DEFAULT); 603 google::ParseCommandLineFlags(&argc, &argv, true); 604 // Set the flag value to empty (in case the caller passed a value for it). 605 FLAGS_config_file = ""; 606 607 ValidateAdbModeFlag(); 608} 609} // namespace launch_cvd 610 611int main(int argc, char** argv) { 612 ::android::base::InitLogging(argv, android::base::StderrLogger); 613 launch_cvd::ParseCommandLineFlags(argc, argv); 614 615 // Do this early so that the config object is ready for anything that needs it 616 if (!SetUpGlobalConfiguration()) { 617 return -1; 618 } 619 620 auto& memory_layout = *vsoc::VSoCMemoryLayout::Get(); 621 // TODO(b/79170615) These values need to go to the config object/file and the 622 // region resizing be done by the ivserver process (or maybe the config 623 // library to ensure all processes have the correct value?) 624 size_t screen_region_size = 625 memory_layout 626 .GetRegionByName(vsoc::layout::screen::ScreenLayout::region_name) 627 ->region_size(); 628 auto actual_width = ((FLAGS_x_res * 4) + 15) & ~15; // aligned to 16 629 screen_region_size += FLAGS_num_screen_buffers * 630 (actual_width * FLAGS_y_res + 16 /* padding */); 631 screen_region_size += (FLAGS_num_screen_buffers - 1) * 4096; /* Guard pages */ 632 memory_layout.ResizeRegion(vsoc::layout::screen::ScreenLayout::region_name, 633 screen_region_size); 634 // TODO(b/79170615) Resize gralloc region too. 635 636 637 auto config = vsoc::CuttlefishConfig::Get(); 638 // Save the config object before starting any host process 639 if (!config->SaveToFile(GetConfigFile())) { 640 return -1; 641 } 642 643 // Start the usb manager 644 VirtualUSBManager vadb(config->usb_v1_socket_name(), config->vhci_port(), 645 config->usb_ip_socket_name()); 646 vadb.Start(); 647 648 // Start IVServer 649 IVServerManager ivshmem(config->mempath(), config->ivshmem_qemu_socket_path()); 650 ivshmem.Start(); 651 652 KernelLogMonitor kmon(config->kernel_log_socket_name(), 653 config->PerInstancePath("kernel.log"), 654 FLAGS_deprecated_boot_completed); 655 kmon.Start(); 656 657 // Initialize the regions that require so before the VM starts. 658 PreLaunchInitializers::Initialize(); 659 660 // Start the guest VM 661 vm_manager::LibvirtManager libvirt; 662 if (!libvirt.Start()) { 663 LOG(FATAL) << "Unable to start libvirt"; 664 return -1; 665 } 666 667 LaunchSocketForwardProxyIfEnabled(); 668 LaunchVNCServerIfEnabled(); 669 LaunchWifiRelayIfEnabled(); 670 671 pause(); 672} 673