• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 "host/libs/vm_manager/qemu_manager.h"
18 
19 #include <string.h>
20 #include <sys/socket.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <sys/un.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 
27 #include <cstdlib>
28 #include <sstream>
29 #include <string>
30 #include <thread>
31 #include <vector>
32 
33 #include <glog/logging.h>
34 
35 #include "common/libs/fs/shared_select.h"
36 #include "common/libs/utils/files.h"
37 #include "common/libs/utils/subprocess.h"
38 #include "common/libs/utils/users.h"
39 #include "host/libs/config/cuttlefish_config.h"
40 
41 namespace vm_manager {
42 
43 namespace {
44 
GetMonitorPath(const vsoc::CuttlefishConfig * config)45 std::string GetMonitorPath(const vsoc::CuttlefishConfig* config) {
46   return config->PerInstancePath("qemu_monitor.sock");
47 }
48 
LogAndSetEnv(const char * key,const std::string & value)49 void LogAndSetEnv(const char* key, const std::string& value) {
50   setenv(key, value.c_str(), 1);
51   LOG(INFO) << key << "=" << value;
52 }
53 
54 }  // namespace
55 
name()56 const std::string QemuManager::name() { return "qemu_cli"; }
57 
ConfigureBootDevices(vsoc::CuttlefishConfig * config)58 void QemuManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
59   // PCI domain 0, bus 0, device 3, function 0
60   // This is controlled with 'addr=0x3' in cf_qemu.sh
61   config->add_kernel_cmdline(
62     "androidboot.boot_devices=pci0000:00/0000:00:03.0");
63 }
64 
QemuManager(const vsoc::CuttlefishConfig * config)65 QemuManager::QemuManager(const vsoc::CuttlefishConfig* config)
66   : VmManager(config) {}
67 
StartCommand()68 cvd::Command QemuManager::StartCommand(){
69   // Set the config values in the environment
70   LogAndSetEnv("qemu_binary", config_->qemu_binary());
71   LogAndSetEnv("instance_name", config_->instance_name());
72   LogAndSetEnv("memory_mb", std::to_string(config_->memory_mb()));
73   LogAndSetEnv("cpus", std::to_string(config_->cpus()));
74   LogAndSetEnv("uuid", config_->uuid());
75   LogAndSetEnv("monitor_path", GetMonitorPath(config_));
76   LogAndSetEnv("kernel_image_path", config_->GetKernelImageToUse());
77   LogAndSetEnv("gdb_flag", config_->gdb_flag());
78   LogAndSetEnv("ramdisk_image_path", config_->ramdisk_image_path());
79   LogAndSetEnv("kernel_cmdline", config_->kernel_cmdline_as_string());
80   LogAndSetEnv("dtb_path", config_->dtb_path());
81   LogAndSetEnv("system_image_path", config_->system_image_path());
82   LogAndSetEnv("data_image_path", config_->data_image_path());
83   LogAndSetEnv("cache_image_path", config_->cache_image_path());
84   LogAndSetEnv("vendor_image_path", config_->vendor_image_path());
85   LogAndSetEnv("metadata_image_path", config_->metadata_image_path());
86   LogAndSetEnv("product_image_path", config_->product_image_path());
87   LogAndSetEnv("super_image_path", config_->super_image_path());
88   LogAndSetEnv("wifi_tap_name", config_->wifi_tap_name());
89   LogAndSetEnv("mobile_tap_name", config_->mobile_tap_name());
90   LogAndSetEnv("kernel_log_socket_name",
91                       config_->kernel_log_socket_name());
92   LogAndSetEnv("console_path", config_->console_path());
93   LogAndSetEnv("logcat_path", config_->logcat_path());
94   LogAndSetEnv("ivshmem_qemu_socket_path",
95                       config_->ivshmem_qemu_socket_path());
96   LogAndSetEnv("ivshmem_vector_count",
97                       std::to_string(config_->ivshmem_vector_count()));
98   LogAndSetEnv("usb_v1_socket_name", config_->usb_v1_socket_name());
99   LogAndSetEnv("vsock_guest_cid", std::to_string(config_->vsock_guest_cid()));
100   LogAndSetEnv("logcat_mode", config_->logcat_mode());
101 
102   cvd::Command qemu_cmd(vsoc::DefaultHostArtifactsPath("bin/cf_qemu.sh"));
103   return qemu_cmd;
104 }
Stop()105 bool QemuManager::Stop() {
106   auto monitor_path = GetMonitorPath(config_);
107   auto monitor_sock = cvd::SharedFD::SocketLocalClient(
108       monitor_path.c_str(), false, SOCK_STREAM);
109 
110   if (!monitor_sock->IsOpen()) {
111     LOG(ERROR) << "The connection to qemu is closed, is it still running?";
112     return false;
113   }
114   char msg[] = "{\"execute\":\"qmp_capabilities\"}{\"execute\":\"quit\"}";
115   ssize_t len = sizeof(msg) - 1;
116   while (len > 0) {
117     int tmp = monitor_sock->Write(msg, len);
118     if (tmp < 0) {
119       LOG(ERROR) << "Error writing to socket: " << monitor_sock->StrError();
120       return false;
121     }
122     len -= tmp;
123   }
124   // Log the reply
125   char buff[1000];
126   while ((len = monitor_sock->Read(buff, sizeof(buff) - 1)) > 0) {
127     buff[len] = '\0';
128     LOG(INFO) << "From qemu monitor: " << buff;
129   }
130 
131   return true;
132 }
133 
134 }  // namespace vm_manager
135