Skip to content

Commit 6dfecc7

Browse files
committed
openwrt's vmm waits for cvdalloc.
openwrt uses a vmm to run a Wi-Fi access point, using a 802.11 hardware simulator connected to a tap device. Without cvdalloc, it assumes this device was already created by cuttlefish-host-resources. With cvdalloc, openwrt's vmm will need to wait for cvdalloc to complete in order to use the tap device it creates. The obvious way to do this is to use WaitForAvailability on cvdalloc's launcher. However, cvdalloc's launcher is already a VmmDependencyCommand for the instance's vmm, and if both openwrt's and cvdalloc's launcher are executing at the same time, we have two contending reads on cvdalloc's socketpair, which complicates matters. We could Wait and Post twice on the socket for notification, but that is rather ugly since that means we couple the number of socket Wait'ers to the cvdalloc binary unnecessarily. Instead, we guard WaitForAvailability by a mutex, so that there is always only one Wait'er at a time, and make WaitForAvailability idempotent, so that the second Wait need not actually attempt to read on the underlying socket.
1 parent 7597120 commit 6dfecc7

File tree

5 files changed

+42
-14
lines changed

5 files changed

+42
-14
lines changed

base/cvd/cuttlefish/host/commands/run_cvd/launch/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ cf_cc_library(
288288
deps = [
289289
"//cuttlefish/common/libs/utils:json",
290290
"//cuttlefish/common/libs/utils:result",
291+
"//cuttlefish/host/commands/run_cvd/launch:cvdalloc",
291292
"//cuttlefish/host/commands/run_cvd/launch:log_tee_creator",
292293
"//cuttlefish/host/commands/run_cvd/launch:wmediumd_server",
293294
"//cuttlefish/host/libs/command_util",

base/cvd/cuttlefish/host/commands/run_cvd/launch/cvdalloc.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/stat.h>
2222

2323
#include <chrono>
24+
#include <mutex>
2425
#include <string>
2526
#include <string_view>
2627
#include <unordered_set>
@@ -47,7 +48,7 @@ constexpr std::chrono::seconds kCvdAllocateTimeout = std::chrono::seconds(30);
4748
constexpr std::chrono::seconds kCvdTeardownTimeout = std::chrono::seconds(2);
4849

4950
Cvdalloc::Cvdalloc(const CuttlefishConfig::InstanceSpecific& instance)
50-
: instance_(instance) {}
51+
: instance_(instance), status_(CvdallocStatus::kUnknown) {}
5152

5253
Result<std::vector<MonitorCommand>> Cvdalloc::Commands() {
5354
std::string path = CvdallocBinary();
@@ -67,10 +68,17 @@ bool Cvdalloc::Enabled() const { return instance_.use_cvdalloc(); }
6768
std::unordered_set<SetupFeature *> Cvdalloc::Dependencies() const { return {}; }
6869

6970
Result<void> Cvdalloc::WaitForAvailability() {
70-
LOG(INFO) << "cvdalloc (run_cvd): waiting to finish allocation.";
71-
CF_EXPECT(cvdalloc::Wait(socket_, kCvdAllocateTimeout),
72-
"cvdalloc (run_cvd): Wait failed");
73-
LOG(INFO) << "cvdalloc (run_cvd): allocation is done.";
71+
std::lock_guard<std::mutex> lock(availability_mutex_);
72+
CF_EXPECT(status_ != CvdallocStatus::kFailed);
73+
if (status_ == CvdallocStatus::kUnknown) {
74+
LOG(INFO) << "cvdalloc (run_cvd): waiting to finish allocation.";
75+
status_ = CvdallocStatus::kFailed;
76+
CF_EXPECT(cvdalloc::Wait(socket_, kCvdAllocateTimeout),
77+
"cvdalloc (run_cvd): Wait failed");
78+
LOG(INFO) << "cvdalloc (run_cvd): allocation is done.";
79+
status_ = CvdallocStatus::kAvailable;
80+
}
81+
LOG(INFO) << "cvdalloc (run_cvd): available.";
7482

7583
return {};
7684
}

base/cvd/cuttlefish/host/commands/run_cvd/launch/cvdalloc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929

3030
namespace cuttlefish {
3131

32+
enum class CvdallocStatus {
33+
kUnknown = 0,
34+
kAvailable,
35+
kFailed
36+
};
37+
3238
class Cvdalloc : public vm_manager::VmmDependencyCommand {
3339
public:
3440
INJECT(Cvdalloc(const CuttlefishConfig::InstanceSpecific &instance));
@@ -49,6 +55,8 @@ class Cvdalloc : public vm_manager::VmmDependencyCommand {
4955

5056
const CuttlefishConfig::InstanceSpecific &instance_;
5157
SharedFD socket_, their_socket_;
58+
std::mutex availability_mutex_;
59+
CvdallocStatus status_;
5260
};
5361

5462
fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>

base/cvd/cuttlefish/host/commands/run_cvd/launch/open_wrt.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include "cuttlefish/common/libs/utils/json.h"
2929
#include "cuttlefish/common/libs/utils/result.h"
30+
#include "cuttlefish/host/commands/run_cvd/launch/cvdalloc.h"
3031
#include "cuttlefish/host/commands/run_cvd/launch/log_tee_creator.h"
3132
#include "cuttlefish/host/commands/run_cvd/launch/wmediumd_server.h"
3233
#include "cuttlefish/host/libs/command_util/snapshot_utils.h"
@@ -48,12 +49,14 @@ class OpenWrt : public CommandSource {
4849
INJECT(OpenWrt(const CuttlefishConfig& config,
4950
const CuttlefishConfig::EnvironmentSpecific& environment,
5051
const CuttlefishConfig::InstanceSpecific& instance,
51-
LogTeeCreator& log_tee, WmediumdServer& wmediumd_server))
52+
LogTeeCreator& log_tee, WmediumdServer& wmediumd_server,
53+
Cvdalloc& cvdalloc))
5254
: config_(config),
5355
environment_(environment),
5456
instance_(instance),
5557
log_tee_(log_tee),
56-
wmediumd_server_(wmediumd_server) {}
58+
wmediumd_server_(wmediumd_server),
59+
cvdalloc_(cvdalloc) {}
5760

5861
// CommandSource
5962
Result<std::vector<MonitorCommand>> Commands() override {
@@ -62,7 +65,11 @@ class OpenWrt : public CommandSource {
6265
CrosvmBuilder ap_cmd;
6366

6467
ap_cmd.Cmd().AddPrerequisite([this]() -> Result<void> {
65-
return wmediumd_server_.WaitForAvailability();
68+
if (cvdalloc_.Enabled()) {
69+
CF_EXPECT(cvdalloc_.WaitForAvailability());
70+
}
71+
CF_EXPECT(wmediumd_server_.WaitForAvailability());
72+
return {};
6673
});
6774

6875
std::string first_time_argument;
@@ -183,15 +190,17 @@ class OpenWrt : public CommandSource {
183190
const CuttlefishConfig::InstanceSpecific& instance_;
184191
LogTeeCreator& log_tee_;
185192
WmediumdServer& wmediumd_server_;
193+
Cvdalloc& cvdalloc_;
186194

187195
static constexpr int kOpenwrtVmResetExitCode = 32;
188196
};
189197

190198
} // namespace
191199

192-
fruit::Component<fruit::Required<
193-
const CuttlefishConfig, const CuttlefishConfig::EnvironmentSpecific,
194-
const CuttlefishConfig::InstanceSpecific, LogTeeCreator, WmediumdServer>>
200+
fruit::Component<fruit::Required<const CuttlefishConfig,
201+
const CuttlefishConfig::EnvironmentSpecific,
202+
const CuttlefishConfig::InstanceSpecific,
203+
LogTeeCreator, WmediumdServer, Cvdalloc>>
195204
OpenWrtComponent() {
196205
return fruit::createComponent()
197206
.addMultibinding<CommandSource, OpenWrt>()

base/cvd/cuttlefish/host/commands/run_cvd/launch/open_wrt.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717

1818
#include <fruit/fruit.h>
1919

20+
#include "cuttlefish/host/commands/run_cvd/launch/cvdalloc.h"
2021
#include "cuttlefish/host/commands/run_cvd/launch/log_tee_creator.h"
2122
#include "cuttlefish/host/commands/run_cvd/launch/wmediumd_server.h"
2223
#include "cuttlefish/host/libs/config/cuttlefish_config.h"
2324

2425
namespace cuttlefish {
2526

26-
fruit::Component<fruit::Required<
27-
const CuttlefishConfig, const CuttlefishConfig::EnvironmentSpecific,
28-
const CuttlefishConfig::InstanceSpecific, LogTeeCreator, WmediumdServer>>
27+
fruit::Component<fruit::Required<const CuttlefishConfig,
28+
const CuttlefishConfig::EnvironmentSpecific,
29+
const CuttlefishConfig::InstanceSpecific,
30+
LogTeeCreator, WmediumdServer, Cvdalloc>>
2931
OpenWrtComponent();
3032

3133
} // namespace cuttlefish

0 commit comments

Comments
 (0)