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