Allow multiple subscribers to boot events from kernel logs
Bug: 131184297
Bug: 131864854
Test: boot locally
Change-Id: If009906baca7aded07ac92b545be6c7fbdca0fb4
Merged-In: If009906baca7aded07ac92b545be6c7fbdca0fb4
diff --git a/host/commands/kernel_log_monitor/Android.bp b/host/commands/kernel_log_monitor/Android.bp
index a7197e5..7bc29e0 100644
--- a/host/commands/kernel_log_monitor/Android.bp
+++ b/host/commands/kernel_log_monitor/Android.bp
@@ -24,6 +24,7 @@
],
shared_libs: [
"libcuttlefish_fs",
+ "libcuttlefish_strings",
"libcuttlefish_utils",
"cuttlefish_auto_resources",
"libbase",
diff --git a/host/commands/kernel_log_monitor/kernel_log_server.h b/host/commands/kernel_log_monitor/kernel_log_server.h
index 80a6cfa..0cc8920 100644
--- a/host/commands/kernel_log_monitor/kernel_log_server.h
+++ b/host/commands/kernel_log_monitor/kernel_log_server.h
@@ -23,7 +23,6 @@
#include "common/libs/fs/shared_fd.h"
#include "common/libs/fs/shared_select.h"
-//#include "host/libs/monitor/kernel_log_client.h"
namespace monitor {
diff --git a/host/commands/kernel_log_monitor/main.cc b/host/commands/kernel_log_monitor/main.cc
index f87f0ea..a17b1b8 100644
--- a/host/commands/kernel_log_monitor/main.cc
+++ b/host/commands/kernel_log_monitor/main.cc
@@ -15,12 +15,17 @@
*/
#include <signal.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include <common/libs/fs/shared_fd.h>
#include <common/libs/fs/shared_select.h>
+#include <common/libs/strings/str_split.h>
#include <host/libs/config/cuttlefish_config.h>
#include "host/commands/kernel_log_monitor/kernel_log_server.h"
@@ -28,14 +33,38 @@
"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");
-DEFINE_int32(subscriber_fd, -1,
- "A file descriptor (a pipe) to write boot events to. If -1 is "
- "given no events will be sent");
+DEFINE_string(subscriber_fds, "",
+ "A comma separated list of file descriptors (most likely pipes) to"
+ " send boot events to.");
+
+std::vector<cvd::SharedFD> SubscribersFromCmdline() {
+ // Validate the parameter
+ std::string fd_list = FLAGS_subscriber_fds;
+ for (auto c: fd_list) {
+ if (c != ',' && (c < '0' || c > '9')) {
+ LOG(ERROR) << "Invalid file descriptor list: " << fd_list;
+ std::exit(1);
+ }
+ }
+
+ auto fds = cvd::StrSplit(FLAGS_subscriber_fds, ',');
+ std::vector<cvd::SharedFD> shared_fds;
+ for (auto& fd_str: fds) {
+ auto fd = std::stoi(fd_str);
+ auto shared_fd = cvd::SharedFD::Dup(fd);
+ close(fd);
+ shared_fds.push_back(shared_fd);
+ }
+
+ return shared_fds;
+}
int main(int argc, char** argv) {
::android::base::InitLogging(argv, android::base::StderrLogger);
google::ParseCommandLineFlags(&argc, &argv, true);
+ auto subscriber_fds = SubscribersFromCmdline();
+
// Disable default handling of SIGPIPE
struct sigaction new_action {
}, old_action{};
@@ -66,24 +95,22 @@
monitor::KernelLogServer klog{server, config->PerInstancePath("kernel.log"),
config->deprecated_boot_completed()};
- if (FLAGS_subscriber_fd >= 0) {
- auto pipe_fd = cvd::SharedFD::Dup(FLAGS_subscriber_fd);
- close(FLAGS_subscriber_fd);
- if (pipe_fd->IsOpen()) {
- klog.SubscribeToBootEvents([pipe_fd](monitor::BootEvent evt) {
- int retval = pipe_fd->Write(&evt, sizeof(evt));
+ for (auto subscriber_fd: subscriber_fds) {
+ if (subscriber_fd->IsOpen()) {
+ klog.SubscribeToBootEvents([subscriber_fd](monitor::BootEvent evt) {
+ int retval = subscriber_fd->Write(&evt, sizeof(evt));
if (retval < 0) {
- if (pipe_fd->GetErrno() != EPIPE) {
+ if (subscriber_fd->GetErrno() != EPIPE) {
LOG(ERROR) << "Error while writing to pipe: "
- << pipe_fd->StrError();
+ << subscriber_fd->StrError();
}
- pipe_fd->Close();
+ subscriber_fd->Close();
return monitor::SubscriptionAction::CancelSubscription;
}
return monitor::SubscriptionAction::ContinueSubscription;
});
} else {
- LOG(ERROR) << "Subscriber fd isn't valid: " << pipe_fd->StrError();
+ LOG(ERROR) << "Subscriber fd isn't valid: " << subscriber_fd->StrError();
// Don't return here, we still need to write the logs to a file
}
}
diff --git a/host/commands/launch/launch.cc b/host/commands/launch/launch.cc
index dd5ab82..b4de6ae 100644
--- a/host/commands/launch/launch.cc
+++ b/host/commands/launch/launch.cc
@@ -147,7 +147,7 @@
LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
std::exit(LauncherExitCodes::kPipeIOError);
}
- kernel_log_monitor.AddParameter("-subscriber_fd=", pipe_write_end);
+ kernel_log_monitor.AddParameter("-subscriber_fds=", pipe_write_end);
}
return kernel_log_monitor;
}