Add cvd_status to check on the launcher
Bug: 143232127
Test: Run cvd_status when the device is on and off
Change-Id: Id08c08b34e81abc45c508d8c44a2f55d01f3b3bc
diff --git a/host/commands/cvd_status/Android.bp b/host/commands/cvd_status/Android.bp
new file mode 100644
index 0000000..7196e07
--- /dev/null
+++ b/host/commands/cvd_status/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2018 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_host {
+ name: "cvd_status",
+ srcs: [
+ "cvd_status.cc",
+ ],
+ header_libs: [
+ "cuttlefish_glog",
+ ],
+ shared_libs: [
+ "libbase",
+ "libcuttlefish_fs",
+ "libcuttlefish_utils",
+ "cuttlefish_auto_resources",
+ ],
+ static_libs: [
+ "libcuttlefish_host_config",
+ "libcuttlefish_vm_manager",
+ "libjsoncpp",
+ "libgflags",
+ "libxml2",
+ ],
+ defaults: ["cuttlefish_host_only", "cuttlefish_libicuuc"],
+}
diff --git a/host/commands/cvd_status/cvd_status.cc b/host/commands/cvd_status/cvd_status.cc
new file mode 100644
index 0000000..fb9911f
--- /dev/null
+++ b/host/commands/cvd_status/cvd_status.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <algorithm>
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <memory>
+#include <sstream>
+#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/utils/environment.h"
+#include "host/commands/run_cvd/runner_defs.h"
+#include "host/libs/config/cuttlefish_config.h"
+#include "host/libs/vm_manager/vm_manager.h"
+
+DEFINE_int32(wait_for_launcher, 5,
+ "How many seconds to wait for the launcher to respond to the status "
+ "command. A value of zero means wait indefinetly");
+
+int main(int argc, char** argv) {
+ ::android::base::InitLogging(argv, android::base::StderrLogger);
+ google::ParseCommandLineFlags(&argc, &argv, true);
+
+ auto config = vsoc::CuttlefishConfig::Get();
+ if (!config) {
+ LOG(ERROR) << "Failed to obtain config object";
+ return 1;
+ }
+
+ auto monitor_path = config->launcher_monitor_socket_path();
+ if (monitor_path.empty()) {
+ LOG(ERROR) << "No path to launcher monitor found";
+ return 2;
+ }
+ auto monitor_socket = cvd::SharedFD::SocketLocalClient(monitor_path.c_str(),
+ false, SOCK_STREAM);
+ if (!monitor_socket->IsOpen()) {
+ LOG(ERROR) << "Unable to connect to launcher monitor at " << monitor_path
+ << ": " << monitor_socket->StrError();
+ return 3;
+ }
+ auto request = cvd::LauncherAction::kStatus;
+ auto bytes_sent = monitor_socket->Send(&request, sizeof(request), 0);
+ if (bytes_sent < 0) {
+ LOG(ERROR) << "Error sending launcher monitor the status command: "
+ << monitor_socket->StrError();
+ return 4;
+ }
+ // Perform a select with a timeout to guard against launcher hanging
+ cvd::SharedFDSet read_set;
+ read_set.Set(monitor_socket);
+ struct timeval timeout = {FLAGS_wait_for_launcher, 0};
+ int selected = cvd::Select(&read_set, nullptr, nullptr,
+ FLAGS_wait_for_launcher <= 0 ? nullptr : &timeout);
+ if (selected < 0){
+ LOG(ERROR) << "Failed communication with the launcher monitor: "
+ << strerror(errno);
+ return 5;
+ }
+ if (selected == 0) {
+ LOG(ERROR) << "Timeout expired waiting for launcher monitor to respond";
+ return 6;
+ }
+ cvd::LauncherResponse response;
+ auto bytes_recv = monitor_socket->Recv(&response, sizeof(response), 0);
+ if (bytes_recv < 0) {
+ LOG(ERROR) << "Error receiving response from launcher monitor: "
+ << monitor_socket->StrError();
+ return 7;
+ }
+ if (response != cvd::LauncherResponse::kSuccess) {
+ LOG(ERROR) << "Received '" << static_cast<char>(response)
+ << "' response from launcher monitor";
+ return 8;
+ }
+ LOG(INFO) << "run_cvd is active.";
+ return 0;
+}
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index 5ea68a3..663b7f0 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -304,6 +304,12 @@
client->Write(&response, sizeof(response));
}
break;
+ case cvd::LauncherAction::kStatus: {
+ // TODO(schuffelen): Return more information on a side channel
+ auto response = cvd::LauncherResponse::kSuccess;
+ client->Write(&response, sizeof(response));
+ break;
+ }
default:
LOG(ERROR) << "Unrecognized launcher action: "
<< static_cast<char>(action);
diff --git a/host/commands/run_cvd/runner_defs.h b/host/commands/run_cvd/runner_defs.h
index 255f5b0..1486b11 100644
--- a/host/commands/run_cvd/runner_defs.h
+++ b/host/commands/run_cvd/runner_defs.h
@@ -48,6 +48,7 @@
// Actions supported by the launcher server
enum class LauncherAction : char {
+ kStatus = 'I',
kStop = 'X',
};