• 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 
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