Merge "Add NATIVE_COVERAGE_PATHS"
diff --git a/host/commands/assemble_cvd/flags.cc b/host/commands/assemble_cvd/flags.cc
index af839c1..b0a24ec 100644
--- a/host/commands/assemble_cvd/flags.cc
+++ b/host/commands/assemble_cvd/flags.cc
@@ -249,7 +249,7 @@
DEFINE_string(ril_dns, "8.8.8.8", "DNS address of mobile network (RIL)");
DEFINE_bool(kgdb, false, "Configure the virtual device for debugging the kernel "
"with kgdb/kdb. The kernel must have been built with "
- "kgdb support.");
+ "kgdb support, and serial console must be enabled.");
DEFINE_bool(start_gnss_proxy, false, "Whether to start the gnss proxy.");
@@ -262,6 +262,8 @@
DEFINE_int32(modem_simulator_sim_type, 1,
"Sim type: 1 for normal, 2 for CtsCarrierApiTestCases");
+DEFINE_bool(console, false, "Enable the serial console");
+
namespace {
const std::string kKernelDefaultPath = "kernel";
@@ -475,6 +477,11 @@
vm_manager_cmdline += " earlycon=uart8250,io,0x3f8";
if (FLAGS_vm_manager == QemuManager::name()) {
+ // crosvm doesn't support ACPI PNP, but QEMU does. We need to disable
+ // it on QEMU so that the ISA serial ports aren't claimed by ACPI, so
+ // we can use serdev with platform devices instead
+ vm_manager_cmdline += " pnpacpi=off";
+
// crosvm sets up the ramoops.xx= flags for us, but QEMU does not.
// See external/crosvm/x86_64/src/lib.rs
// this feature is not supported on aarch64
@@ -490,26 +497,47 @@
}
}
- std::string console_dev;
- auto can_use_virtio_console = !FLAGS_kgdb && !FLAGS_use_bootloader;
- if (can_use_virtio_console) {
- // If kgdb and the bootloader are disabled, the Android serial console spawns on a
- // virtio-console port. If the bootloader is enabled, virtio console can't be used
- // since uboot doesn't support it.
- console_dev = "hvc1";
- } else {
- // crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
- if (cuttlefish::HostArch() == "aarch64" && FLAGS_vm_manager != CrosvmManager::name()) {
- console_dev = "ttyAMA0";
+ if (FLAGS_console) {
+ std::string console_dev;
+ auto can_use_virtio_console = !FLAGS_kgdb && !FLAGS_use_bootloader;
+ if (can_use_virtio_console) {
+ // If kgdb and the bootloader are disabled, the Android serial console spawns on a
+ // virtio-console port. If the bootloader is enabled, virtio console can't be used
+ // since uboot doesn't support it.
+ console_dev = "hvc1";
} else {
- console_dev = "ttyS0";
+ // crosvm ARM does not support ttyAMA. ttyAMA is a part of ARM arch.
+ if (cuttlefish::HostArch() == "aarch64" && FLAGS_vm_manager != CrosvmManager::name()) {
+ console_dev = "ttyAMA0";
+ } else {
+ console_dev = "ttyS0";
+ }
}
+
+ vm_manager_cmdline += " androidboot.console=" + console_dev;
+ if (FLAGS_kgdb) {
+ vm_manager_cmdline += " kgdboc_earlycon kgdbcon kgdboc=" + console_dev;
+ }
+
+ tmp_config_obj.set_kgdb(FLAGS_kgdb);
+ } else {
+ // Specify an invalid path under /dev, so the init process will disable the
+ // console service due to the console not being found. On physical devices,
+ // it is enough to not specify androidboot.console= *and* not specify the
+ // console= kernel command line parameter, because the console and kernel
+ // dmesg are muxed. However, on cuttlefish, we don't need to mux, and would
+ // prefer to retain the kernel dmesg logging, so we must work around init
+ // falling back to the check for /dev/console (which we'll always have).
+ vm_manager_cmdline += " androidboot.console=invalid";
+
+ // Right now 'kdb' is the only way to interact with kgdb. Until we move the
+ // kgdb feature to its own serial port, it doesn't make much to enable kgdb
+ // unless serial console is also enabled. The 'kdb' feature cannot be used
+ // over adb.
+ tmp_config_obj.set_kgdb(false);
}
- vm_manager_cmdline += " androidboot.console=" + console_dev;
- if (FLAGS_kgdb) {
- vm_manager_cmdline += " kgdboc_earlycon kgdbcon kgdboc=" + console_dev;
- }
+ tmp_config_obj.set_console(FLAGS_console);
tmp_config_obj.set_vm_manager_kernel_cmdline(vm_manager_cmdline);
@@ -591,7 +619,6 @@
tmp_config_obj.set_ril_dns(FLAGS_ril_dns);
- tmp_config_obj.set_kgdb(FLAGS_kgdb);
tmp_config_obj.set_enable_minimal_mode(FLAGS_enable_minimal_mode);
std::vector<int> instance_nums;
diff --git a/host/commands/run_cvd/launch.cc b/host/commands/run_cvd/launch.cc
index 909e831..acc2717 100644
--- a/host/commands/run_cvd/launch.cc
+++ b/host/commands/run_cvd/launch.cc
@@ -449,17 +449,16 @@
}
void LaunchGnssGrpcProxyServerIfEnabled(const cuttlefish::CuttlefishConfig& config,
- cuttlefish::ProcessMonitor* process_monitor) {
+ cuttlefish::ProcessMonitor* process_monitor) {
if (!config.enable_gnss_grpc_proxy() ||
!cuttlefish::FileExists(cuttlefish::GnssGrpcProxyBinary())) {
return;
}
+
cuttlefish::Command gnss_grpc_proxy_cmd(cuttlefish::GnssGrpcProxyBinary());
auto instance = config.ForDefaultInstance();
+
auto gnss_in_pipe_name = instance.gnss_in_pipe_name();
-
- auto gnss_out_pipe_name = instance.gnss_out_pipe_name();
-
if (mkfifo(gnss_in_pipe_name.c_str(), 0600) != 0) {
auto error = errno;
LOG(ERROR) << "Failed to create gnss input fifo for crosvm: "
@@ -467,12 +466,14 @@
return;
}
+ auto gnss_out_pipe_name = instance.gnss_out_pipe_name();
if (mkfifo(gnss_out_pipe_name.c_str(), 0660) != 0) {
auto error = errno;
LOG(ERROR) << "Failed to create gnss output fifo for crosvm: "
<< strerror(error);
return;
}
+
// These fds will only be read from or written to, but open them with
// read and write access to keep them open in case the subprocesses exit
cuttlefish::SharedFD gnss_grpc_proxy_in_wr =
@@ -482,6 +483,7 @@
<< gnss_grpc_proxy_in_wr->StrError();
return;
}
+
cuttlefish::SharedFD gnss_grpc_proxy_out_rd =
cuttlefish::SharedFD::Open(gnss_out_pipe_name.c_str(), O_RDWR);
if (!gnss_grpc_proxy_out_rd->IsOpen()) {
@@ -496,7 +498,6 @@
gnss_grpc_proxy_cmd.AddParameter("--gnss_grpc_port=", gnss_grpc_proxy_server_port);
process_monitor->StartSubprocess(std::move(gnss_grpc_proxy_cmd),
GetOnSubprocessExitCallback(config));
-
}
void LaunchSecureEnvironment(cuttlefish::ProcessMonitor* process_monitor,
@@ -538,3 +539,54 @@
process_monitor->StartSubprocess(std::move(grpc_server),
GetOnSubprocessExitCallback(config));
}
+
+void LaunchConsoleForwarderIfEnabled(const cuttlefish::CuttlefishConfig& config,
+ cuttlefish::ProcessMonitor* process_monitor)
+{
+ if (!config.console()) {
+ return;
+ }
+
+ cuttlefish::Command console_forwarder_cmd(cuttlefish::ConsoleForwarderBinary());
+ auto instance = config.ForDefaultInstance();
+
+ auto console_in_pipe_name = instance.console_in_pipe_name();
+ if (mkfifo(console_in_pipe_name.c_str(), 0600) != 0) {
+ auto error = errno;
+ LOG(ERROR) << "Failed to create console input fifo for crosvm: "
+ << strerror(error);
+ return;
+ }
+
+ auto console_out_pipe_name = instance.console_out_pipe_name();
+ if (mkfifo(console_out_pipe_name.c_str(), 0660) != 0) {
+ auto error = errno;
+ LOG(ERROR) << "Failed to create console output fifo for crosvm: "
+ << strerror(error);
+ return;
+ }
+
+ // These fds will only be read from or written to, but open them with
+ // read and write access to keep them open in case the subprocesses exit
+ cuttlefish::SharedFD console_forwarder_in_wr =
+ cuttlefish::SharedFD::Open(console_in_pipe_name.c_str(), O_RDWR);
+ if (!console_forwarder_in_wr->IsOpen()) {
+ LOG(ERROR) << "Failed to open console_forwarder input fifo for writes: "
+ << console_forwarder_in_wr->StrError();
+ return;
+ }
+
+ cuttlefish::SharedFD console_forwarder_out_rd =
+ cuttlefish::SharedFD::Open(console_out_pipe_name.c_str(), O_RDWR);
+ if (!console_forwarder_out_rd->IsOpen()) {
+ LOG(ERROR) << "Failed to open console_forwarder output fifo for reads: "
+ << console_forwarder_out_rd->StrError();
+ return;
+ }
+
+ console_forwarder_cmd.AddParameter("--console_in_fd=", console_forwarder_in_wr);
+ console_forwarder_cmd.AddParameter("--console_out_fd=", console_forwarder_out_rd);
+ process_monitor->StartSubprocess(std::move(console_forwarder_cmd),
+ GetOnSubprocessExitCallback(config));
+
+}
diff --git a/host/commands/run_cvd/launch.h b/host/commands/run_cvd/launch.h
index 9679bcf..974bba9 100644
--- a/host/commands/run_cvd/launch.h
+++ b/host/commands/run_cvd/launch.h
@@ -50,3 +50,6 @@
void LaunchVerhicleHalServerIfEnabled(const cuttlefish::CuttlefishConfig& config,
cuttlefish::ProcessMonitor* process_monitor);
+
+void LaunchConsoleForwarderIfEnabled(const cuttlefish::CuttlefishConfig& config,
+ cuttlefish::ProcessMonitor* process_monitor);
diff --git a/host/commands/run_cvd/main.cc b/host/commands/run_cvd/main.cc
index e57d20c..02ed6eb 100644
--- a/host/commands/run_cvd/main.cc
+++ b/host/commands/run_cvd/main.cc
@@ -501,17 +501,21 @@
PrintStreamingInformation(*config);
- LOG(INFO) << kGreenColor << "To access the console run: screen "
- << instance.console_path() << kResetColor;
+ if (config->console()) {
+ LOG(INFO) << kGreenColor << "To access the console run: screen "
+ << instance.console_path() << kResetColor;
+ } else {
+ LOG(INFO) << kGreenColor
+ << "Serial console is disabled; use -console=true to enable it"
+ << kResetColor;
+ }
LOG(INFO) << kGreenColor
<< "The following files contain useful debugging information:"
<< kResetColor;
- if (config->run_as_daemon()) {
- LOG(INFO) << kGreenColor
- << " Launcher log: " << instance.launcher_log_path()
- << kResetColor;
- }
+ LOG(INFO) << kGreenColor
+ << " Launcher log: " << instance.launcher_log_path()
+ << kResetColor;
LOG(INFO) << kGreenColor
<< " Android's logcat output: " << instance.logcat_path()
<< kResetColor;
@@ -577,6 +581,7 @@
LaunchGnssGrpcProxyServerIfEnabled(*config, &process_monitor);
LaunchSecureEnvironment(&process_monitor, *config);
LaunchVerhicleHalServerIfEnabled(*config, &process_monitor);
+ LaunchConsoleForwarderIfEnabled(*config, &process_monitor);
// The streamer needs to launch before the VMM because it serves on several
// sockets (input devices, vsock frame server) when using crosvm.
diff --git a/host/frontend/webrtc/lib/client_handler.cpp b/host/frontend/webrtc/lib/client_handler.cpp
index 7c5c785..d11c32a 100644
--- a/host/frontend/webrtc/lib/client_handler.cpp
+++ b/host/frontend/webrtc/lib/client_handler.cpp
@@ -381,15 +381,18 @@
reply["type"] = "offer";
reply["sdp"] = offer_str;
+ state_ = State::kAwaitingAnswer;
send_to_client_(reply);
}
void ClientHandler::OnCreateSDPFailure(webrtc::RTCError error) {
+ state_ = State::kFailed;
LogAndReplyError(error.message());
Close();
}
void ClientHandler::OnSetSDPFailure(webrtc::RTCError error) {
+ state_ = State::kFailed;
LogAndReplyError(error.message());
LOG(ERROR) << "Error setting local description: Either there is a bug in "
"libwebrtc or the local description was (incorrectly) modified "
@@ -408,6 +411,14 @@
}
auto type = message["type"].asString();
if (type == "request-offer") {
+ // Can't check for state being different that kNew because renegotiation can
+ // start in any state after the answer is returned.
+ if (state_ == State::kCreatingOffer) {
+ // An offer has been requested already
+ LogAndReplyError("Multiple requests for offer received from single client");
+ return;
+ }
+ state_ = State::kCreatingOffer;
peer_connection_->CreateOffer(
// No memory leak here because this is a ref counted objects and the
// peer connection immediately wraps it with a scoped_refptr
@@ -417,6 +428,10 @@
// The created offer wil be sent to the client on
// OnSuccess(webrtc::SessionDescriptionInterface* desc)
} else if (type == "answer") {
+ if (state_ != State::kAwaitingAnswer) {
+ LogAndReplyError("Received unexpected SDP answer");
+ return;
+ }
auto result = ValidationResult::ValidateJsonObject(message, type,
{{"sdp", Json::ValueType::stringValue}});
if (!result.ok()) {
@@ -441,6 +456,7 @@
}
}));
peer_connection_->SetRemoteDescription(std::move(remote_desc), observer);
+ state_ = State::kConnecting;
} else if (type == "ice-candidate") {
{
@@ -508,6 +524,7 @@
break;
case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
LOG(VERBOSE) << "Client " << client_id_ << ": WebRTC connected";
+ state_ = State::kConnected;
observer_->OnConnected(
[this](const uint8_t *msg, size_t size, bool binary) {
control_handler_->Send(msg, size, binary);
@@ -559,6 +576,7 @@
}
void ClientHandler::OnRenegotiationNeeded() {
+ state_ = State::kNew;
LOG(VERBOSE) << "Client " << client_id_ << " needs renegotiation";
}
@@ -620,6 +638,7 @@
LOG(DEBUG) << "ICE connection state: Completed";
break;
case webrtc::PeerConnectionInterface::kIceConnectionFailed:
+ state_ = State::kFailed;
LOG(DEBUG) << "ICE connection state: Failed";
break;
case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
diff --git a/host/frontend/webrtc/lib/client_handler.h b/host/frontend/webrtc/lib/client_handler.h
index adaec3e..8e1488d 100644
--- a/host/frontend/webrtc/lib/client_handler.h
+++ b/host/frontend/webrtc/lib/client_handler.h
@@ -93,6 +93,14 @@
rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) override;
private:
+ enum class State {
+ kNew,
+ kCreatingOffer,
+ kAwaitingAnswer,
+ kConnecting,
+ kConnected,
+ kFailed,
+ };
ClientHandler(int client_id, std::shared_ptr<ConnectionObserver> observer,
std::function<void(const Json::Value&)> send_client_cb,
std::function<void()> on_connection_closed_cb);
@@ -103,6 +111,7 @@
void LogAndReplyError(const std::string& error_msg) const;
int client_id_;
+ State state_ = State::kNew;
std::shared_ptr<ConnectionObserver> observer_;
std::function<void(const Json::Value&)> send_to_client_;
std::function<void()> on_connection_closed_cb_;
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 3ac9fb1..31ec07c 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -160,6 +160,8 @@
const char* kEnableMinimalMode = "enable_minimal_mode";
+const char* kConsole = "console";
+
} // namespace
namespace cuttlefish {
@@ -743,6 +745,13 @@
(*dictionary_)[kEnableMinimalMode] = enable_minimal_mode;
}
+void CuttlefishConfig::set_console(bool console) {
+ (*dictionary_)[kConsole] = console;
+}
+bool CuttlefishConfig::console() const {
+ return (*dictionary_)[kConsole].asBool();
+}
+
// Creates the (initially empty) config object and populates it with values from
// the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
// Returns nullptr if there was an error loading from file
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index d48cd1b..0f7a6b8 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -286,6 +286,10 @@
void set_kgdb(bool kgdb);
bool kgdb() const;
+ // Serial console
+ void set_console(bool console);
+ bool console() const;
+
// Configuration flags for a minimal device
bool enable_minimal_mode() const;
void set_enable_minimal_mode(bool enable_minimal_mode);
@@ -389,9 +393,11 @@
std::string kernel_log_pipe_name() const;
+ std::string console_pipe_prefix() const;
std::string console_in_pipe_name() const;
std::string console_out_pipe_name() const;
+ std::string gnss_pipe_prefix() const;
std::string gnss_in_pipe_name() const;
std::string gnss_out_pipe_name() const;
diff --git a/host/libs/config/cuttlefish_config_instance.cpp b/host/libs/config/cuttlefish_config_instance.cpp
index 556ac52..d1bca71 100644
--- a/host/libs/config/cuttlefish_config_instance.cpp
+++ b/host/libs/config/cuttlefish_config_instance.cpp
@@ -115,20 +115,28 @@
return cuttlefish::AbsolutePath(PerInstanceInternalPath("kernel-log-pipe"));
}
+std::string CuttlefishConfig::InstanceSpecific::console_pipe_prefix() const {
+ return cuttlefish::AbsolutePath(PerInstanceInternalPath("console"));
+}
+
std::string CuttlefishConfig::InstanceSpecific::console_in_pipe_name() const {
- return cuttlefish::AbsolutePath(PerInstanceInternalPath("console-in-pipe"));
+ return console_pipe_prefix() + ".in";
}
std::string CuttlefishConfig::InstanceSpecific::console_out_pipe_name() const {
- return cuttlefish::AbsolutePath(PerInstanceInternalPath("console-out-pipe"));
+ return console_pipe_prefix() + ".out";
+}
+
+std::string CuttlefishConfig::InstanceSpecific::gnss_pipe_prefix() const {
+ return cuttlefish::AbsolutePath(PerInstanceInternalPath("gnss"));
}
std::string CuttlefishConfig::InstanceSpecific::gnss_in_pipe_name() const {
- return cuttlefish::AbsolutePath(PerInstanceInternalPath("gnss-in-pipe"));
+ return gnss_pipe_prefix() + ".in";
}
std::string CuttlefishConfig::InstanceSpecific::gnss_out_pipe_name() const {
- return cuttlefish::AbsolutePath(PerInstanceInternalPath("gnss-out-pipe"));
+ return gnss_pipe_prefix() + ".out";
}
int CuttlefishConfig::InstanceSpecific::gnss_grpc_proxy_server_port() const {
diff --git a/host/libs/config/kernel_args.cpp b/host/libs/config/kernel_args.cpp
index 1db316e..40f527d 100644
--- a/host/libs/config/kernel_args.cpp
+++ b/host/libs/config/kernel_args.cpp
@@ -61,7 +61,7 @@
if (config.enable_gnss_grpc_proxy()) {
kernel_cmdline.push_back("gnss_cmdline.serdev=serial8250/serial0/serial0-0");
kernel_cmdline.push_back("gnss_cmdline.type=0");
- kernel_cmdline.push_back("serdev_ttyport.pdev_tty_port=ttyS3");
+ kernel_cmdline.push_back("serdev_ttyport.pdev_tty_port=ttyS1");
}
kernel_cmdline.push_back(concat("androidboot.serialno=", instance.serial_number()));
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index aa0b3f1..96239a4 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -220,7 +220,7 @@
// virtio-console driver may not be available for early messages
// In kgdb mode, earlycon is an interactive console, and so early
// dmesg will go there instead of the kernel.log
- if (!(config_->use_bootloader() || config_->kgdb())) {
+ if (!(config_->console() && (config_->use_bootloader() || config_->kgdb()))) {
crosvm_cmd.AddParameter("--serial=hardware=serial,num=1,type=file,path=",
instance.kernel_log_pipe_name(), ",earlycon=true");
}
@@ -231,71 +231,37 @@
crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=1,type=file,path=",
instance.kernel_log_pipe_name(), ",console=true");
- auto console_in_pipe_name = instance.console_in_pipe_name();
- if (mkfifo(console_in_pipe_name.c_str(), 0600) != 0) {
- auto error = errno;
- LOG(ERROR) << "Failed to create console input fifo for crosvm: "
- << strerror(error);
- return {};
- }
- auto console_out_pipe_name = instance.console_out_pipe_name();
- if (mkfifo(console_out_pipe_name.c_str(), 0660) != 0) {
- auto error = errno;
- LOG(ERROR) << "Failed to create console output fifo for crosvm: "
- << strerror(error);
- return {};
- }
-
- // These fds will only be read from or written to, but open them with
- // read and write access to keep them open in case the subprocesses exit
- cuttlefish::SharedFD console_in_wr =
- cuttlefish::SharedFD::Open(console_in_pipe_name.c_str(), O_RDWR);
- if (!console_in_wr->IsOpen()) {
- LOG(ERROR) << "Failed to open console input fifo for writes: "
- << console_in_wr->StrError();
- return {};
- }
- cuttlefish::SharedFD console_out_rd =
- cuttlefish::SharedFD::Open(console_out_pipe_name.c_str(), O_RDWR);
- if (!console_out_rd->IsOpen()) {
- LOG(ERROR) << "Failed to open console output fifo for reads: "
- << console_out_rd->StrError();
- return {};
- }
-
- // stdin is the only currently supported way to write data to a serial port in
- // crosvm. A file (named pipe) is used here instead of stdout to ensure only
- // the serial port output is received by the console forwarder as crosvm may
- // print other messages to stdout.
- if (config_->kgdb() || config_->use_bootloader()) {
- crosvm_cmd.AddParameter("--serial=hardware=serial,num=1,type=file,path=",
- console_out_pipe_name, ",input=", console_in_pipe_name,
- ",earlycon=true");
- // In kgdb mode, we have the interactive console on ttyS0 (both Android's
- // console and kdb), so we can disable the virtio-console port usually
- // allocated to Android's serial console, and redirect it to a sink. This
- // ensures that that the PCI device assignments (and thus sepolicy) don't
- // have to change
- crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=2,type=sink");
+ if (config_->console()) {
+ // stdin is the only currently supported way to write data to a serial port in
+ // crosvm. A file (named pipe) is used here instead of stdout to ensure only
+ // the serial port output is received by the console forwarder as crosvm may
+ // print other messages to stdout.
+ if (config_->kgdb() || config_->use_bootloader()) {
+ crosvm_cmd.AddParameter("--serial=hardware=serial,num=1,type=file,path=",
+ instance.console_out_pipe_name(), ",input=",
+ instance.console_in_pipe_name(), ",earlycon=true");
+ // In kgdb mode, we have the interactive console on ttyS0 (both Android's
+ // console and kdb), so we can disable the virtio-console port usually
+ // allocated to Android's serial console, and redirect it to a sink. This
+ // ensures that that the PCI device assignments (and thus sepolicy) don't
+ // have to change
+ crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=2,type=sink");
+ } else {
+ crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=2,type=file,path=",
+ instance.console_out_pipe_name(), ",input=",
+ instance.console_in_pipe_name());
+ }
} else {
- crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=2,type=file,path=",
- console_out_pipe_name, ",input=", console_in_pipe_name);
+ // as above, create a fake virtio-console 'sink' port when the serial
+ // console is disabled, so the PCI device ID assignments don't move
+ // around
+ crosvm_cmd.AddParameter("--serial=hardware=virtio-console,num=2,type=sink");
}
- cuttlefish::Command console_cmd(ConsoleForwarderBinary());
- console_cmd.AddParameter("--console_in_fd=", console_in_wr);
- console_cmd.AddParameter("--console_out_fd=", console_out_rd);
-
-
if (config_->enable_gnss_grpc_proxy()) {
- auto gnss_in_pipe_name = instance.gnss_in_pipe_name();
- auto gnss_out_pipe_name = instance.gnss_out_pipe_name();
-
-
-
- crosvm_cmd.AddParameter("--serial=hardware=serial,num=4,type=file,path=",
- gnss_out_pipe_name,
- ",input=", gnss_in_pipe_name);
+ crosvm_cmd.AddParameter("--serial=hardware=serial,num=2,type=file,path=",
+ instance.gnss_out_pipe_name(), ",input=",
+ instance.gnss_in_pipe_name());
}
cuttlefish::SharedFD log_out_rd, log_out_wr;
@@ -348,7 +314,6 @@
std::vector<cuttlefish::Command> ret;
ret.push_back(std::move(crosvm_cmd));
- ret.push_back(std::move(console_cmd));
ret.push_back(std::move(log_tee_cmd));
return ret;
}
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index bd5f57c..d9bbfa5 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -38,6 +38,7 @@
#include "common/libs/utils/subprocess.h"
#include "common/libs/utils/users.h"
#include "host/libs/config/cuttlefish_config.h"
+#include "host/libs/config/known_paths.h"
namespace cuttlefish {
namespace vm_manager {
@@ -200,21 +201,17 @@
// In kgdb mode, earlycon is an interactive console, and so early
// dmesg will go there instead of the kernel.log
- if (config_->kgdb() || config_->use_bootloader()) {
- qemu_cmd.AddParameter("-chardev");
- qemu_cmd.AddParameter("socket,id=earlycon,path=",
- instance.console_path(), ",server,nowait");
- } else {
+ if (!(config_->console() && (config_->kgdb() || config_->use_bootloader()))) {
qemu_cmd.AddParameter("-chardev");
qemu_cmd.AddParameter("file,id=earlycon,path=",
instance.kernel_log_pipe_name(), ",append=on");
- }
- // On ARM, -serial will imply an AMBA pl011 serial port. On x86, -serial
- // will imply an ISA serial port. We have set up earlycon for each of these
- // port types, so the setting here should match
- qemu_cmd.AddParameter("-serial");
- qemu_cmd.AddParameter("chardev:earlycon");
+ // On ARM, -serial will imply an AMBA pl011 serial port. On x86, -serial
+ // will imply an ISA serial port. We have set up earlycon for each of these
+ // port types, so the setting here should match
+ qemu_cmd.AddParameter("-serial");
+ qemu_cmd.AddParameter("chardev:earlycon");
+ }
// This sets up the HVC (virtio-serial / virtio-console) port for the kernel
// logging. This will take over the earlycon logging when the module is
@@ -231,18 +228,34 @@
// This handles the Android interactive serial console - /dev/hvc1
- // In kgdb mode, we have the interactive console on ttyS0 (both Android's
- // console and kdb), so we can disable the virtio-console port usually
- // allocated to Android's serial console, and redirect it to a sink. This
- // ensures that that the PCI device assignments (and thus sepolicy) don't
- // have to change
- if (config_->kgdb() || config_->use_bootloader()) {
+ if (config_->console()) {
+ if (config_->kgdb() || config_->use_bootloader()) {
+ qemu_cmd.AddParameter("-chardev");
+ qemu_cmd.AddParameter("pipe,id=earlycon,path=", instance.console_pipe_prefix());
+
+ // On ARM, -serial will imply an AMBA pl011 serial port. On x86, -serial
+ // will imply an ISA serial port. We have set up earlycon for each of these
+ // port types, so the setting here should match
+ qemu_cmd.AddParameter("-serial");
+ qemu_cmd.AddParameter("chardev:earlycon");
+
+ // In kgdb mode, we have the interactive console on ttyS0 (both Android's
+ // console and kdb), so we can disable the virtio-console port usually
+ // allocated to Android's serial console, and redirect it to a sink. This
+ // ensures that that the PCI device assignments (and thus sepolicy) don't
+ // have to change
+ qemu_cmd.AddParameter("-chardev");
+ qemu_cmd.AddParameter("null,id=hvc1");
+ } else {
+ qemu_cmd.AddParameter("-chardev");
+ qemu_cmd.AddParameter("pipe,id=hvc1,path=", instance.console_pipe_prefix());
+ }
+ } else {
+ // as above, create a fake virtio-console 'sink' port when the serial
+ // console is disabled, so the PCI device ID assignments don't move
+ // around
qemu_cmd.AddParameter("-chardev");
qemu_cmd.AddParameter("null,id=hvc1");
- } else {
- qemu_cmd.AddParameter("-chardev");
- qemu_cmd.AddParameter("socket,id=hvc1,path=", instance.console_path(),
- ",server,nowait");
}
qemu_cmd.AddParameter("-device");
@@ -251,6 +264,14 @@
qemu_cmd.AddParameter("-device");
qemu_cmd.AddParameter("virtconsole,bus=virtio-serial1.0,chardev=hvc1");
+ if (config_->enable_gnss_grpc_proxy()) {
+ qemu_cmd.AddParameter("-chardev");
+ qemu_cmd.AddParameter("pipe,id=gnss,path=", instance.gnss_pipe_prefix());
+
+ qemu_cmd.AddParameter("-serial");
+ qemu_cmd.AddParameter("chardev:gnss");
+ }
+
// If configured, this handles logcat forwarding to the host via serial
// (instead of vsocket) - /dev/hvc2