• 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/launch.h"
17 #include "host/commands/run_cvd/launch/wmediumd_server.h"
18 
19 #include <string>
20 #include <unordered_set>
21 #include <utility>
22 #include <vector>
23 
24 #include <android-base/logging.h>
25 #include <fruit/fruit.h>
26 
27 #include "common/libs/utils/files.h"
28 #include "common/libs/utils/json.h"
29 #include "common/libs/utils/network.h"
30 #include "common/libs/utils/result.h"
31 #include "host/libs/command_util/snapshot_utils.h"
32 #include "host/libs/config/command_source.h"
33 #include "host/libs/config/known_paths.h"
34 #include "host/libs/config/openwrt_args.h"
35 #include "host/libs/vm_manager/crosvm_builder.h"
36 #include "host/libs/vm_manager/crosvm_manager.h"
37 
38 namespace cuttlefish {
39 namespace {
40 
41 using APBootFlow = CuttlefishConfig::InstanceSpecific::APBootFlow;
42 
43 // TODO(b/288987294) Remove dependency to InstanceSpecific config when moving
44 // to run_env is completed.
45 class OpenWrt : public CommandSource {
46  public:
INJECT(OpenWrt (const CuttlefishConfig & config,const CuttlefishConfig::EnvironmentSpecific & environment,const CuttlefishConfig::InstanceSpecific & instance,LogTeeCreator & log_tee,WmediumdServer & wmediumd_server))47   INJECT(OpenWrt(const CuttlefishConfig& config,
48                  const CuttlefishConfig::EnvironmentSpecific& environment,
49                  const CuttlefishConfig::InstanceSpecific& instance,
50                  LogTeeCreator& log_tee, WmediumdServer& wmediumd_server))
51       : config_(config),
52         environment_(environment),
53         instance_(instance),
54         log_tee_(log_tee),
55         wmediumd_server_(wmediumd_server) {}
56 
57   // CommandSource
Commands()58   Result<std::vector<MonitorCommand>> Commands() override {
59     constexpr auto crosvm_for_ap_socket = "ap_control.sock";
60 
61     CrosvmBuilder ap_cmd;
62 
63     ap_cmd.Cmd().AddPrerequisite([this]() -> Result<void> {
64       return wmediumd_server_.WaitForAvailability();
65     });
66 
67     std::string first_time_argument;
68     if (IsRestoring(config_)) {
69       const std::string snapshot_dir_path = config_.snapshot_path();
70       auto meta_info_json = CF_EXPECT(LoadMetaJson(snapshot_dir_path));
71       const std::vector<std::string> selectors{kGuestSnapshotField,
72                                                instance_.id()};
73       const auto guest_snapshot_dir_suffix =
74           CF_EXPECT(GetValue<std::string>(meta_info_json, selectors));
75       // guest_snapshot_dir_suffix is a relative to
76       // the snapshot_path
77       const auto restore_path = snapshot_dir_path + "/" +
78                                 guest_snapshot_dir_suffix + "/" +
79                                 kGuestSnapshotBase + "_openwrt";
80       first_time_argument = "--restore=" + restore_path;
81     }
82 
83     /* TODO(b/305102099): Due to hostapd issue of OpenWRT 22.03.X versions,
84      * OpenWRT instance should be rebooted.
85      */
86     LOG(DEBUG) << "Restart OpenWRT due to hostapd issue";
87     ap_cmd.ApplyProcessRestarter(instance_.crosvm_binary(), first_time_argument,
88                                  kOpenwrtVmResetExitCode);
89     ap_cmd.Cmd().AddParameter("run");
90     ap_cmd.AddControlSocket(
91         instance_.PerInstanceInternalUdsPath(crosvm_for_ap_socket),
92         instance_.crosvm_binary());
93 
94     if (!config_.kvm_path().empty()) {
95       ap_cmd.AddKvmPath(config_.kvm_path());
96     }
97 
98     ap_cmd.Cmd().AddParameter("--no-usb");
99     ap_cmd.Cmd().AddParameter("--core-scheduling=false");
100 
101     if (!environment_.vhost_user_mac80211_hwsim().empty()) {
102       ap_cmd.Cmd().AddParameter("--vhost-user=mac80211-hwsim,socket=",
103                                 environment_.vhost_user_mac80211_hwsim());
104     }
105     if (environment_.enable_wifi() && instance_.enable_tap_devices()) {
106       ap_cmd.AddTap(instance_.wifi_tap_name());
107     }
108 
109     /* TODO(kwstephenkim): delete this code when Minidroid completely disables
110      * the AP VM itself
111      */
112     if (!instance_.crosvm_use_balloon()) {
113       ap_cmd.Cmd().AddParameter("--no-balloon");
114     }
115 
116     /* TODO(kwstephenkim): delete this code when Minidroid completely disables
117      * the AP VM itself
118      */
119     if (!instance_.crosvm_use_rng()) {
120       ap_cmd.Cmd().AddParameter("--no-rng");
121     }
122 
123     if (instance_.enable_sandbox()) {
124       ap_cmd.Cmd().AddParameter("--seccomp-policy-dir=",
125                                 instance_.seccomp_policy_dir());
126     } else {
127       ap_cmd.Cmd().AddParameter("--disable-sandbox");
128     }
129     ap_cmd.AddReadWriteDisk(instance_.PerInstancePath("ap_overlay.img"));
130 
131     auto boot_logs_path =
132         instance_.PerInstanceLogPath("crosvm_openwrt_boot.log");
133     auto logs_path = instance_.PerInstanceLogPath("crosvm_openwrt.log");
134     ap_cmd.AddSerialConsoleReadOnly(boot_logs_path);
135     ap_cmd.AddHvcReadOnly(logs_path);
136 
137     auto openwrt_args = OpenwrtArgsFromConfig(instance_);
138     switch (instance_.ap_boot_flow()) {
139       case APBootFlow::Grub:
140         if (config_.vm_manager() == VmmMode::kQemu) {
141           ap_cmd.AddReadWriteDisk(
142               instance_.persistent_ap_composite_overlay_path());
143         } else {
144           ap_cmd.AddReadWriteDisk(
145               instance_.persistent_ap_composite_disk_path());
146         }
147         ap_cmd.Cmd().AddParameter("--bios=", instance_.bootloader());
148         break;
149       case APBootFlow::LegacyDirect:
150         ap_cmd.Cmd().AddParameter("--params=\"root=/dev/vda1\"");
151         for (auto& openwrt_arg : openwrt_args) {
152           ap_cmd.Cmd().AddParameter("--params=" + openwrt_arg.first + "=" +
153                                     openwrt_arg.second);
154         }
155         ap_cmd.Cmd().AddParameter(config_.ap_kernel_image());
156         break;
157       default:
158         // must not be happened
159         break;
160     }
161 
162     std::vector<MonitorCommand> commands;
163     commands.emplace_back(
164         CF_EXPECT(log_tee_.CreateFullLogTee(ap_cmd.Cmd(), "openwrt")));
165     commands.emplace_back(std::move(ap_cmd.Cmd()));
166     return commands;
167   }
168 
169   // SetupFeature
Name() const170   std::string Name() const override { return "OpenWrt"; }
Enabled() const171   bool Enabled() const override {
172     return instance_.ap_boot_flow() != APBootFlow::None &&
173            config_.vm_manager() == VmmMode::kCrosvm;
174   }
175 
176  private:
Dependencies() const177   std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()178   Result<void> ResultSetup() override { return {}; }
179 
180   const CuttlefishConfig& config_;
181   const CuttlefishConfig::EnvironmentSpecific& environment_;
182   const CuttlefishConfig::InstanceSpecific& instance_;
183   LogTeeCreator& log_tee_;
184   WmediumdServer& wmediumd_server_;
185 
186   static constexpr int kOpenwrtVmResetExitCode = 32;
187 };
188 
189 }  // namespace
190 
191 fruit::Component<fruit::Required<
192     const CuttlefishConfig, const CuttlefishConfig::EnvironmentSpecific,
193     const CuttlefishConfig::InstanceSpecific, LogTeeCreator, WmediumdServer>>
OpenWrtComponent()194 OpenWrtComponent() {
195   return fruit::createComponent()
196       .addMultibinding<CommandSource, OpenWrt>()
197       .addMultibinding<SetupFeature, OpenWrt>();
198 }
199 
200 }  // namespace cuttlefish
201