Home | History | Annotate | Download | only in config
      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