Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8b9aa63 authored by Jack He's avatar Jack He
Browse files

GD-HCI: Flush snoop log to kernel buffer on every write

* std::ofstream::flush() pushes user data into kernel memory. The data
  will be written even if this process crashes. However, data will be lost
  if there is a kernel panic, which is out of scope of BT snoop log.
* std::ofstream::write() followed by std::ofstream::flush() has similar
  effect as UNIX write(fd, data, len) as write() syscall dumps data into
  kernel memory directly
* Before this change, btsnoop log data might be partially stored in
  memory when bluetooth stack crashes, causing broken log entries
  or missing packets

Bug: 164973960
Test: make, flash phone, and test pairing
Tag: #gd-refactor
Change-Id: I611e0b9480511b569dadbb023775b0db8159f39d
parent d0ab2373
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ void SnoopLogger::OpenNextSnoopLogFile() {
  if (!btsnoop_ostream_.write(reinterpret_cast<const char*>(&kBtSnoopFileHeader), sizeof(FileHeaderType))) {
    LOG_ALWAYS_FATAL("Unable to write file header to \"%s\", error: \"%s\"", file_path_.c_str(), strerror(errno));
  }
  if (!btsnoop_ostream_.flush()) {
    LOG_ERROR("Failed to flush, error: \"%s\"", strerror(errno));
  }
}

void SnoopLogger::SetFilePath(std::string filename) {
@@ -219,13 +222,15 @@ void SnoopLogger::Capture(const HciPacket& packet, Direction direction, PacketTy
    if (!btsnoop_ostream_.write(reinterpret_cast<const char*>(packet.data()), packet.size())) {
      LOG_ERROR("Failed to write packet payload, error: \"%s\"", strerror(errno));
    }
    if (os::ParameterProvider::SnoopLogAlwaysFlush()) {
    // std::ofstream::flush() pushes user data into kernel memory. The data will be written even if this process
    // crashes. However, data will be lost if there is a kernel panic, which is out of scope of BT snoop log.
    // NOTE: std::ofstream::write() followed by std::ofstream::flush() has similar effect as UNIX write(fd, data, len)
    //       as write() syscall dumps data into kernel memory directly
    if (!btsnoop_ostream_.flush()) {
      LOG_ERROR("Failed to flush, error: \"%s\"", strerror(errno));
    }
  }
}
}

void SnoopLogger::ListDependencies(ModuleList* list) {
  // We have no dependencies
+0 −4
Original line number Diff line number Diff line
@@ -28,9 +28,5 @@ std::string ParameterProvider::SnoopLogFilePath() {
  return "/data/misc/bluetooth/logs/btsnoop_hci.log";
}

bool ParameterProvider::SnoopLogAlwaysFlush() {
  return false;
}

}  // namespace os
}  // namespace bluetooth
 No newline at end of file
+0 −4
Original line number Diff line number Diff line
@@ -44,9 +44,5 @@ std::string ParameterProvider::SnoopLogFilePath() {
  return std::string(cwd) + "/btsnoop_hci.log";
}

bool ParameterProvider::SnoopLogAlwaysFlush() {
  return true;
}

}  // namespace os
}  // namespace bluetooth
 No newline at end of file
+0 −3
Original line number Diff line number Diff line
@@ -28,9 +28,6 @@ class ParameterProvider {

  // Return the path to the default snoop log file location
  static std::string SnoopLogFilePath();

  // Flag to allow flush into persistent memory on every packet captured. This is enabled on host for debugging
  static bool SnoopLogAlwaysFlush();
};

}  // namespace os