1 /*
2  * Copyright (C) 2021 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/commands/run_cvd/validate.h"
18 
19 #include <sys/utsname.h>
20 
21 #include <android-base/logging.h>
22 #include <fruit/fruit.h>
23 
24 #include "common/libs/utils/in_sandbox.h"
25 #include "common/libs/utils/network.h"
26 #include "common/libs/utils/result.h"
27 #include "host/libs/config/cuttlefish_config.h"
28 #include "host/libs/vm_manager/host_configuration.h"
29 
30 namespace cuttlefish {
31 
TestTapDevices(const CuttlefishConfig::InstanceSpecific & instance)32 static Result<void> TestTapDevices(
33     const CuttlefishConfig::InstanceSpecific& instance) {
34 #ifdef __linux__
35   if (InSandbox()) {
36     return {};
37   }
38   auto taps = TapInterfacesInUse();
39   auto wifi = instance.wifi_tap_name();
40   CF_EXPECTF(taps.count(wifi) == 0, "Device \"{}\" in use", wifi);
41   auto mobile = instance.mobile_tap_name();
42   CF_EXPECTF(taps.count(mobile) == 0, "Device \"{}\" in use", mobile);
43   auto eth = instance.ethernet_tap_name();
44   CF_EXPECTF(taps.count(eth) == 0, "Device \"{}\" in use", eth);
45 #else
46   (void)instance;
47 #endif
48   return {};
49 }
50 
ValidateTapDevices(const CuttlefishConfig::InstanceSpecific & instance)51 Result<void> ValidateTapDevices(
52     const CuttlefishConfig::InstanceSpecific& instance) {
53   CF_EXPECT(TestTapDevices(instance),
54             "There appears to be another cuttlefish device"
55             " already running, using the requested host "
56             "resources. Try `cvd reset` or `pkill run_cvd` "
57             "and `pkill crosvm`");
58   return {};
59 }
60 
ValidateHostConfiguration()61 Result<void> ValidateHostConfiguration() {
62 #ifdef __ANDROID__
63   std::vector<std::string> config_commands;
64   CF_EXPECTF(vm_manager::ValidateHostConfiguration(&config_commands),
65              "Validation of user configuration failed.\n"
66              "Execute the following to correctly configure: \n[{}]\n",
67              "You may need to logout for the changes to take effect.\n",
68              fmt::join(config_commands, "\n"));
69 #endif
70   return {};
71 }
72 
ValidateHostKernel()73 Result<void> ValidateHostKernel() {
74   struct utsname uname_data;
75   CF_EXPECT_EQ(uname(&uname_data), 0, "uname failed: " << strerror(errno));
76   LOG(DEBUG) << "uts.sysname = \"" << uname_data.sysname << "\"";
77   LOG(DEBUG) << "uts.nodename = \"" << uname_data.nodename << "\"";
78   LOG(DEBUG) << "uts.release = \"" << uname_data.release << "\"";
79   LOG(DEBUG) << "uts.version = \"" << uname_data.version << "\"";
80   LOG(DEBUG) << "uts.machine = \"" << uname_data.machine << "\"";
81 #ifdef _GNU_SOURCE
82   LOG(DEBUG) << "uts.domainname = \"" << uname_data.domainname << "\"";
83 #endif
84   return {};
85 }
86 
87 }  // namespace cuttlefish
88