Adds command to send logcat output over vsock
The command takes a port, connects to it on the host's cid and sends
the output from logcat. If the logcat process exits for some reason it
sends a message down the socket and restarts logcat.
Bug: 124535805
Test: run locally
Change-Id: Icd6e97ed480cc9a06135480b1d587c2aca9c6bd4
diff --git a/guest/commands/Android.bp b/guest/commands/Android.bp
index 8264fcc..5c7c3c2 100644
--- a/guest/commands/Android.bp
+++ b/guest/commands/Android.bp
@@ -14,4 +14,5 @@
// limitations under the License.
subdirs = [
+ "vsock_logcat",
]
diff --git a/guest/commands/vsock_logcat/Android.bp b/guest/commands/vsock_logcat/Android.bp
new file mode 100644
index 0000000..52575d7
--- /dev/null
+++ b/guest/commands/vsock_logcat/Android.bp
@@ -0,0 +1,36 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_binary {
+ name: "vsock_logcat",
+ srcs: [
+ "main.cpp",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libcuttlefish_fs",
+ "libcuttlefish_utils",
+ "liblog",
+ ],
+ static_libs: [
+ "libgflags",
+ ],
+ header_libs: [
+ "cuttlefish_glog",
+ ],
+ defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/vsock_logcat/main.cpp b/guest/commands/vsock_logcat/main.cpp
new file mode 100644
index 0000000..d93be80
--- /dev/null
+++ b/guest/commands/vsock_logcat/main.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "vsock_logcat"
+
+#include <sstream>
+
+#include <cutils/properties.h>
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/utils/subprocess.h"
+
+DEFINE_uint32(port, property_get_int32("ro.boot.vsock_logcat_port", 0),
+ "VSOCK port to send logcat output to");
+DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to");
+
+int main(int argc, char** argv) {
+ gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+ CHECK(FLAGS_port != 0) << "Port flag is required";
+
+ auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port, SOCK_STREAM);
+ if (!log_fd->IsOpen()) {
+ LOG(ERROR) << "Unable to connect to vsock:" << FLAGS_cid << ":"
+ << FLAGS_port << ": " << log_fd->StrError();
+ return 1;
+ }
+
+ cvd::Command logcat_cmd("/system/bin/logcat");
+ logcat_cmd.AddParameter("-b");
+ logcat_cmd.AddParameter("all");
+ logcat_cmd.AddParameter("-v");
+ logcat_cmd.AddParameter("threadtime");
+ logcat_cmd.AddParameter("*:V");
+
+ logcat_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, log_fd);
+
+ while (true) {
+ int wstatus;
+ logcat_cmd.Start().Wait(&wstatus, 0);
+ std::ostringstream exit_msg_builder;
+ exit_msg_builder << std::endl
+ << "Logcat process exited with wstatus " << wstatus
+ << ", restarting ..." << std::endl
+ << std::endl;
+ auto exit_msg = exit_msg_builder.str();
+ size_t written = log_fd->Write(exit_msg.c_str(), exit_msg.size());
+ if (written != exit_msg.size()) {
+ LOG(ERROR) << "Unable to write complete message on socket: "
+ << log_fd->StrError();
+ return 2;
+ }
+ }
+}