VirtualUsmManager runs in its own process
Bug: 110532566
Test: local & gce
Change-Id: Ia0f6d15389574f4d226b380390428ede5c52e368
diff --git a/host/commands/Android.bp b/host/commands/Android.bp
index 15f7b2f..8c4b898 100644
--- a/host/commands/Android.bp
+++ b/host/commands/Android.bp
@@ -19,4 +19,5 @@
"stop_cvd",
"ivserver",
"record_audio",
+ "virtual_usb_manager",
]
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index 9d8a8e4..af99652 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -40,8 +40,6 @@
"libcuttlefish_host_config",
"libcuttlefish_vm_manager",
"libivserver",
- "libvadb",
- "libusbip",
"libgflags",
"libxml2",
"libjsoncpp",
diff --git a/host/commands/launch/launcher_defs.h b/host/commands/launch/launcher_defs.h
index a6d3372..2732fdf 100644
--- a/host/commands/launch/launcher_defs.h
+++ b/host/commands/launch/launcher_defs.h
@@ -33,6 +33,7 @@
kProcessGroupError = 12,
kMonitorCreationFailed = 13,
kServerError = 14,
+ kUsbV1SocketError = 15,
};
// Actions supported by the launcher server
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index e3a4caf..f3bc1e0 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -32,6 +32,7 @@
#include <memory>
#include <sstream>
#include <string>
+#include <thread>
#include <vector>
#include <gflags/gflags.h>
@@ -52,8 +53,6 @@
#include "host/commands/launch/vsoc_shared_memory.h"
#include "host/libs/config/cuttlefish_config.h"
#include "host/libs/monitor/kernel_log_server.h"
-#include "host/libs/usbip/server.h"
-#include "host/libs/vadb/virtual_adb_server.h"
#include "host/libs/vm_manager/vm_manager.h"
#include "host/libs/vm_manager/libvirt_manager.h"
#include "host/libs/vm_manager/qemu_manager.h"
@@ -122,6 +121,9 @@
DEFINE_string(vnc_server_binary,
vsoc::DefaultHostArtifactsPath("bin/vnc_server"),
"Location of the vnc server binary.");
+DEFINE_string(virtual_usb_manager_binary,
+ vsoc::DefaultHostArtifactsPath("bin/virtual_usb_manager"),
+ "Location of the virtual usb manager binary.");
DEFINE_string(ivserver_binary,
vsoc::DefaultHostArtifactsPath("bin/ivserver"),
"Location of the ivshmem server binary.");
@@ -171,47 +173,6 @@
constexpr char kAdbModeTunnel[] = "tunnel";
constexpr char kAdbModeUsb[] = "usb";
-// VirtualUSBManager manages virtual USB device presence for Cuttlefish.
-class VirtualUSBManager {
- public:
- VirtualUSBManager(const std::string& usbsocket, int vhci_port,
- const std::string& android_usbipsocket)
- : adb_{usbsocket, vhci_port, android_usbipsocket},
- usbip_{android_usbipsocket, adb_.Pool()} {}
-
- ~VirtualUSBManager() = default;
-
- // Initialize Virtual USB and start USB management thread.
- void Start() {
- CHECK(adb_.Init()) << "Could not initialize Virtual ADB server";
- CHECK(usbip_.Init()) << "Could not start USB/IP server";
- std::thread([this] { Thread(); }).detach();
- }
-
- private:
- void Thread() {
- for (;;) {
- cvd::SharedFDSet fd_read;
- fd_read.Zero();
-
- adb_.BeforeSelect(&fd_read);
- usbip_.BeforeSelect(&fd_read);
-
- int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr);
- if (ret <= 0) continue;
-
- adb_.AfterSelect(fd_read);
- usbip_.AfterSelect(fd_read);
- }
- }
-
- vadb::VirtualADBServer adb_;
- vadb::usbip::Server usbip_;
-
- VirtualUSBManager(const VirtualUSBManager&) = delete;
- VirtualUSBManager& operator=(const VirtualUSBManager&) = delete;
-};
-
// KernelLogMonitor receives and monitors kernel log for Cuttlefish.
class KernelLogMonitor {
public:
@@ -367,6 +328,32 @@
return FLAGS_run_adb_connector && AdbTunnelEnabled();
}
+void LaunchUsbServerIfEnabled(vsoc::CuttlefishConfig* config) {
+ if (!AdbUsbEnabled()) {
+ return;
+ }
+ auto socket_name = config->usb_v1_socket_name();
+ auto usb_v1_server = cvd::SharedFD::SocketLocalServer(
+ socket_name.c_str(), false, SOCK_STREAM, 0666);
+ if (!usb_v1_server->IsOpen()) {
+ LOG(ERROR) << "Unable to create USB v1 server socket: "
+ << usb_v1_server->StrError();
+ std::exit(cvd::LauncherExitCodes::kUsbV1SocketError);
+ }
+ int server_fd = usb_v1_server->UNMANAGED_Dup();
+ if (server_fd < 0) {
+ LOG(ERROR) << "Unable to dup USB v1 server socket file descriptor: "
+ << strerror(errno);
+ std::exit(cvd::LauncherExitCodes::kUsbV1SocketError);
+ }
+
+ cvd::subprocess({FLAGS_virtual_usb_manager_binary,
+ "-usb_v1_fd=" + std::to_string(server_fd),
+ GetConfigFileArg()});
+
+ close(server_fd);
+}
+
void LaunchIvServer(vsoc::CuttlefishConfig* config) {
// Resize gralloc region
auto actual_width = cvd::AlignToPowerOf2(FLAGS_x_res * 4, 4); // align to 16
@@ -946,11 +933,7 @@
kmon.Start();
- // Start the usb manager
- VirtualUSBManager vadb(config->usb_v1_socket_name(), config->vhci_port(),
- config->usb_ip_socket_name());
- vadb.Start();
-
+ LaunchUsbServerIfEnabled(config);
LaunchIvServer(config);
// Initialize the regions that require so before the VM starts.
diff --git a/host/commands/virtual_usb_manager/Android.bp b/host/commands/virtual_usb_manager/Android.bp
new file mode 100644
index 0000000..19c3dc6
--- /dev/null
+++ b/host/commands/virtual_usb_manager/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2017 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: "virtual_usb_manager",
+ srcs: [
+ "main.cc",
+ ],
+ header_libs: [
+ "cuttlefish_glog",
+ ],
+ shared_libs: [
+ "vsoc_lib",
+ "libcuttlefish_fs",
+ "libcuttlefish_utils",
+ "cuttlefish_auto_resources",
+ "libbase",
+ ],
+ static_libs: [
+ "libcuttlefish_host_config",
+ "libvadb",
+ "libusbip",
+ "libgflags",
+ "libjsoncpp",
+ ],
+ defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/commands/virtual_usb_manager/main.cc b/host/commands/virtual_usb_manager/main.cc
new file mode 100644
index 0000000..0bcb5bb
--- /dev/null
+++ b/host/commands/virtual_usb_manager/main.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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 <string>
+#include <thread>
+
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/fs/shared_select.h"
+#include "host/libs/config/cuttlefish_config.h"
+#include "host/libs/usbip/server.h"
+#include "host/libs/vadb/virtual_adb_server.h"
+
+DEFINE_int32(
+ usb_v1_fd, -1,
+ "A file descriptor pointing to the USB v1 open socket or -1 to create it");
+
+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) << "Unable to get config object";
+ return 1;
+ }
+
+ cvd::SharedFD usb_v1_server;
+
+ if (FLAGS_usb_v1_fd < 0) {
+ auto socket_name = config->usb_v1_socket_name();
+ LOG(INFO) << "Starting server at " << socket_name;
+ usb_v1_server = cvd::SharedFD::SocketLocalServer(socket_name.c_str(), false,
+ SOCK_STREAM, 0666);
+ } else {
+ usb_v1_server = cvd::SharedFD::Dup(FLAGS_usb_v1_fd);
+ }
+
+ if (!usb_v1_server->IsOpen()) {
+ LOG(ERROR) << "Error openning USB v1 server: " << usb_v1_server->StrError();
+ return 2;
+ }
+
+ vadb::VirtualADBServer adb_{usb_v1_server, config->vhci_port(),
+ config->usb_ip_socket_name()};
+ vadb::usbip::Server usbip_{config->usb_ip_socket_name(), adb_.Pool()};
+
+ CHECK(usbip_.Init()) << "Could not start USB/IP server";
+
+ for (;;) {
+ cvd::SharedFDSet fd_read;
+ fd_read.Zero();
+
+ adb_.BeforeSelect(&fd_read);
+ usbip_.BeforeSelect(&fd_read);
+
+ int ret = cvd::Select(&fd_read, nullptr, nullptr, nullptr);
+ if (ret <= 0) continue;
+
+ adb_.AfterSelect(fd_read);
+ usbip_.AfterSelect(fd_read);
+ }
+
+ return 0;
+}
diff --git a/host/libs/vadb/virtual_adb_server.cpp b/host/libs/vadb/virtual_adb_server.cpp
index fae84d2..86838c0 100644
--- a/host/libs/vadb/virtual_adb_server.cpp
+++ b/host/libs/vadb/virtual_adb_server.cpp
@@ -18,22 +18,6 @@
namespace vadb {
-bool VirtualADBServer::Init() {
- if (name_.empty()) {
- LOG(INFO) << "name_ empty, not starting server socket";
- return true;
- }
- LOG(INFO) << "Starting server socket: " << name_;
-
- server_ =
- cvd::SharedFD::SocketLocalServer(name_.c_str(), false, SOCK_STREAM, 0666);
- if (!server_->IsOpen()) {
- LOG(ERROR) << "Could not create socket: " << server_->StrError();
- return false;
- }
- return true;
-}
-
void VirtualADBServer::BeforeSelect(cvd::SharedFDSet* fd_read) const {
fd_read->Set(server_);
for (const auto& client : clients_) {
diff --git a/host/libs/vadb/virtual_adb_server.h b/host/libs/vadb/virtual_adb_server.h
index 6e09ef7..231ccde 100644
--- a/host/libs/vadb/virtual_adb_server.h
+++ b/host/libs/vadb/virtual_adb_server.h
@@ -26,18 +26,14 @@
// VirtualADBServer manages incoming VirtualUSB/ADB connections from QEmu.
class VirtualADBServer {
public:
- VirtualADBServer(const std::string& usb_socket_name, int vhci_port,
+ VirtualADBServer(cvd::SharedFD usb_v1_socket, int vhci_port,
const std::string& usbip_socket_name)
- : name_(usb_socket_name),
- vhci_port_{vhci_port},
- usbip_name_(usbip_socket_name) {}
+ : vhci_port_{vhci_port},
+ usbip_name_(usbip_socket_name),
+ server_(usb_v1_socket) {}
~VirtualADBServer() = default;
- // Initialize this instance of Server.
- // Returns true, if initialization was successful.
- bool Init();
-
// Pool of USB devices available to export.
const usbip::DevicePool& Pool() const { return pool_; };
@@ -53,7 +49,6 @@
void HandleIncomingConnection();
usbip::DevicePool pool_;
- std::string name_;
int vhci_port_{};
std::string usbip_name_;
cvd::SharedFD server_;