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
18 #include <string>
19 #include <unordered_set>
20 #include <utility>
21 #include <vector>
22
23 #include <android-base/logging.h>
24 #include <fruit/fruit.h>
25
26 #include "common/libs/utils/files.h"
27 #include "common/libs/utils/network.h"
28 #include "common/libs/utils/result.h"
29 #include "host/libs/config/command_source.h"
30 #include "host/libs/config/known_paths.h"
31 #include "host/libs/config/openwrt_args.h"
32 #include "host/libs/vm_manager/crosvm_builder.h"
33 #include "host/libs/vm_manager/crosvm_manager.h"
34
35 namespace cuttlefish {
36 namespace {
37
38 using APBootFlow = CuttlefishConfig::InstanceSpecific::APBootFlow;
39
40 class OpenWrt : public CommandSource {
41 public:
INJECT(OpenWrt (const CuttlefishConfig & config,const CuttlefishConfig::InstanceSpecific & instance,LogTeeCreator & log_tee))42 INJECT(OpenWrt(const CuttlefishConfig& config,
43 const CuttlefishConfig::InstanceSpecific& instance,
44 LogTeeCreator& log_tee))
45 : config_(config), instance_(instance), log_tee_(log_tee) {}
46
47 // CommandSource
Commands()48 Result<std::vector<MonitorCommand>> Commands() override {
49 constexpr auto crosvm_for_ap_socket = "ap_control.sock";
50
51 CrosvmBuilder ap_cmd;
52 ap_cmd.ApplyProcessRestarter(instance_.crosvm_binary(),
53 kOpenwrtVmResetExitCode);
54 ap_cmd.Cmd().AddParameter("run");
55 ap_cmd.AddControlSocket(
56 instance_.PerInstanceInternalUdsPath(crosvm_for_ap_socket),
57 instance_.crosvm_binary());
58
59 ap_cmd.Cmd().AddParameter("--core-scheduling=false");
60
61 if (!config_.vhost_user_mac80211_hwsim().empty()) {
62 ap_cmd.Cmd().AddParameter("--vhost-user-mac80211-hwsim=",
63 config_.vhost_user_mac80211_hwsim());
64 }
65 SharedFD wifi_tap = ap_cmd.AddTap(instance_.wifi_tap_name());
66 if (instance_.enable_sandbox()) {
67 ap_cmd.Cmd().AddParameter("--seccomp-policy-dir=",
68 instance_.seccomp_policy_dir());
69 } else {
70 ap_cmd.Cmd().AddParameter("--disable-sandbox");
71 }
72 ap_cmd.AddReadWriteDisk(instance_.PerInstancePath("ap_overlay.img"));
73
74 auto boot_logs_path =
75 instance_.PerInstanceLogPath("crosvm_openwrt_boot.log");
76 auto logs_path = instance_.PerInstanceLogPath("crosvm_openwrt.log");
77 ap_cmd.AddSerialConsoleReadOnly(boot_logs_path);
78 ap_cmd.AddHvcReadOnly(logs_path);
79
80 auto openwrt_args = OpenwrtArgsFromConfig(instance_);
81 switch (instance_.ap_boot_flow()) {
82 case APBootFlow::Grub:
83 ap_cmd.AddReadWriteDisk(instance_.persistent_ap_composite_disk_path());
84 ap_cmd.Cmd().AddParameter("--bios=", instance_.bootloader());
85 break;
86 case APBootFlow::LegacyDirect:
87 ap_cmd.Cmd().AddParameter("--params=\"root=/dev/vda1\"");
88 for (auto& openwrt_arg : openwrt_args) {
89 ap_cmd.Cmd().AddParameter("--params=" + openwrt_arg.first + "=" +
90 openwrt_arg.second);
91 }
92 ap_cmd.Cmd().AddParameter(config_.ap_kernel_image());
93 break;
94 default:
95 // must not be happened
96 break;
97 }
98
99 std::vector<MonitorCommand> commands;
100 commands.emplace_back(
101 std::move(log_tee_.CreateLogTee(ap_cmd.Cmd(), "openwrt")));
102 commands.emplace_back(std::move(ap_cmd.Cmd()));
103 return commands;
104 }
105
106 // SetupFeature
Name() const107 std::string Name() const override { return "OpenWrt"; }
Enabled() const108 bool Enabled() const override {
109 return instance_.ap_boot_flow() != APBootFlow::None &&
110 config_.vm_manager() == vm_manager::CrosvmManager::name();
111 }
112
113 private:
Dependencies() const114 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
Setup()115 bool Setup() override { return true; }
116
117 const CuttlefishConfig& config_;
118 const CuttlefishConfig::InstanceSpecific& instance_;
119 LogTeeCreator& log_tee_;
120
121 static constexpr int kOpenwrtVmResetExitCode = 32;
122 };
123
124 } // namespace
125
126 fruit::Component<
127 fruit::Required<const CuttlefishConfig,
128 const CuttlefishConfig::InstanceSpecific, LogTeeCreator>>
OpenWrtComponent()129 OpenWrtComponent() {
130 return fruit::createComponent()
131 .addMultibinding<CommandSource, OpenWrt>()
132 .addMultibinding<SetupFeature, OpenWrt>();
133 }
134
135 } // namespace cuttlefish
136