blob: 178ff0f2b776546d76210825149e048fe0d6622c [file] [log] [blame]
/*
* 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>
#include "common/libs/utils/environment.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* kWifiBridgeName = "wifi_bridge_name";
const char* kWifiTapName = "wifi_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";
const char* kCuttlefishEnvPath = "cuttlefish_env_path";
} // 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_bridge_name() const {
return (*dictionary_)[kWifiBridgeName].asString();
}
void CuttlefishConfig::set_wifi_bridge_name(
const std::string& wifi_bridge_name) {
(*dictionary_)[kWifiBridgeName] = wifi_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::wifi_tap_name() const {
return (*dictionary_)[kWifiTapName].asString();
}
void CuttlefishConfig::set_wifi_tap_name(const std::string& wifi_tap_name) {
(*dictionary_)[kWifiTapName] = wifi_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;
}
void CuttlefishConfig::set_cuttlefish_env_path(const std::string& path) {
(*dictionary_)[kCuttlefishEnvPath] = path;
}
std::string CuttlefishConfig::cuttlefish_env_path() const {
return (*dictionary_)[kCuttlefishEnvPath].asString();
}
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