1 #include "host/commands/run_cvd/launch.h"
2
3 #include <sys/stat.h>
4 #include <sys/types.h>
5
6 #include <android-base/logging.h>
7
8 #include "common/libs/fs/shared_fd.h"
9 #include "common/libs/utils/files.h"
10 #include "common/libs/utils/size_utils.h"
11 #include "host/commands/run_cvd/pre_launch_initializers.h"
12 #include "host/commands/run_cvd/runner_defs.h"
13 #include "host/libs/vm_manager/crosvm_manager.h"
14 #include "host/libs/vm_manager/qemu_manager.h"
15
16 using cuttlefish::MonitorEntry;
17 using cuttlefish::RunnerExitCodes;
18 using cuttlefish::vm_manager::QemuManager;
19
20 namespace {
21
GetAdbConnectorTcpArg(const cuttlefish::CuttlefishConfig & config)22 std::string GetAdbConnectorTcpArg(const cuttlefish::CuttlefishConfig& config) {
23 auto instance = config.ForDefaultInstance();
24 return std::string{"127.0.0.1:"} + std::to_string(instance.host_port());
25 }
26
GetAdbConnectorVsockArg(const cuttlefish::CuttlefishConfig & config)27 std::string GetAdbConnectorVsockArg(const cuttlefish::CuttlefishConfig& config) {
28 auto instance = config.ForDefaultInstance();
29 return std::string{"vsock:"} + std::to_string(instance.vsock_guest_cid()) +
30 std::string{":5555"};
31 }
32
AdbModeEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::AdbMode mode)33 bool AdbModeEnabled(const cuttlefish::CuttlefishConfig& config, cuttlefish::AdbMode mode) {
34 return config.adb_mode().count(mode) > 0;
35 }
36
AdbVsockTunnelEnabled(const cuttlefish::CuttlefishConfig & config)37 bool AdbVsockTunnelEnabled(const cuttlefish::CuttlefishConfig& config) {
38 auto instance = config.ForDefaultInstance();
39 return instance.vsock_guest_cid() > 2 &&
40 AdbModeEnabled(config, cuttlefish::AdbMode::VsockTunnel);
41 }
42
AdbVsockHalfTunnelEnabled(const cuttlefish::CuttlefishConfig & config)43 bool AdbVsockHalfTunnelEnabled(const cuttlefish::CuttlefishConfig& config) {
44 auto instance = config.ForDefaultInstance();
45 return instance.vsock_guest_cid() > 2 &&
46 AdbModeEnabled(config, cuttlefish::AdbMode::VsockHalfTunnel);
47 }
48
AdbTcpConnectorEnabled(const cuttlefish::CuttlefishConfig & config)49 bool AdbTcpConnectorEnabled(const cuttlefish::CuttlefishConfig& config) {
50 bool vsock_tunnel = AdbVsockTunnelEnabled(config);
51 bool vsock_half_tunnel = AdbVsockHalfTunnelEnabled(config);
52 return config.run_adb_connector() && (vsock_tunnel || vsock_half_tunnel);
53 }
54
AdbVsockConnectorEnabled(const cuttlefish::CuttlefishConfig & config)55 bool AdbVsockConnectorEnabled(const cuttlefish::CuttlefishConfig& config) {
56 return config.run_adb_connector() &&
57 AdbModeEnabled(config, cuttlefish::AdbMode::NativeVsock);
58 }
59
GetOnSubprocessExitCallback(const cuttlefish::CuttlefishConfig & config)60 cuttlefish::OnSocketReadyCb GetOnSubprocessExitCallback(
61 const cuttlefish::CuttlefishConfig& config) {
62 if (config.restart_subprocesses()) {
63 return cuttlefish::ProcessMonitor::RestartOnExitCb;
64 } else {
65 return cuttlefish::ProcessMonitor::DoNotMonitorCb;
66 }
67 }
68
CreateUnixInputServer(const std::string & path)69 cuttlefish::SharedFD CreateUnixInputServer(const std::string& path) {
70 auto server =
71 cuttlefish::SharedFD::SocketLocalServer(path.c_str(), false, SOCK_STREAM, 0666);
72 if (!server->IsOpen()) {
73 LOG(ERROR) << "Unable to create unix input server: " << server->StrError();
74 return cuttlefish::SharedFD();
75 }
76 return server;
77 }
78
79 // Creates the frame and input sockets and add the relevant arguments to the vnc
80 // server and webrtc commands
CreateStreamerServers(cuttlefish::Command * cmd,const cuttlefish::CuttlefishConfig & config)81 StreamerLaunchResult CreateStreamerServers(
82 cuttlefish::Command* cmd, const cuttlefish::CuttlefishConfig& config) {
83 StreamerLaunchResult server_ret;
84 cuttlefish::SharedFD touch_server;
85 cuttlefish::SharedFD keyboard_server;
86
87 auto instance = config.ForDefaultInstance();
88 if (config.vm_manager() == QemuManager::name()) {
89 cmd->AddParameter("-write_virtio_input");
90
91 touch_server = cuttlefish::SharedFD::VsockServer(instance.touch_server_port(),
92 SOCK_STREAM);
93 keyboard_server =
94 cuttlefish::SharedFD::VsockServer(instance.keyboard_server_port(),
95 SOCK_STREAM);
96 } else {
97 touch_server = CreateUnixInputServer(instance.touch_socket_path());
98 keyboard_server = CreateUnixInputServer(instance.keyboard_socket_path());
99 }
100 if (!touch_server->IsOpen()) {
101 LOG(ERROR) << "Could not open touch server: " << touch_server->StrError();
102 return {};
103 }
104 cmd->AddParameter("-touch_fd=", touch_server);
105
106 if (!keyboard_server->IsOpen()) {
107 LOG(ERROR) << "Could not open keyboard server: "
108 << keyboard_server->StrError();
109 return {};
110 }
111 cmd->AddParameter("-keyboard_fd=", keyboard_server);
112
113 cuttlefish::SharedFD frames_server;
114 if (config.gpu_mode() == cuttlefish::kGpuModeDrmVirgl ||
115 config.gpu_mode() == cuttlefish::kGpuModeGfxStream) {
116 frames_server = CreateUnixInputServer(instance.frames_socket_path());
117 } else {
118 frames_server = cuttlefish::SharedFD::VsockServer(instance.frames_server_port(),
119 SOCK_STREAM);
120 }
121 if (!frames_server->IsOpen()) {
122 LOG(ERROR) << "Could not open frames server: " << frames_server->StrError();
123 return {};
124 }
125 cmd->AddParameter("-frame_server_fd=", frames_server);
126 return server_ret;
127 }
128
129 } // namespace
130
LaunchKernelLogMonitor(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor,unsigned int number_of_event_pipes)131 std::vector<cuttlefish::SharedFD> LaunchKernelLogMonitor(
132 const cuttlefish::CuttlefishConfig& config, cuttlefish::ProcessMonitor* process_monitor,
133 unsigned int number_of_event_pipes) {
134 auto instance = config.ForDefaultInstance();
135 auto log_name = instance.kernel_log_pipe_name();
136 if (mkfifo(log_name.c_str(), 0600) != 0) {
137 LOG(ERROR) << "Unable to create named pipe at " << log_name << ": "
138 << strerror(errno);
139 return {};
140 }
141
142 cuttlefish::SharedFD pipe;
143 // Open the pipe here (from the launcher) to ensure the pipe is not deleted
144 // due to the usage counters in the kernel reaching zero. If this is not done
145 // and the kernel_log_monitor crashes for some reason the VMM may get SIGPIPE.
146 pipe = cuttlefish::SharedFD::Open(log_name.c_str(), O_RDWR);
147 cuttlefish::Command command(config.kernel_log_monitor_binary());
148 command.AddParameter("-log_pipe_fd=", pipe);
149
150 std::vector<cuttlefish::SharedFD> ret;
151
152 if (number_of_event_pipes > 0) {
153 auto param_builder = command.GetParameterBuilder();
154 param_builder << "-subscriber_fds=";
155 for (unsigned int i = 0; i < number_of_event_pipes; ++i) {
156 cuttlefish::SharedFD event_pipe_write_end, event_pipe_read_end;
157 if (!cuttlefish::SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) {
158 LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
159 std::exit(RunnerExitCodes::kPipeIOError);
160 }
161 if (i > 0) {
162 param_builder << ",";
163 }
164 param_builder << event_pipe_write_end;
165 ret.push_back(event_pipe_read_end);
166 }
167 param_builder.Build();
168 }
169
170 process_monitor->StartSubprocess(std::move(command),
171 GetOnSubprocessExitCallback(config));
172
173 return ret;
174 }
175
LaunchLogcatReceiver(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)176 void LaunchLogcatReceiver(const cuttlefish::CuttlefishConfig& config,
177 cuttlefish::ProcessMonitor* process_monitor) {
178 auto instance = config.ForDefaultInstance();
179 auto log_name = instance.logcat_pipe_name();
180 if (mkfifo(log_name.c_str(), 0600) != 0) {
181 LOG(ERROR) << "Unable to create named pipe at " << log_name << ": "
182 << strerror(errno);
183 return;
184 }
185
186 cuttlefish::SharedFD pipe;
187 // Open the pipe here (from the launcher) to ensure the pipe is not deleted
188 // due to the usage counters in the kernel reaching zero. If this is not done
189 // and the logcat_receiver crashes for some reason the VMM may get SIGPIPE.
190 pipe = cuttlefish::SharedFD::Open(log_name.c_str(), O_RDWR);
191 cuttlefish::Command command(config.logcat_receiver_binary());
192 command.AddParameter("-log_pipe_fd=", pipe);
193
194 process_monitor->StartSubprocess(std::move(command),
195 GetOnSubprocessExitCallback(config));
196 return;
197 }
198
LaunchConfigServer(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)199 void LaunchConfigServer(const cuttlefish::CuttlefishConfig& config,
200 cuttlefish::ProcessMonitor* process_monitor) {
201 auto instance = config.ForDefaultInstance();
202 auto port = instance.config_server_port();
203 auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
204 if (!socket->IsOpen()) {
205 LOG(ERROR) << "Unable to create configuration server socket: "
206 << socket->StrError();
207 std::exit(RunnerExitCodes::kConfigServerError);
208 }
209 cuttlefish::Command cmd(config.config_server_binary());
210 cmd.AddParameter("-server_fd=", socket);
211 process_monitor->StartSubprocess(std::move(cmd),
212 GetOnSubprocessExitCallback(config));
213 return;
214 }
215
LaunchTombstoneReceiverIfEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)216 void LaunchTombstoneReceiverIfEnabled(const cuttlefish::CuttlefishConfig& config,
217 cuttlefish::ProcessMonitor* process_monitor) {
218 if (!config.enable_tombstone_receiver()) {
219 return;
220 }
221 auto instance = config.ForDefaultInstance();
222
223 std::string tombstoneDir = instance.PerInstancePath("tombstones");
224 if (!cuttlefish::DirectoryExists(tombstoneDir.c_str())) {
225 LOG(DEBUG) << "Setting up " << tombstoneDir;
226 if (mkdir(tombstoneDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) <
227 0) {
228 LOG(ERROR) << "Failed to create tombstone directory: " << tombstoneDir
229 << ". Error: " << errno;
230 exit(RunnerExitCodes::kTombstoneDirCreationError);
231 return;
232 }
233 }
234
235 auto port = instance.tombstone_receiver_port();
236 auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
237 if (!socket->IsOpen()) {
238 LOG(ERROR) << "Unable to create tombstone server socket: "
239 << socket->StrError();
240 std::exit(RunnerExitCodes::kTombstoneServerError);
241 return;
242 }
243 cuttlefish::Command cmd(config.tombstone_receiver_binary());
244 cmd.AddParameter("-server_fd=", socket);
245 cmd.AddParameter("-tombstone_dir=", tombstoneDir);
246
247 process_monitor->StartSubprocess(std::move(cmd),
248 GetOnSubprocessExitCallback(config));
249 return;
250 }
251
LaunchVNCServer(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor,std::function<bool (MonitorEntry *)> callback)252 StreamerLaunchResult LaunchVNCServer(
253 const cuttlefish::CuttlefishConfig& config, cuttlefish::ProcessMonitor* process_monitor,
254 std::function<bool(MonitorEntry*)> callback) {
255 auto instance = config.ForDefaultInstance();
256 // Launch the vnc server, don't wait for it to complete
257 auto port_options = "-port=" + std::to_string(instance.vnc_server_port());
258 cuttlefish::Command vnc_server(config.vnc_server_binary());
259 vnc_server.AddParameter(port_options);
260
261 auto server_ret = CreateStreamerServers(&vnc_server, config);
262
263 process_monitor->StartSubprocess(std::move(vnc_server), callback);
264 server_ret.launched = true;
265 return server_ret;
266 }
267
LaunchAdbConnectorIfEnabled(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config,cuttlefish::SharedFD adbd_events_pipe)268 void LaunchAdbConnectorIfEnabled(cuttlefish::ProcessMonitor* process_monitor,
269 const cuttlefish::CuttlefishConfig& config,
270 cuttlefish::SharedFD adbd_events_pipe) {
271 cuttlefish::Command adb_connector(config.adb_connector_binary());
272 adb_connector.AddParameter("-adbd_events_fd=", adbd_events_pipe);
273 std::set<std::string> addresses;
274
275 if (AdbTcpConnectorEnabled(config)) {
276 addresses.insert(GetAdbConnectorTcpArg(config));
277 }
278 if (AdbVsockConnectorEnabled(config)) {
279 addresses.insert(GetAdbConnectorVsockArg(config));
280 }
281
282 if (addresses.size() > 0) {
283 std::string address_arg = "--addresses=";
284 for (auto& arg : addresses) {
285 address_arg += arg + ",";
286 }
287 address_arg.pop_back();
288 adb_connector.AddParameter(address_arg);
289 process_monitor->StartSubprocess(std::move(adb_connector),
290 GetOnSubprocessExitCallback(config));
291 }
292 }
293
LaunchWebRTC(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)294 StreamerLaunchResult LaunchWebRTC(cuttlefish::ProcessMonitor* process_monitor,
295 const cuttlefish::CuttlefishConfig& config) {
296 if (config.ForDefaultInstance().start_webrtc_sig_server()) {
297 cuttlefish::Command sig_server(config.sig_server_binary());
298 sig_server.AddParameter("-assets_dir=", config.webrtc_assets_dir());
299 if (!config.webrtc_certs_dir().empty()) {
300 sig_server.AddParameter("-certs_dir=", config.webrtc_certs_dir());
301 }
302 sig_server.AddParameter("-http_server_port=", config.sig_server_port());
303 process_monitor->StartSubprocess(std::move(sig_server),
304 GetOnSubprocessExitCallback(config));
305 }
306
307 // Currently there is no way to ensure the signaling server will already have
308 // bound the socket to the port by the time the webrtc process runs (the
309 // common technique of doing it from the launcher is not possible here as the
310 // server library being used creates its own sockets). However, this issue is
311 // mitigated slightly by doing some retrying and backoff in the webrtc process
312 // when connecting to the websocket, so it shouldn't be an issue most of the
313 // time.
314
315 cuttlefish::Command webrtc(config.webrtc_binary());
316
317 auto server_ret = CreateStreamerServers(&webrtc, config);
318
319 // TODO get from launcher params
320 process_monitor->StartSubprocess(std::move(webrtc),
321 GetOnSubprocessExitCallback(config));
322 server_ret.launched = true;
323
324 return server_ret;
325 }
326
StopModemSimulator()327 bool StopModemSimulator() {
328 auto config = cuttlefish::CuttlefishConfig::Get();
329 auto instance = config->ForDefaultInstance();
330
331 std::string monitor_socket_name = "modem_simulator";
332 std::stringstream ss;
333 ss << instance.host_port();
334 monitor_socket_name.append(ss.str());
335 auto monitor_sock = cuttlefish::SharedFD::SocketLocalClient(
336 monitor_socket_name.c_str(), true, SOCK_STREAM);
337 if (!monitor_sock->IsOpen()) {
338 LOG(ERROR) << "The connection to modem simulator is closed";
339 return false;
340 }
341 std::string msg("STOP");
342 if (monitor_sock->Write(msg.data(), msg.size()) < 0) {
343 monitor_sock->Close();
344 LOG(ERROR) << "Failed to send 'STOP' to modem simulator";
345 return false;
346 }
347 char buf[64] = {0};
348 if (monitor_sock->Read(buf, sizeof(buf)) <= 0) {
349 monitor_sock->Close();
350 LOG(ERROR) << "Failed to read message from modem simulator";
351 return false;
352 }
353 if (strcmp(buf, "OK")) {
354 monitor_sock->Close();
355 LOG(ERROR) << "Read '" << buf << "' instead of 'OK' from modem simulator";
356 return false;
357 }
358
359 return true;
360 }
361
LaunchModemSimulatorIfEnabled(const cuttlefish::CuttlefishConfig & config,cuttlefish::ProcessMonitor * process_monitor)362 void LaunchModemSimulatorIfEnabled(
363 const cuttlefish::CuttlefishConfig& config,
364 cuttlefish::ProcessMonitor* process_monitor) {
365 if (!config.enable_modem_simulator()) {
366 LOG(DEBUG) << "Modem simulator not enabled";
367 return;
368 }
369
370 int instance_number = config.modem_simulator_instance_number();
371 if (instance_number > 3 /* max value */ || instance_number < 0) {
372 LOG(ERROR)
373 << "Modem simulator instance number should range between 1 and 3";
374 return;
375 }
376
377 cuttlefish::Command cmd(
378 config.modem_simulator_binary(), [](cuttlefish::Subprocess* proc) {
379 auto stopped = StopModemSimulator();
380 if (stopped) {
381 return true;
382 }
383 LOG(WARNING) << "Failed to stop modem simulator nicely, "
384 << "attempting to KILL";
385 return KillSubprocess(proc);
386 });
387
388 auto instance = config.ForDefaultInstance();
389 auto ports = instance.modem_simulator_ports();
390 auto param_builder = cmd.GetParameterBuilder();
391 param_builder << "-server_fds=";
392 for (int i = 0; i < instance_number; ++i) {
393 auto pos = ports.find(',');
394 auto temp = (pos != std::string::npos) ? ports.substr(0, pos - 1) : ports;
395 auto port = std::stoi(temp);
396 ports = ports.substr(pos + 1);
397
398 auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
399 if (!socket->IsOpen()) {
400 LOG(ERROR) << "Unable to create modem simulator server socket: "
401 << socket->StrError();
402 std::exit(RunnerExitCodes::kModemSimulatorServerError);
403 }
404 if (i > 0) {
405 param_builder << ",";
406 }
407 param_builder << socket;
408 }
409 param_builder.Build();
410
411 process_monitor->StartSubprocess(std::move(cmd),
412 GetOnSubprocessExitCallback(config));
413 }
414
LaunchSocketVsockProxyIfEnabled(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)415 void LaunchSocketVsockProxyIfEnabled(cuttlefish::ProcessMonitor* process_monitor,
416 const cuttlefish::CuttlefishConfig& config) {
417 auto instance = config.ForDefaultInstance();
418 if (AdbVsockTunnelEnabled(config)) {
419 cuttlefish::Command adb_tunnel(config.socket_vsock_proxy_binary());
420 adb_tunnel.AddParameter("--server=tcp");
421 adb_tunnel.AddParameter("--vsock_port=6520");
422 adb_tunnel.AddParameter(std::string{"--tcp_port="} +
423 std::to_string(instance.host_port()));
424 adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
425 std::to_string(instance.vsock_guest_cid()));
426 process_monitor->StartSubprocess(std::move(adb_tunnel),
427 GetOnSubprocessExitCallback(config));
428 }
429 if (AdbVsockHalfTunnelEnabled(config)) {
430 cuttlefish::Command adb_tunnel(config.socket_vsock_proxy_binary());
431 adb_tunnel.AddParameter("--server=tcp");
432 adb_tunnel.AddParameter("--vsock_port=5555");
433 adb_tunnel.AddParameter(std::string{"--tcp_port="} +
434 std::to_string(instance.host_port()));
435 adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
436 std::to_string(instance.vsock_guest_cid()));
437 process_monitor->StartSubprocess(std::move(adb_tunnel),
438 GetOnSubprocessExitCallback(config));
439 }
440 }
441
LaunchTpmSimulator(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)442 void LaunchTpmSimulator(cuttlefish::ProcessMonitor* process_monitor,
443 const cuttlefish::CuttlefishConfig& config) {
444 auto instance = config.ForDefaultInstance();
445 auto port = instance.tpm_port();
446 auto socket = cuttlefish::SharedFD::VsockServer(port, SOCK_STREAM);
447 cuttlefish::Command tpm_command(
448 cuttlefish::DefaultHostArtifactsPath("bin/tpm_simulator_manager"));
449 tpm_command.AddParameter("-port=", port);
450 process_monitor->StartSubprocess(std::move(tpm_command),
451 GetOnSubprocessExitCallback(config));
452
453 cuttlefish::Command proxy_command(config.socket_vsock_proxy_binary());
454 proxy_command.AddParameter("--server=vsock");
455 proxy_command.AddParameter("--tcp_port=", port);
456 proxy_command.AddParameter("--vsock_port=", port);
457 process_monitor->StartSubprocess(std::move(proxy_command),
458 GetOnSubprocessExitCallback(config));
459 }
460
LaunchMetrics(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)461 void LaunchMetrics(cuttlefish::ProcessMonitor* process_monitor,
462 const cuttlefish::CuttlefishConfig& config) {
463 cuttlefish::Command metrics(config.metrics_binary());
464
465 process_monitor->StartSubprocess(std::move(metrics),
466 GetOnSubprocessExitCallback(config));
467 }
468
LaunchTpmPassthrough(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)469 void LaunchTpmPassthrough(cuttlefish::ProcessMonitor* process_monitor,
470 const cuttlefish::CuttlefishConfig& config) {
471 auto server = cuttlefish::SharedFD::VsockServer(SOCK_STREAM);
472 if (!server->IsOpen()) {
473 LOG(ERROR) << "Unable to create tpm passthrough server: "
474 << server->StrError();
475 std::exit(RunnerExitCodes::kTpmPassthroughError);
476 }
477 cuttlefish::Command tpm_command(
478 cuttlefish::DefaultHostArtifactsPath("bin/vtpm_passthrough"));
479 tpm_command.AddParameter("-server_fd=", server);
480 tpm_command.AddParameter("-device=", config.tpm_device());
481
482 process_monitor->StartSubprocess(std::move(tpm_command),
483 GetOnSubprocessExitCallback(config));
484 }
485
LaunchTpm(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)486 void LaunchTpm(cuttlefish::ProcessMonitor* process_monitor,
487 const cuttlefish::CuttlefishConfig& config) {
488 if (config.tpm_device() != "") {
489 if (config.tpm_binary() != "") {
490 LOG(WARNING)
491 << "Both -tpm_device and -tpm_binary were set. Using -tpm_device.";
492 }
493 LaunchTpmPassthrough(process_monitor, config);
494 } else if (config.tpm_binary() != "") {
495 LaunchTpmSimulator(process_monitor, config);
496 }
497 }
498
LaunchSecureEnvironment(cuttlefish::ProcessMonitor * process_monitor,const cuttlefish::CuttlefishConfig & config)499 void LaunchSecureEnvironment(cuttlefish::ProcessMonitor* process_monitor,
500 const cuttlefish::CuttlefishConfig& config) {
501 auto keymaster_port = config.ForDefaultInstance().keymaster_vsock_port();
502 auto keymaster_server =
503 cuttlefish::SharedFD::VsockServer(keymaster_port, SOCK_STREAM);
504 auto gatekeeper_port = config.ForDefaultInstance().gatekeeper_vsock_port();
505 auto gatekeeper_server =
506 cuttlefish::SharedFD::VsockServer(gatekeeper_port, SOCK_STREAM);
507 cuttlefish::Command command(cuttlefish::DefaultHostArtifactsPath("bin/secure_env"));
508 command.AddParameter("-keymaster_fd=", keymaster_server);
509 command.AddParameter("-gatekeeper_fd=", gatekeeper_server);
510 process_monitor->StartSubprocess(std::move(command),
511 GetOnSubprocessExitCallback(config));
512 }
513