Use a FIFO instead of a socket for kernel logs
Once created, FIFOs are opened just like any other file, which will
allow crosvm to use it directly with a --serial option.
Bug: 134435388
Test: local
Change-Id: Ia837eedfb2e0f7a600b85a36f921b808df8bc97e
diff --git a/host/commands/kernel_log_monitor/kernel_log_server.cc b/host/commands/kernel_log_monitor/kernel_log_server.cc
index 84b2694..f8ceb94 100644
--- a/host/commands/kernel_log_monitor/kernel_log_server.cc
+++ b/host/commands/kernel_log_monitor/kernel_log_server.cc
@@ -66,25 +66,20 @@
} // namespace
namespace monitor {
-KernelLogServer::KernelLogServer(cvd::SharedFD server_socket,
+KernelLogServer::KernelLogServer(cvd::SharedFD pipe_fd,
const std::string& log_name,
bool deprecated_boot_completed)
- : server_fd_(server_socket),
+ : pipe_fd_(pipe_fd),
log_fd_(cvd::SharedFD::Open(log_name.c_str(), O_CREAT | O_RDWR, 0666)),
deprecated_boot_completed_(deprecated_boot_completed) {}
void KernelLogServer::BeforeSelect(cvd::SharedFDSet* fd_read) const {
- if (!client_fd_->IsOpen()) fd_read->Set(server_fd_);
- if (client_fd_->IsOpen()) fd_read->Set(client_fd_);
+ fd_read->Set(pipe_fd_);
}
void KernelLogServer::AfterSelect(const cvd::SharedFDSet& fd_read) {
- if (fd_read.IsSet(server_fd_)) HandleIncomingConnection();
-
- if (client_fd_->IsOpen() && fd_read.IsSet(client_fd_)) {
- if (!HandleIncomingMessage()) {
- client_fd_->Close();
- }
+ if (fd_read.IsSet(pipe_fd_)) {
+ HandleIncomingMessage();
}
}
@@ -93,29 +88,12 @@
subscribers_.push_back(callback);
}
-// Accept new kernel log connection.
-void KernelLogServer::HandleIncomingConnection() {
- if (client_fd_->IsOpen()) {
- LOG(ERROR) << "Client already connected. No longer accepting connection.";
- return;
- }
-
- client_fd_ = SharedFD::Accept(*server_fd_, nullptr, nullptr);
- if (!client_fd_->IsOpen()) {
- LOG(ERROR) << "Client connection failed: " << client_fd_->StrError();
- return;
- }
- if (client_fd_->Fcntl(F_SETFL, O_NONBLOCK) == -1) {
- LOG(ERROR) << "Client connection refused O_NONBLOCK: " << client_fd_->StrError();
- }
-}
-
bool KernelLogServer::HandleIncomingMessage() {
const size_t buf_len = 256;
char buf[buf_len];
- ssize_t ret = client_fd_->Read(buf, buf_len);
+ ssize_t ret = pipe_fd_->Read(buf, buf_len);
if (ret < 0) {
- LOG(ERROR) << "Could not read from QEmu serial port: " << client_fd_->StrError();
+ LOG(ERROR) << "Could not read kernel logs: " << pipe_fd_->StrError();
return false;
}
if (ret == 0) return false;
diff --git a/host/commands/kernel_log_monitor/kernel_log_server.h b/host/commands/kernel_log_monitor/kernel_log_server.h
index f71ebb7..f5709ee 100644
--- a/host/commands/kernel_log_monitor/kernel_log_server.h
+++ b/host/commands/kernel_log_monitor/kernel_log_server.h
@@ -46,7 +46,7 @@
// one connection.
class KernelLogServer {
public:
- KernelLogServer(cvd::SharedFD server_socket,
+ KernelLogServer(cvd::SharedFD pipe_fd,
const std::string& log_name,
bool deprecated_boot_completed);
@@ -62,15 +62,11 @@
void SubscribeToBootEvents(BootEventCallback callback);
private:
- // Handle new client connection. Only accept one connection.
- void HandleIncomingConnection();
-
// Respond to message from remote client.
// Returns false, if client disconnected.
bool HandleIncomingMessage();
- cvd::SharedFD server_fd_;
- cvd::SharedFD client_fd_;
+ cvd::SharedFD pipe_fd_;
cvd::SharedFD log_fd_;
std::string line_;
bool deprecated_boot_completed_;
diff --git a/host/commands/kernel_log_monitor/main.cc b/host/commands/kernel_log_monitor/main.cc
index a17b1b8..1f0ead3 100644
--- a/host/commands/kernel_log_monitor/main.cc
+++ b/host/commands/kernel_log_monitor/main.cc
@@ -29,7 +29,7 @@
#include <host/libs/config/cuttlefish_config.h>
#include "host/commands/kernel_log_monitor/kernel_log_server.h"
-DEFINE_int32(log_server_fd, -1,
+DEFINE_int32(log_pipe_fd, -1,
"A file descriptor representing a (UNIX) socket from which to "
"read the logs. If -1 is given the socket is created according to "
"the instance configuration");
@@ -77,22 +77,21 @@
return 1;
}
- cvd::SharedFD server;
- if (FLAGS_log_server_fd < 0) {
- auto log_name = config->kernel_log_socket_name();
- server = cvd::SharedFD::SocketLocalServer(log_name.c_str(), false,
- SOCK_STREAM, 0666);
+ cvd::SharedFD pipe;
+ if (FLAGS_log_pipe_fd < 0) {
+ auto log_name = config->kernel_log_pipe_name();
+ pipe = cvd::SharedFD::Open(log_name.c_str(), O_RDONLY);
} else {
- server = cvd::SharedFD::Dup(FLAGS_log_server_fd);
- close(FLAGS_log_server_fd);
+ pipe = cvd::SharedFD::Dup(FLAGS_log_pipe_fd);
+ close(FLAGS_log_pipe_fd);
}
- if (!server->IsOpen()) {
- LOG(ERROR) << "Error opening log server: " << server->StrError();
+ if (!pipe->IsOpen()) {
+ LOG(ERROR) << "Error opening log pipe: " << pipe->StrError();
return 2;
}
- monitor::KernelLogServer klog{server, config->PerInstancePath("kernel.log"),
+ monitor::KernelLogServer klog{pipe, config->PerInstancePath("kernel.log"),
config->deprecated_boot_completed()};
for (auto subscriber_fd: subscriber_fds) {
diff --git a/host/commands/launch/flags.cc b/host/commands/launch/flags.cc
index 105741b..d16eb0e 100644
--- a/host/commands/launch/flags.cc
+++ b/host/commands/launch/flags.cc
@@ -452,7 +452,7 @@
tmp_config_obj.set_usb_ip_socket_name(tmp_config_obj.PerInstancePath("usb-ip"));
}
- tmp_config_obj.set_kernel_log_socket_name(tmp_config_obj.PerInstancePath("kernel-log"));
+ tmp_config_obj.set_kernel_log_pipe_name(tmp_config_obj.PerInstancePath("kernel-log"));
tmp_config_obj.set_deprecated_boot_completed(FLAGS_deprecated_boot_completed);
tmp_config_obj.set_console_path(tmp_config_obj.PerInstancePath("console"));
tmp_config_obj.set_logcat_path(tmp_config_obj.PerInstancePath("logcat"));
diff --git a/host/commands/launch/launch.cc b/host/commands/launch/launch.cc
index e8367b3..75387f0 100644
--- a/host/commands/launch/launch.cc
+++ b/host/commands/launch/launch.cc
@@ -1,5 +1,8 @@
#include "host/commands/launch/launch.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include <glog/logging.h>
#include "common/libs/fs/shared_fd.h"
@@ -130,11 +133,20 @@
const vsoc::CuttlefishConfig& config,
cvd::ProcessMonitor* process_monitor,
unsigned int number_of_event_pipes) {
- auto log_name = config.kernel_log_socket_name();
- auto server = cvd::SharedFD::SocketLocalServer(log_name.c_str(), false,
- SOCK_STREAM, 0666);
+ auto log_name = config.kernel_log_pipe_name();
+ if (mkfifo(log_name.c_str(), 0600) != 0) {
+ LOG(ERROR) << "Unable to create named pipe at " << log_name << ": "
+ << strerror(errno);
+ return {};
+ }
+
+ cvd::SharedFD pipe;
+ // Open the pipe here (from the launcher) to ensure the pipe is not deleted
+ // due to the usage counters in the kernel reaching zero. If this is not done
+ // and the kernel_log_monitor crashes for some reason the VMM may get SIGPIPE.
+ pipe = cvd::SharedFD::Open(log_name.c_str(), O_RDWR);
cvd::Command command(config.kernel_log_monitor_binary());
- command.AddParameter("-log_server_fd=", server);
+ command.AddParameter("-log_pipe_fd=", pipe);
std::vector<cvd::SharedFD> ret;
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 34df60e..bfd8633 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -102,7 +102,7 @@
const char* kUsbV1SocketName = "usb_v1_socket_name";
const char* kVhciPort = "vhci_port";
const char* kUsbIpSocketName = "usb_ip_socket_name";
-const char* kKernelLogSocketName = "kernel_log_socket_name";
+const char* kKernelLogPipeName = "kernel_log_pipe_name";
const char* kDeprecatedBootCompleted = "deprecated_boot_completed";
const char* kConsolePath = "console_path";
const char* kLogcatPath = "logcat_path";
@@ -495,12 +495,12 @@
(*dictionary_)[kUsbIpSocketName] = usb_ip_socket_name;
}
-std::string CuttlefishConfig::kernel_log_socket_name() const {
- return (*dictionary_)[kKernelLogSocketName].asString();
+std::string CuttlefishConfig::kernel_log_pipe_name() const {
+ return (*dictionary_)[kKernelLogPipeName].asString();
}
-void CuttlefishConfig::set_kernel_log_socket_name(
- const std::string& kernel_log_socket_name) {
- (*dictionary_)[kKernelLogSocketName] = kernel_log_socket_name;
+void CuttlefishConfig::set_kernel_log_pipe_name(
+ const std::string& kernel_log_pipe_name) {
+ (*dictionary_)[kKernelLogPipeName] = kernel_log_pipe_name;
}
bool CuttlefishConfig::deprecated_boot_completed() const {
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index 74118b1..9d591ac 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -193,8 +193,8 @@
std::string usb_ip_socket_name() const;
void set_usb_ip_socket_name(const std::string& usb_ip_socket_name);
- std::string kernel_log_socket_name() const;
- void set_kernel_log_socket_name(const std::string& kernel_log_socket_name);
+ std::string kernel_log_pipe_name() const;
+ void set_kernel_log_pipe_name(const std::string& kernel_log_pipe_name);
bool deprecated_boot_completed() const;
void set_deprecated_boot_completed(bool deprecated_boot_completed);
diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh
index 3556303..e81e1de 100755
--- a/host/libs/vm_manager/cf_qemu.sh
+++ b/host/libs/vm_manager/cf_qemu.sh
@@ -212,7 +212,7 @@
args+=(
-chardev "socket,id=charmonitor,path=${monitor_path:-${default_dir}/qemu_monitor.sock},server,nowait"
-mon "chardev=charmonitor,id=monitor,mode=control"
- -chardev "socket,id=charserial0,path=${kernel_log_socket_name:-${default_dir}/kernel-log}"
+ -chardev "file,id=charserial0,path=${kernel_log_pipe_name:-${default_dir}/kernel-log},append=on"
-device "${kernel_console_serial},chardev=charserial0,id=serial0"
-chardev "socket,id=charserial1,path=${console_path:-${default_dir}/console},server,nowait"
-device "pci-serial,chardev=charserial1,id=serial1"
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index ef0645f..6aa13af 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -36,8 +36,7 @@
}
cvd::SharedFD ConnectToLogMonitor(const std::string& log_monitor_name) {
- return cvd::SharedFD::SocketLocalClient(log_monitor_name.c_str(), false,
- SOCK_STREAM);
+ return cvd::SharedFD::Open(log_monitor_name.c_str(), O_WRONLY);
}
void AddTapFdParameter(cvd::Command* crosvm_cmd, const std::string& tap_name) {
@@ -146,7 +145,7 @@
}
auto kernel_log_connection =
- ConnectToLogMonitor(config_->kernel_log_socket_name());
+ ConnectToLogMonitor(config_->kernel_log_pipe_name());
if (!kernel_log_connection->IsOpen()) {
LOG(WARNING) << "Unable to connect to log monitor: "
<< kernel_log_connection->StrError();
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index 36deff1..09ec4a2 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -109,14 +109,14 @@
LogAndSetEnv("composite_disk_path", config_->composite_disk_path());
LogAndSetEnv("wifi_tap_name", config_->wifi_tap_name());
LogAndSetEnv("mobile_tap_name", config_->mobile_tap_name());
- LogAndSetEnv("kernel_log_socket_name",
- config_->kernel_log_socket_name());
+ LogAndSetEnv("kernel_log_pipe_name",
+ config_->kernel_log_pipe_name());
LogAndSetEnv("console_path", config_->console_path());
LogAndSetEnv("logcat_path", config_->logcat_path());
LogAndSetEnv("ivshmem_qemu_socket_path",
- config_->ivshmem_qemu_socket_path());
+ config_->ivshmem_qemu_socket_path());
LogAndSetEnv("ivshmem_vector_count",
- std::to_string(config_->ivshmem_vector_count()));
+ std::to_string(config_->ivshmem_vector_count()));
LogAndSetEnv("usb_v1_socket_name", config_->usb_v1_socket_name());
LogAndSetEnv("vsock_guest_cid", std::to_string(config_->vsock_guest_cid()));
LogAndSetEnv("logcat_mode", config_->logcat_mode());