• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2019 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 #include "host/commands/run_cvd/launch.h"
17 
18 #include <android-base/logging.h>
19 #include <set>
20 #include <string>
21 #include <utility>
22 
23 #include "common/libs/fs/shared_fd.h"
24 #include "common/libs/utils/subprocess.h"
25 #include "host/libs/config/cuttlefish_config.h"
26 #include "host/libs/config/known_paths.h"
27 
28 namespace cuttlefish {
29 
30 namespace {
31 
GetAdbConnectorTcpArg(const CuttlefishConfig & config)32 std::string GetAdbConnectorTcpArg(const CuttlefishConfig& config) {
33   auto instance = config.ForDefaultInstance();
34   return std::string{"0.0.0.0:"} + std::to_string(instance.host_port());
35 }
36 
GetAdbConnectorVsockArg(const CuttlefishConfig & config)37 std::string GetAdbConnectorVsockArg(const CuttlefishConfig& config) {
38   auto instance = config.ForDefaultInstance();
39   return std::string{"vsock:"} + std::to_string(instance.vsock_guest_cid()) +
40          std::string{":5555"};
41 }
42 
AdbModeEnabled(const CuttlefishConfig & config,AdbMode mode)43 bool AdbModeEnabled(const CuttlefishConfig& config, AdbMode mode) {
44   return config.adb_mode().count(mode) > 0;
45 }
46 
AdbVsockTunnelEnabled(const CuttlefishConfig & config)47 bool AdbVsockTunnelEnabled(const CuttlefishConfig& config) {
48   auto instance = config.ForDefaultInstance();
49   return instance.vsock_guest_cid() > 2 &&
50          AdbModeEnabled(config, AdbMode::VsockTunnel);
51 }
52 
AdbVsockHalfTunnelEnabled(const CuttlefishConfig & config)53 bool AdbVsockHalfTunnelEnabled(const CuttlefishConfig& config) {
54   auto instance = config.ForDefaultInstance();
55   return instance.vsock_guest_cid() > 2 &&
56          AdbModeEnabled(config, AdbMode::VsockHalfTunnel);
57 }
58 
AdbTcpConnectorEnabled(const CuttlefishConfig & config)59 bool AdbTcpConnectorEnabled(const CuttlefishConfig& config) {
60   bool vsock_tunnel = AdbVsockTunnelEnabled(config);
61   bool vsock_half_tunnel = AdbVsockHalfTunnelEnabled(config);
62   return config.run_adb_connector() && (vsock_tunnel || vsock_half_tunnel);
63 }
64 
AdbVsockConnectorEnabled(const CuttlefishConfig & config)65 bool AdbVsockConnectorEnabled(const CuttlefishConfig& config) {
66   return config.run_adb_connector() &&
67          AdbModeEnabled(config, AdbMode::NativeVsock);
68 }
69 
70 }  // namespace
71 
LaunchAdbConnectorIfEnabled(const CuttlefishConfig & config)72 std::vector<Command> LaunchAdbConnectorIfEnabled(
73     const CuttlefishConfig& config) {
74   Command adb_connector(AdbConnectorBinary());
75   std::set<std::string> addresses;
76 
77   if (AdbTcpConnectorEnabled(config)) {
78     addresses.insert(GetAdbConnectorTcpArg(config));
79   }
80   if (AdbVsockConnectorEnabled(config)) {
81     addresses.insert(GetAdbConnectorVsockArg(config));
82   }
83 
84   if (addresses.size() == 0) {
85     return {};
86   }
87   std::string address_arg = "--addresses=";
88   for (auto& arg : addresses) {
89     address_arg += arg + ",";
90   }
91   address_arg.pop_back();
92   adb_connector.AddParameter(address_arg);
93   std::vector<Command> commands;
94   commands.emplace_back(std::move(adb_connector));
95   return std::move(commands);
96 }
97 
LaunchSocketVsockProxyIfEnabled(const CuttlefishConfig & config,SharedFD adbd_events_pipe)98 std::vector<Command> LaunchSocketVsockProxyIfEnabled(
99     const CuttlefishConfig& config, SharedFD adbd_events_pipe) {
100   auto instance = config.ForDefaultInstance();
101   auto append = [](const std::string& s, const int i) -> std::string {
102     return s + std::to_string(i);
103   };
104   auto tcp_server =
105       SharedFD::SocketLocalServer(instance.host_port(), SOCK_STREAM);
106   CHECK(tcp_server->IsOpen())
107       << "Unable to create socket_vsock_proxy server socket: "
108       << tcp_server->StrError();
109   std::vector<Command> commands;
110   if (AdbVsockTunnelEnabled(config)) {
111     Command adb_tunnel(SocketVsockProxyBinary());
112     adb_tunnel.AddParameter("-adbd_events_fd=", adbd_events_pipe);
113     /**
114      * This socket_vsock_proxy (a.k.a. sv proxy) runs on the host. It assumes
115      * that another sv proxy runs inside the guest. see:
116      * shared/config/init.vendor.rc The sv proxy in the guest exposes
117      * vsock:cid:6520 across the cuttlefish instances in multi-tenancy. cid is
118      * different per instance.
119      *
120      * This host sv proxy should cooperate with the guest sv proxy. Thus, one
121      * end of the tunnel is vsock:cid:6520 regardless of instance number.
122      * Another end faces the host adb daemon via tcp. Thus, the server type is
123      * tcp here. The tcp port differs from instance to instance, and is
124      * instance.host_port()
125      *
126      */
127     adb_tunnel.AddParameter("--server=tcp");
128     adb_tunnel.AddParameter("--vsock_port=6520");
129     adb_tunnel.AddParameter(std::string{"--server_fd="}, tcp_server);
130     adb_tunnel.AddParameter(std::string{"--vsock_cid="} +
131                             std::to_string(instance.vsock_guest_cid()));
132     commands.emplace_back(std::move(adb_tunnel));
133   }
134   if (AdbVsockHalfTunnelEnabled(config)) {
135     Command adb_tunnel(SocketVsockProxyBinary());
136     adb_tunnel.AddParameter("-adbd_events_fd=", adbd_events_pipe);
137     /*
138      * This socket_vsock_proxy (a.k.a. sv proxy) runs on the host, and
139      * cooperates with the adbd inside the guest. See this file:
140      *  shared/device.mk, especially the line says "persist.adb.tcp.port="
141      *
142      * The guest adbd is listening on vsock:cid:5555 across cuttlefish
143      * instances. Sv proxy faces the host adb daemon via tcp. The server type
144      * should be therefore tcp, and the port should differ from instance to
145      * instance and be equal to instance.host_port()
146      */
147     adb_tunnel.AddParameter("--server=tcp");
148     adb_tunnel.AddParameter(append("--vsock_port=", 5555));
149     adb_tunnel.AddParameter(std::string{"--server_fd="}, tcp_server);
150     adb_tunnel.AddParameter(append("--vsock_cid=", instance.vsock_guest_cid()));
151     commands.emplace_back(std::move(adb_tunnel));
152   }
153   return commands;
154 }
155 
156 }  // namespace cuttlefish
157