1 /*
2 * Copyright (C) 2017 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 <android-base/logging.h>
18 #include <android-base/strings.h>
19 #include <build/version.h>
20 #include <fruit/fruit.h>
21 #include <gflags/gflags.h>
22 #include <unistd.h>
23
24 #include <fstream>
25 #include <memory>
26 #include <string>
27 #include <utility>
28 #include <vector>
29
30 #include "common/libs/fs/shared_buf.h"
31 #include "common/libs/fs/shared_fd.h"
32 #include "common/libs/utils/environment.h"
33 #include "common/libs/utils/files.h"
34 #include "common/libs/utils/size_utils.h"
35 #include "common/libs/utils/subprocess.h"
36 #include "common/libs/utils/tee_logging.h"
37 #include "host/commands/run_cvd/boot_state_machine.h"
38 #include "host/commands/run_cvd/launch/auto_cmd.h"
39 #include "host/commands/run_cvd/launch/launch.h"
40 #include "host/commands/run_cvd/reporting.h"
41 #include "host/commands/run_cvd/server_loop.h"
42 #include "host/commands/run_cvd/validate.h"
43 #include "host/libs/command_util/runner/defs.h"
44 #include "host/libs/config/adb/adb.h"
45 #include "host/libs/config/config_flag.h"
46 #include "host/libs/config/config_fragment.h"
47 #include "host/libs/config/custom_actions.h"
48 #include "host/libs/config/cuttlefish_config.h"
49 #include "host/libs/config/fastboot/fastboot.h"
50 #include "host/libs/config/inject.h"
51 #include "host/libs/metrics/metrics_receiver.h"
52 #include "host/libs/process_monitor/process_monitor.h"
53 #include "host/libs/vm_manager/vm_manager.h"
54
55 namespace cuttlefish {
56
57 namespace {
58
59 class CuttlefishEnvironment : public DiagnosticInformation {
60 public:
INJECT(CuttlefishEnvironment (const CuttlefishConfig::InstanceSpecific & instance))61 INJECT(
62 CuttlefishEnvironment(const CuttlefishConfig::InstanceSpecific& instance))
63 : instance_(instance) {}
64
65 // DiagnosticInformation
Diagnostics() const66 std::vector<std::string> Diagnostics() const override {
67 auto config_path = instance_.PerInstancePath("cuttlefish_config.json");
68 return {
69 "Launcher log: " + instance_.launcher_log_path(),
70 "Instance configuration: " + config_path,
71 // TODO(rammuthiah) replace this with a more thorough cvd host package
72 // version scheme. Currently this only reports the Build Number of
73 // run_cvd and it is possible for other host binaries to be from
74 // different versions.
75 "Launcher Build ID: " + android::build::GetBuildNumber(),
76 };
77 }
78
79 private:
80 const CuttlefishConfig::InstanceSpecific& instance_;
81 };
82
83 class InstanceLifecycle : public LateInjected {
84 public:
INJECT(InstanceLifecycle (const CuttlefishConfig & config,ServerLoop & server_loop))85 INJECT(InstanceLifecycle(const CuttlefishConfig& config,
86 ServerLoop& server_loop))
87 : config_(config), server_loop_(server_loop) {}
88
LateInject(fruit::Injector<> & injector)89 Result<void> LateInject(fruit::Injector<>& injector) override {
90 config_fragments_ = injector.getMultibindings<ConfigFragment>();
91 setup_features_ = injector.getMultibindings<SetupFeature>();
92 diagnostics_ = injector.getMultibindings<DiagnosticInformation>();
93 return {};
94 }
95
Run()96 Result<void> Run() {
97 for (auto& fragment : config_fragments_) {
98 CF_EXPECT(config_.LoadFragment(*fragment));
99 }
100
101 // One of the setup features can consume most output, so print this early.
102 DiagnosticInformation::PrintAll(diagnostics_);
103
104 CF_EXPECT(SetupFeature::RunSetup(setup_features_));
105
106 CF_EXPECT(server_loop_.Run());
107
108 return {};
109 }
110
111 private:
112 const CuttlefishConfig& config_;
113 ServerLoop& server_loop_;
114 std::vector<ConfigFragment*> config_fragments_;
115 std::vector<SetupFeature*> setup_features_;
116 std::vector<DiagnosticInformation*> diagnostics_;
117 };
118
runCvdComponent(const CuttlefishConfig * config,const CuttlefishConfig::EnvironmentSpecific * environment,const CuttlefishConfig::InstanceSpecific * instance)119 fruit::Component<> runCvdComponent(
120 const CuttlefishConfig* config,
121 const CuttlefishConfig::EnvironmentSpecific* environment,
122 const CuttlefishConfig::InstanceSpecific* instance) {
123 // WARNING: The install order indirectly controls the order that processes
124 // are started and stopped. The start order shouldn't matter, but if the stop
125 // order is inccorect, then some processes may crash on shutdown. For
126 // example, vhost-user processes must be stopped *after* VMM processes (so,
127 // sort vhost-user before VMM in this list).
128 return fruit::createComponent()
129 .addMultibinding<DiagnosticInformation, CuttlefishEnvironment>()
130 .addMultibinding<InstanceLifecycle, InstanceLifecycle>()
131 .addMultibinding<LateInjected, InstanceLifecycle>()
132 .bindInstance(*config)
133 .bindInstance(*instance)
134 .bindInstance(*environment)
135 #ifdef __linux__
136 .install(AutoCmd<AutomotiveProxyService>::Component)
137 .install(AutoCmd<ModemSimulator>::Component)
138 .install(AutoCmd<TombstoneReceiver>::Component)
139 .install(McuComponent)
140 .install(VhostDeviceVsockComponent)
141 .install(VhostInputDevicesComponent)
142 .install(WmediumdServerComponent)
143 .install(launchStreamerComponent)
144 .install(AutoCmd<VhalProxyServer>::Component)
145 .install(Ti50EmulatorComponent)
146 #endif
147 .install(AdbConfigComponent)
148 .install(AdbConfigFragmentComponent)
149 .install(FastbootConfigComponent)
150 .install(FastbootConfigFragmentComponent)
151 .install(bootStateMachineComponent)
152 .install(AutoCmd<CasimirControlServer>::Component)
153 .install(AutoCmd<ScreenRecordingServer>::Component)
154 .install(ConfigFlagPlaceholder)
155 .install(CustomActionsComponent)
156 .install(LaunchAdbComponent)
157 .install(LaunchFastbootComponent)
158 .install(AutoCmd<BluetoothConnector>::Component)
159 .install(AutoCmd<NfcConnector>::Component)
160 .install(AutoCmd<UwbConnector>::Component)
161 .install(AutoCmd<ConsoleForwarder>::Component)
162 .install(AutoDiagnostic<ConsoleInfo>::Component)
163 .install(ControlEnvProxyServerComponent)
164 .install(AutoCmd<EchoServer>::Component)
165 .install(AutoCmd<GnssGrpcProxyServer>::Component)
166 .install(AutoCmd<LogcatReceiver>::Component)
167 .install(AutoDiagnostic<LogcatInfo>::Component)
168 .install(KernelLogMonitorComponent)
169 .install(AutoCmd<MetricsService>::Component)
170 .install(OpenwrtControlServerComponent)
171 .install(AutoCmd<Pica>::Component)
172 .install(RootCanalComponent)
173 .install(AutoCmd<Casimir>::Component)
174 .install(NetsimServerComponent)
175 .install(AutoSnapshotControlFiles::Component)
176 .install(AutoCmd<SecureEnv>::Component)
177 .install(AutoSensorsSocketPair::Component)
178 .install(AutoCmd<SensorsSimulator>::Component)
179 .install(serverLoopComponent)
180 .install(WebRtcControllerComponent)
181 .install(AutoSetup<ValidateTapDevices>::Component)
182 .install(AutoSetup<ValidateHostConfiguration>::Component)
183 .install(AutoSetup<ValidateHostKernel>::Component)
184 #ifdef __linux__
185 // OpenWrtComponent spawns a VMM and so has similar install order
186 // requirements to VmManagerComponent.
187 .install(OpenWrtComponent)
188 #endif
189 .install(vm_manager::VmManagerComponent);
190 }
191
StdinValid()192 Result<void> StdinValid() {
193 CF_EXPECT(!isatty(0),
194 "stdin was a tty, expected to be passed the output of a"
195 " previous stage. Did you mean to run launch_cvd?");
196 CF_EXPECT(errno != EBADF,
197 "stdin was not a valid file descriptor, expected to be passed the "
198 "output of assemble_cvd. Did you mean to run launch_cvd?");
199 return {};
200 }
201
ConfigureLogs(const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance)202 void ConfigureLogs(const CuttlefishConfig& config,
203 const CuttlefishConfig::InstanceSpecific& instance) {
204 auto log_path = instance.launcher_log_path();
205
206 if (!FileHasContent(log_path)) {
207 std::ofstream launcher_log_ofstream(log_path.c_str());
208 auto assembly_path = config.AssemblyPath("assemble_cvd.log");
209 std::ifstream assembly_log_ifstream(assembly_path);
210 if (assembly_log_ifstream) {
211 auto assemble_log = ReadFile(assembly_path);
212 launcher_log_ofstream << assemble_log;
213 }
214 }
215 std::string prefix;
216 if (config.Instances().size() > 1) {
217 prefix = instance.instance_name() + ": ";
218 }
219 ::android::base::SetLogger(LogToStderrAndFiles({log_path}, prefix));
220 }
221
222 } // namespace
223
RunCvdMain(int argc,char ** argv)224 Result<void> RunCvdMain(int argc, char** argv) {
225 setenv("ANDROID_LOG_TAGS", "*:v", /* overwrite */ 0);
226 ::android::base::InitLogging(argv, android::base::StderrLogger);
227 google::ParseCommandLineFlags(&argc, &argv, false);
228
229 CF_EXPECT(StdinValid(), "Invalid stdin");
230 auto config = CF_EXPECT(CuttlefishConfig::Get());
231 auto environment = config->ForDefaultEnvironment();
232 auto instance = config->ForDefaultInstance();
233 ConfigureLogs(*config, instance);
234
235 fruit::Injector<> injector(runCvdComponent, config, &environment, &instance);
236
237 for (auto& late_injected : injector.getMultibindings<LateInjected>()) {
238 CF_EXPECT(late_injected->LateInject(injector));
239 }
240
241 if (config->enable_metrics() == cuttlefish::CuttlefishConfig::Answer::kYes) {
242 MetricsReceiver::LogMetricsVMStart();
243 }
244
245 auto instance_bindings = injector.getMultibindings<InstanceLifecycle>();
246 CF_EXPECT(instance_bindings.size() == 1);
247 CF_EXPECT(instance_bindings[0]->Run()); // Should not return
248
249 return CF_ERR("The server loop returned, it should never happen!!");
250 }
251
252 } // namespace cuttlefish
253
main(int argc,char ** argv)254 int main(int argc, char** argv) {
255 auto result = cuttlefish::RunCvdMain(argc, argv);
256 if (result.ok()) {
257 return 0;
258 }
259 LOG(ERROR) << result.error().FormatForEnv();
260 abort();
261 }
262