Skip to content

Commit 79a1949

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 79a1949

File tree

5 files changed

+44
-14
lines changed

5 files changed

+44
-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: 18 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>
@@ -46,8 +47,14 @@ namespace cuttlefish {
4647
constexpr std::chrono::seconds kCvdAllocateTimeout = std::chrono::seconds(30);
4748
constexpr std::chrono::seconds kCvdTeardownTimeout = std::chrono::seconds(2);
4849

50+
enum class CvdallocStatus {
51+
kUnknown = 0,
52+
kAvailable,
53+
kFailed
54+
};
55+
4956
Cvdalloc::Cvdalloc(const CuttlefishConfig::InstanceSpecific& instance)
50-
: instance_(instance) {}
57+
: instance_(instance), status_(CvdallocStatus::kUnknown) {}
5158

5259
Result<std::vector<MonitorCommand>> Cvdalloc::Commands() {
5360
std::string path = CvdallocBinary();
@@ -67,10 +74,16 @@ bool Cvdalloc::Enabled() const { return instance_.use_cvdalloc(); }
6774
std::unordered_set<SetupFeature *> Cvdalloc::Dependencies() const { return {}; }
6875

6976
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.";
77+
std::lock_guard<std::mutex> lock(availability_mutex_);
78+
CF_EXPECT(status_ != CvdallocStatus::kFailed);
79+
if (status_ == CvdallocStatus::kUnknown) {
80+
LOG(INFO) << "cvdalloc (run_cvd): waiting to finish allocation.";
81+
status_ = CvdallocStatus::kFailed;
82+
CF_EXPECT(cvdalloc::Wait(socket_, kCvdAllocateTimeout),
83+
"cvdalloc (run_cvd): Wait failed");
84+
LOG(INFO) << "cvdalloc (run_cvd): allocation is done.";
85+
status_ = CvdallocStatus::kAvailable;
86+
}
7487

7588
return {};
7689
}

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

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

3030
namespace cuttlefish {
3131

32+
enum class CvdallocStatus;
33+
3234
class Cvdalloc : public vm_manager::VmmDependencyCommand {
3335
public:
3436
INJECT(Cvdalloc(const CuttlefishConfig::InstanceSpecific &instance));
@@ -49,6 +51,8 @@ class Cvdalloc : public vm_manager::VmmDependencyCommand {
4951

5052
const CuttlefishConfig::InstanceSpecific &instance_;
5153
SharedFD socket_, their_socket_;
54+
std::mutex availability_mutex_;
55+
CvdallocStatus status_;
5256
};
5357

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

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

Lines changed: 16 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,12 @@ 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+
LOG(INFO) << "openwrt (run_cvd): cvdalloc is available.";
71+
}
72+
CF_EXPECT(wmediumd_server_.WaitForAvailability());
73+
return {};
6674
});
6775

6876
std::string first_time_argument;
@@ -183,15 +191,17 @@ class OpenWrt : public CommandSource {
183191
const CuttlefishConfig::InstanceSpecific& instance_;
184192
LogTeeCreator& log_tee_;
185193
WmediumdServer& wmediumd_server_;
194+
Cvdalloc& cvdalloc_;
186195

187196
static constexpr int kOpenwrtVmResetExitCode = 32;
188197
};
189198

190199
} // namespace
191200

192-
fruit::Component<fruit::Required<
193-
const CuttlefishConfig, const CuttlefishConfig::EnvironmentSpecific,
194-
const CuttlefishConfig::InstanceSpecific, LogTeeCreator, WmediumdServer>>
201+
fruit::Component<fruit::Required<const CuttlefishConfig,
202+
const CuttlefishConfig::EnvironmentSpecific,
203+
const CuttlefishConfig::InstanceSpecific,
204+
LogTeeCreator, WmediumdServer, Cvdalloc>>
195205
OpenWrtComponent() {
196206
return fruit::createComponent()
197207
.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)