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 <fruit/fruit.h>
24
25 #include "common/libs/utils/result.h"
26 #include "host/commands/run_cvd/reporting.h"
27 #include "host/libs/config/command_source.h"
28 #include "host/libs/config/known_paths.h"
29
30 namespace cuttlefish {
31 namespace {
32
33 class LogcatReceiver : public CommandSource, public DiagnosticInformation {
34 public:
INJECT(LogcatReceiver (const CuttlefishConfig::InstanceSpecific & instance))35 INJECT(LogcatReceiver(const CuttlefishConfig::InstanceSpecific& instance))
36 : instance_(instance) {}
37 // DiagnosticInformation
Diagnostics() const38 std::vector<std::string> Diagnostics() const override {
39 return {"Logcat output: " + instance_.logcat_path()};
40 }
41
42 // CommandSource
Commands()43 Result<std::vector<MonitorCommand>> Commands() override {
44 Command command(LogcatReceiverBinary());
45 command.AddParameter("-log_pipe_fd=", pipe_);
46 std::vector<MonitorCommand> commands;
47 commands.emplace_back(std::move(command));
48 return commands;
49 }
50
51 // SetupFeature
Name() const52 std::string Name() const override { return "LogcatReceiver"; }
Enabled() const53 bool Enabled() const override { return true; }
54
55 private:
Dependencies() const56 std::unordered_set<SetupFeature*> Dependencies() const override { return {}; }
ResultSetup()57 Result<void> ResultSetup() {
58 auto log_name = instance_.logcat_pipe_name();
59 CF_EXPECT(mkfifo(log_name.c_str(), 0600) == 0,
60 "Unable to create named pipe at " << log_name << ": "
61 << strerror(errno));
62 // Open the pipe here (from the launcher) to ensure the pipe is not deleted
63 // due to the usage counters in the kernel reaching zero. If this is not
64 // done and the logcat_receiver crashes for some reason the VMM may get
65 // SIGPIPE.
66 pipe_ = SharedFD::Open(log_name.c_str(), O_RDWR);
67 CF_EXPECT(pipe_->IsOpen(),
68 "Can't open \"" << log_name << "\": " << pipe_->StrError());
69 return {};
70 }
71
72 const CuttlefishConfig::InstanceSpecific& instance_;
73 SharedFD pipe_;
74 };
75
76 } // namespace
77
78 fruit::Component<fruit::Required<const CuttlefishConfig::InstanceSpecific>>
LogcatReceiverComponent()79 LogcatReceiverComponent() {
80 return fruit::createComponent()
81 .addMultibinding<CommandSource, LogcatReceiver>()
82 .addMultibinding<SetupFeature, LogcatReceiver>()
83 .addMultibinding<DiagnosticInformation, LogcatReceiver>();
84 }
85
86 } // namespace cuttlefish
87