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/config/cuttlefish_config.h" 18 19 #include <climits> 20 #include <cstdlib> 21 #include <cstring> 22 #include <fstream> 23 #include <iomanip> 24 #include <sstream> 25 #include <string> 26 27 #include <gflags/gflags.h> 28 #include <glog/logging.h> 29 #include <json/json.h> 30 31 DEFINE_string(config_file, 32 vsoc::GetDefaultPerInstanceDir() + "/cuttlefish_config.json", 33 "A file from where to load the config values. This flag is " 34 "ignored by the launcher"); 35 36 namespace { 37 38 constexpr char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1"; 39 40 int InstanceFromEnvironment() { 41 static constexpr char kInstanceEnvironmentVariable[] = "CUTTLEFISH_INSTANCE"; 42 static constexpr char kVsocUserPrefix[] = "vsoc-"; 43 static constexpr int kDefaultInstance = 1; 44 45 // CUTTLEFISH_INSTANCE environment variable 46 const char* instance_str = std::getenv(kInstanceEnvironmentVariable); 47 if (!instance_str) { 48 // Try to get it from the user instead 49 instance_str = std::getenv("USER"); 50 if (!instance_str || std::strncmp(instance_str, kVsocUserPrefix, 51 sizeof(kVsocUserPrefix) - 1)) { 52 // No user or we don't recognize this user 53 return kDefaultInstance; 54 } 55 instance_str += sizeof(kVsocUserPrefix) - 1; 56 // Set the environment variable so that child processes see it 57 setenv(kInstanceEnvironmentVariable, instance_str, 0); 58 } 59 60 int instance = std::atoi(instance_str); 61 if (instance <= 0) { 62 instance = kDefaultInstance; 63 } 64 65 return instance; 66 } 67 const char* kSerialNumber = "serial_number"; 68 const char* kInstanceDir = "instance_dir"; 69 70 const char* kCpus = "cpus"; 71 const char* kMemoryMb = "memory_mb"; 72 const char* kDpi = "dpi"; 73 const char* kXRes = "x_res"; 74 const char* kYRes = "y_res"; 75 const char* kRefreshRateHz = "refresh_rate_hz"; 76 77 const char* kKernelImagePath = "kernel_image_path"; 78 const char* kKernelArgs = "kernel_args"; 79 const char* kRamdiskImagePath = "ramdisk_image_path"; 80 81 const char* kSystemImagePath = "system_image_path"; 82 const char* kCacheImagePath = "cache_image_path"; 83 const char* kDataImagePath = "data_image_path"; 84 const char* kVendorImagePath = "vendor_image_path"; 85 const char* kUsbV1SocketName = "usb_v1_socket_name"; 86 const char* kVhciPort = "vhci_port"; 87 const char* kUsbIpSocketName = "usb_ip_socket_name"; 88 const char* kKernelLogSocketName = "kernel_log_socket_name"; 89 const char* kConsolePath = "console_path"; 90 const char* kLogcatPath = "logcat_path"; 91 const char* kDtbPath = "dtb_path"; 92 93 const char* kMempath = "mempath"; 94 const char* kIvshmemQemuSocketPath = "ivshmem_qemu_socket_path"; 95 const char* kIvshmemClientSocketPath = "ivshmem_client_socket_path"; 96 const char* kIvshmemVectorCount = "ivshmem_vector_count"; 97 98 const char* kMobileBridgeName = "mobile_bridge_name"; 99 const char* kMobileTapName = "mobile_tap_name"; 100 const char* kWifiGuestMacAddr = "wifi_guest_mac_addr"; 101 const char* kWifiHostMacAddr = "wifi_host_mac_addr"; 102 const char* kEntropySource = "entropy_source"; 103 104 const char* kUuid = "uuid"; 105 const char* kDisableDacSecurity = "disable_dac_security"; 106 const char* kDisableAppArmorSecurity = "disable_app_armor_security"; 107 } // namespace 108 109 namespace vsoc { 110 111 std::string CuttlefishConfig::instance_dir() const { 112 return (*dictionary_)[kInstanceDir].asString(); 113 } 114 void CuttlefishConfig::set_instance_dir(const std::string& instance_dir) { 115 (*dictionary_)[kInstanceDir] = instance_dir; 116 } 117 118 std::string CuttlefishConfig::serial_number() const { 119 return (*dictionary_)[kSerialNumber].asString(); 120 } 121 void CuttlefishConfig::set_serial_number(const std::string& serial_number) { 122 (*dictionary_)[kSerialNumber] = serial_number; 123 } 124 125 int CuttlefishConfig::cpus() const { return (*dictionary_)[kCpus].asInt(); } 126 void CuttlefishConfig::set_cpus(int cpus) { (*dictionary_)[kCpus] = cpus; } 127 128 int CuttlefishConfig::memory_mb() const { 129 return (*dictionary_)[kMemoryMb].asInt(); 130 } 131 void CuttlefishConfig::set_memory_mb(int memory_mb) { 132 (*dictionary_)[kMemoryMb] = memory_mb; 133 } 134 135 int CuttlefishConfig::dpi() const { return (*dictionary_)[kDpi].asInt(); } 136 void CuttlefishConfig::set_dpi(int dpi) { (*dictionary_)[kDpi] = dpi; } 137 138 int CuttlefishConfig::x_res() const { return (*dictionary_)[kXRes].asInt(); } 139 void CuttlefishConfig::set_x_res(int x_res) { (*dictionary_)[kXRes] = x_res; } 140 141 int CuttlefishConfig::y_res() const { return (*dictionary_)[kYRes].asInt(); } 142 void CuttlefishConfig::set_y_res(int y_res) { (*dictionary_)[kYRes] = y_res; } 143 144 int CuttlefishConfig::refresh_rate_hz() const { 145 return (*dictionary_)[kRefreshRateHz].asInt(); 146 } 147 void CuttlefishConfig::set_refresh_rate_hz(int refresh_rate_hz) { 148 (*dictionary_)[kRefreshRateHz] = refresh_rate_hz; 149 } 150 151 std::string CuttlefishConfig::kernel_image_path() const { 152 return (*dictionary_)[kKernelImagePath].asString(); 153 } 154 void CuttlefishConfig::set_kernel_image_path( 155 const std::string& kernel_image_path) { 156 (*dictionary_)[kKernelImagePath] = kernel_image_path; 157 } 158 159 std::string CuttlefishConfig::kernel_args() const { 160 return (*dictionary_)[kKernelArgs].asString(); 161 } 162 void CuttlefishConfig::set_kernel_args(const std::string& kernel_args) { 163 (*dictionary_)[kKernelArgs] = kernel_args; 164 } 165 166 std::string CuttlefishConfig::ramdisk_image_path() const { 167 return (*dictionary_)[kRamdiskImagePath].asString(); 168 } 169 void CuttlefishConfig::set_ramdisk_image_path( 170 const std::string& ramdisk_image_path) { 171 (*dictionary_)[kRamdiskImagePath] = ramdisk_image_path; 172 } 173 174 std::string CuttlefishConfig::system_image_path() const { 175 return (*dictionary_)[kSystemImagePath].asString(); 176 } 177 void CuttlefishConfig::set_system_image_path( 178 const std::string& system_image_path) { 179 (*dictionary_)[kSystemImagePath] = system_image_path; 180 } 181 182 std::string CuttlefishConfig::cache_image_path() const { 183 return (*dictionary_)[kCacheImagePath].asString(); 184 } 185 void CuttlefishConfig::set_cache_image_path( 186 const std::string& cache_image_path) { 187 (*dictionary_)[kCacheImagePath] = cache_image_path; 188 } 189 190 std::string CuttlefishConfig::data_image_path() const { 191 return (*dictionary_)[kDataImagePath].asString(); 192 } 193 void CuttlefishConfig::set_data_image_path(const std::string& data_image_path) { 194 (*dictionary_)[kDataImagePath] = data_image_path; 195 } 196 197 std::string CuttlefishConfig::vendor_image_path() const { 198 return (*dictionary_)[kVendorImagePath].asString(); 199 } 200 void CuttlefishConfig::set_vendor_image_path( 201 const std::string& vendor_image_path) { 202 (*dictionary_)[kVendorImagePath] = vendor_image_path; 203 } 204 205 std::string CuttlefishConfig::dtb_path() const { 206 return (*dictionary_)[kDtbPath].asString(); 207 } 208 void CuttlefishConfig::set_dtb_path(const std::string& dtb_path) { 209 (*dictionary_)[kDtbPath] = dtb_path; 210 } 211 212 std::string CuttlefishConfig::mempath() const { 213 return (*dictionary_)[kMempath].asString(); 214 } 215 void CuttlefishConfig::set_mempath(const std::string& mempath) { 216 (*dictionary_)[kMempath] = mempath; 217 } 218 219 std::string CuttlefishConfig::ivshmem_qemu_socket_path() const { 220 return (*dictionary_)[kIvshmemQemuSocketPath].asString(); 221 } 222 void CuttlefishConfig::set_ivshmem_qemu_socket_path( 223 const std::string& ivshmem_qemu_socket_path) { 224 (*dictionary_)[kIvshmemQemuSocketPath] = ivshmem_qemu_socket_path; 225 } 226 227 std::string CuttlefishConfig::ivshmem_client_socket_path() const { 228 return (*dictionary_)[kIvshmemClientSocketPath].asString(); 229 } 230 void CuttlefishConfig::set_ivshmem_client_socket_path( 231 const std::string& ivshmem_client_socket_path) { 232 (*dictionary_)[kIvshmemClientSocketPath] = ivshmem_client_socket_path; 233 } 234 235 int CuttlefishConfig::ivshmem_vector_count() const { 236 return (*dictionary_)[kIvshmemVectorCount].asInt(); 237 } 238 void CuttlefishConfig::set_ivshmem_vector_count(int ivshmem_vector_count) { 239 (*dictionary_)[kIvshmemVectorCount] = ivshmem_vector_count; 240 } 241 242 std::string CuttlefishConfig::usb_v1_socket_name() const { 243 return (*dictionary_)[kUsbV1SocketName].asString(); 244 } 245 void CuttlefishConfig::set_usb_v1_socket_name( 246 const std::string& usb_v1_socket_name) { 247 (*dictionary_)[kUsbV1SocketName] = usb_v1_socket_name; 248 } 249 250 int CuttlefishConfig::vhci_port() const { 251 return (*dictionary_)[kVhciPort].asInt(); 252 } 253 void CuttlefishConfig::set_vhci_port(int vhci_port) { 254 (*dictionary_)[kVhciPort] = vhci_port; 255 } 256 257 std::string CuttlefishConfig::usb_ip_socket_name() const { 258 return (*dictionary_)[kUsbIpSocketName].asString(); 259 } 260 void CuttlefishConfig::set_usb_ip_socket_name( 261 const std::string& usb_ip_socket_name) { 262 (*dictionary_)[kUsbIpSocketName] = usb_ip_socket_name; 263 } 264 265 std::string CuttlefishConfig::kernel_log_socket_name() const { 266 return (*dictionary_)[kKernelLogSocketName].asString(); 267 } 268 void CuttlefishConfig::set_kernel_log_socket_name( 269 const std::string& kernel_log_socket_name) { 270 (*dictionary_)[kKernelLogSocketName] = kernel_log_socket_name; 271 } 272 273 std::string CuttlefishConfig::console_path() const { 274 return (*dictionary_)[kConsolePath].asString(); 275 } 276 void CuttlefishConfig::set_console_path(const std::string& console_path) { 277 (*dictionary_)[kConsolePath] = console_path; 278 } 279 280 std::string CuttlefishConfig::logcat_path() const { 281 return (*dictionary_)[kLogcatPath].asString(); 282 } 283 void CuttlefishConfig::set_logcat_path(const std::string& logcat_path) { 284 (*dictionary_)[kLogcatPath] = logcat_path; 285 } 286 287 std::string CuttlefishConfig::mobile_bridge_name() const { 288 return (*dictionary_)[kMobileBridgeName].asString(); 289 } 290 void CuttlefishConfig::set_mobile_bridge_name( 291 const std::string& mobile_bridge_name) { 292 (*dictionary_)[kMobileBridgeName] = mobile_bridge_name; 293 } 294 295 std::string CuttlefishConfig::wifi_guest_mac_addr() const { 296 return (*dictionary_)[kWifiGuestMacAddr].asString(); 297 } 298 void CuttlefishConfig::set_wifi_guest_mac_addr( 299 const std::string& wifi_guest_mac_addr) { 300 (*dictionary_)[kWifiGuestMacAddr] = wifi_guest_mac_addr; 301 } 302 303 std::string CuttlefishConfig::wifi_host_mac_addr() const { 304 return (*dictionary_)[kWifiHostMacAddr].asString(); 305 } 306 void CuttlefishConfig::set_wifi_host_mac_addr( 307 const std::string& wifi_host_mac_addr) { 308 (*dictionary_)[kWifiHostMacAddr] = wifi_host_mac_addr; 309 } 310 311 std::string CuttlefishConfig::mobile_tap_name() const { 312 return (*dictionary_)[kMobileTapName].asString(); 313 } 314 void CuttlefishConfig::set_mobile_tap_name(const std::string& mobile_tap_name) { 315 (*dictionary_)[kMobileTapName] = mobile_tap_name; 316 } 317 318 std::string CuttlefishConfig::entropy_source() const { 319 return (*dictionary_)[kEntropySource].asString(); 320 } 321 void CuttlefishConfig::set_entropy_source(const std::string& entropy_source) { 322 (*dictionary_)[kEntropySource] = entropy_source; 323 } 324 325 std::string CuttlefishConfig::uuid() const { 326 return (*dictionary_)[kUuid].asString(); 327 } 328 void CuttlefishConfig::set_uuid(const std::string& uuid) { 329 (*dictionary_)[kUuid] = uuid; 330 } 331 332 bool CuttlefishConfig::disable_dac_security() const { 333 return (*dictionary_)[kDisableDacSecurity].asBool(); 334 } 335 void CuttlefishConfig::set_disable_dac_security(bool disable_dac_security) { 336 (*dictionary_)[kDisableDacSecurity] = disable_dac_security; 337 } 338 339 bool CuttlefishConfig::disable_app_armor_security() const { 340 return (*dictionary_)[kDisableAppArmorSecurity].asBool(); 341 } 342 void CuttlefishConfig::set_disable_app_armor_security( 343 bool disable_app_armor_security) { 344 (*dictionary_)[kDisableAppArmorSecurity] = disable_app_armor_security; 345 } 346 347 /*static*/ CuttlefishConfig* CuttlefishConfig::Get() { 348 static CuttlefishConfig config; 349 return &config; 350 } 351 352 CuttlefishConfig::CuttlefishConfig() : dictionary_(new Json::Value()) { 353 if (!FLAGS_config_file.empty()) { 354 LoadFromFile(FLAGS_config_file.c_str()); 355 } 356 } 357 358 void CuttlefishConfig::LoadFromFile(const char* file) { 359 char real_file_path[PATH_MAX]; 360 if (realpath(file, real_file_path) == nullptr) { 361 LOG(FATAL) << "Could not get real path for file " << file << ": " 362 << strerror(errno); 363 } 364 365 Json::Reader reader; 366 std::ifstream ifs(real_file_path); 367 if (!reader.parse(ifs, *dictionary_)) { 368 LOG(FATAL) << "Could not read config file " << file << ": " 369 << reader.getFormattedErrorMessages(); 370 } 371 } 372 bool CuttlefishConfig::SaveToFile(const std::string& file) const { 373 std::ofstream ofs(file); 374 if (!ofs.is_open()) { 375 LOG(ERROR) << "Unable to write to file " << file; 376 return false; 377 } 378 ofs << *dictionary_; 379 return !ofs.fail(); 380 } 381 382 std::string CuttlefishConfig::PerInstancePath(const char* file_name) const { 383 return (instance_dir() + "/") + file_name; 384 } 385 386 std::string CuttlefishConfig::instance_name() const { 387 return GetPerInstanceDefault("cvd-"); 388 } 389 390 bool CuttlefishConfig::ReadKernelArgs(const std::string& cmdline_file, 391 const std::string& extra_args) { 392 std::ostringstream kernel_args; 393 std::ifstream cmd_stream(cmdline_file); 394 if (!cmd_stream) { 395 LOG(WARNING) << "Unable to open " << cmdline_file; 396 return false; 397 } else { 398 kernel_args << cmd_stream.rdbuf(); 399 cmd_stream.close(); 400 } 401 if (!extra_args.empty()) { 402 kernel_args << " " << extra_args; 403 } 404 set_kernel_args(kernel_args.str()); 405 return true; 406 } 407 408 int GetInstance() { 409 static int instance_id = InstanceFromEnvironment(); 410 return instance_id; 411 } 412 413 std::string GetDomain() { 414 return CuttlefishConfig::Get()->ivshmem_client_socket_path(); 415 } 416 417 std::string GetPerInstanceDefault(const char* prefix) { 418 std::ostringstream stream; 419 stream << prefix << std::setfill('0') << std::setw(2) << GetInstance(); 420 return stream.str(); 421 } 422 int GetPerInstanceDefault(int base) { return base + GetInstance() - 1; } 423 424 std::string GetDefaultPerInstanceDir() { 425 // TODO(79170615): Change to a directory in home once libvirt is no longer 426 // default. 427 std::ostringstream stream; 428 stream << "/var/run/libvirt-" << kDefaultUuidPrefix << std::setfill('0') 429 << std::setw(2) << GetInstance(); 430 return stream.str(); 431 } 432 433 } // namespace vsoc 434