Merge "Merges FrameBuffer and FBBroadcast regions into a single Screen region" into gce-dev
diff --git a/common/commands/socket_forward_proxy/Android.bp b/common/commands/socket_forward_proxy/Android.bp
index 07d02ce..9819e9d 100644
--- a/common/commands/socket_forward_proxy/Android.bp
+++ b/common/commands/socket_forward_proxy/Android.bp
@@ -5,6 +5,7 @@
],
shared_libs: [
"libbase",
+ "libcuttlefish_fs",
"vsoc_lib",
"liblog",
"cuttlefish_tcp_socket",
diff --git a/common/commands/socket_forward_proxy/main.cpp b/common/commands/socket_forward_proxy/main.cpp
index cec1b05..cb1fadb 100644
--- a/common/commands/socket_forward_proxy/main.cpp
+++ b/common/commands/socket_forward_proxy/main.cpp
@@ -26,13 +26,14 @@
#include <unistd.h>
+#include "common/libs/fs/shared_fd.h"
#include "common/vsoc/lib/socket_forward_region_view.h"
-#include "common/libs/tcp_socket/tcp_socket.h"
#ifdef CUTTLEFISH_HOST
#include "host/libs/config/host_config.h"
#endif
+using vsoc::socket_forward::Packet;
using vsoc::socket_forward::SocketForwardRegionView;
#ifdef CUTTLEFISH_HOST
@@ -43,7 +44,7 @@
class Worker {
public:
Worker(SocketForwardRegionView::Connection shm_connection,
- cvd::ClientSocket socket)
+ cvd::SharedFD socket)
: shm_connection_(std::move(shm_connection)),
socket_(std::move(socket)){}
@@ -54,7 +55,7 @@
return true;
}
}
- if (shm_connection_.closed() || socket_.closed()) {
+ if (shm_connection_.closed() || !socket_->IsOpen()) {
std::lock_guard<std::mutex> guard(closed_lock_);
closed_ = true;
}
@@ -76,35 +77,54 @@
private:
void SocketToShmImpl() {
- constexpr int kRecvSize = 8192;
+ auto shm_sender = shm_connection_.MakeSender();
- auto sender = shm_connection_.MakeSender();
-
+ auto packet = Packet::MakeData();
while (true) {
if (closed()) {
break;
}
- auto msg = socket_.RecvAny(kRecvSize);
- if (msg.empty()) {
+ auto size = socket_->Recv(packet.payload(), sizeof packet.payload(), 0);
+ if (size <= 0) {
break;
}
- sender.Send(std::move(msg));
+ packet.set_payload_length(size);
+ shm_sender.Send(packet);
}
LOG(INFO) << "Socket to shm exiting";
close();
}
+ ssize_t SocketSendAll(const Packet& packet) {
+ ssize_t written{};
+ while (written < static_cast<ssize_t>(packet.payload_length())) {
+ if (!socket_->IsOpen()) {
+ return -1;
+ }
+ auto just_written = socket_->Write(packet.payload() + written,
+ packet.payload_length() - written);
+ if (just_written <= 0) {
+ LOG(INFO) << "Couldn't write to client: "
+ << strerror(socket_->GetErrno());
+ return just_written;
+ }
+ written += just_written;
+ }
+ return written;
+ }
+
void ShmToSocketImpl() {
- auto receiver = shm_connection_.MakeReceiver();
+ auto shm_receiver = shm_connection_.MakeReceiver();
+ Packet packet{};
while (true) {
if (closed()) {
break;
}
- auto msg = receiver.Recv();
- if (msg.empty() || socket_.closed()) {
+ shm_receiver.Recv(&packet);
+ if (packet.IsEnd()) {
break;
}
- if (socket_.Send(msg) < 0) {
+ if (SocketSendAll(packet) < 0) {
break;
}
}
@@ -113,7 +133,7 @@
}
SocketForwardRegionView::Connection shm_connection_;
- cvd::ClientSocket socket_;
+ cvd::SharedFD socket_;
bool closed_{};
std::mutex closed_lock_;
};
@@ -121,7 +141,7 @@
// One thread for reading from shm and writing into a socket.
// One thread for reading from a socket and writing into shm.
void LaunchWorkers(SocketForwardRegionView::Connection conn,
- cvd::ClientSocket socket) {
+ cvd::SharedFD socket) {
auto worker = std::make_shared<Worker>(std::move(conn), std::move(socket));
std::thread threads[] = {std::thread(Worker::SocketToShm, worker),
std::thread(Worker::ShmToSocket, worker)};
@@ -133,9 +153,11 @@
#ifdef CUTTLEFISH_HOST
[[noreturn]] void host(SocketForwardRegionView* shm, int port) {
LOG(INFO) << "starting server on " << port;
- cvd::ServerSocket server(port);
+ auto server = cvd::SharedFD::SocketLocalServer(port, SOCK_STREAM);
+ CHECK(server->IsOpen()) << "Could not start server on port " << port;
while (true) {
- auto client_socket = server.Accept();
+ auto client_socket = cvd::SharedFD::Accept(*server);
+ CHECK(client_socket->IsOpen()) << "error creating client socket";
LOG(INFO) << "client socket accepted";
auto conn = shm->OpenConnection(port);
LOG(INFO) << "shm connection opened";
@@ -148,7 +170,8 @@
while (true) {
auto conn = shm->AcceptConnection();
LOG(INFO) << "shm connection accepted";
- auto sock = cvd::ClientSocket(conn.port());
+ auto sock = cvd::SharedFD::SocketLocalClient(conn.port(), SOCK_STREAM);
+ CHECK(sock->IsOpen()) << "Could not open socket to port " << conn.port();
LOG(INFO) << "socket opened to " << conn.port();
LaunchWorkers(std::move(conn), std::move(sock));
}
@@ -170,7 +193,7 @@
// makes sure we're running as root on the guest, no-op on the host
void assert_correct_user() {
#ifndef CUTTLEFISH_HOST
- CHECK_EQ(getuid(), 0u) << "must run as root!";
+ CHECK_EQ(getuid(), 0u) << "must run as root!";
#endif
}
diff --git a/common/vsoc/lib/socket_forward_region_view.cpp b/common/vsoc/lib/socket_forward_region_view.cpp
index b56dde4..102a827 100644
--- a/common/vsoc/lib/socket_forward_region_view.cpp
+++ b/common/vsoc/lib/socket_forward_region_view.cpp
@@ -39,69 +39,44 @@
guest_to_host;
#endif
-using vsoc::socket_forward::Message;
using vsoc::socket_forward::SocketForwardRegionView;
-constexpr std::int32_t kConnectionBegin = -1;
-constexpr std::int32_t kConnectionEnd = -2;
-
-Message SocketForwardRegionView::Recv(int connection_id) {
- std::int32_t len{};
- (data()->queues_[connection_id].*ReadDirection)
- .Read(this, reinterpret_cast<char*>(&len), sizeof len);
- if (len == kConnectionEnd) {
- return {};
- }
- CHECK_NE(len, 0) << "zero-size message received";
- CHECK_GT(len, 0) << "invalid size";
- Message message(len);
- (data()->queues_[connection_id].*ReadDirection)
- .Read(this, reinterpret_cast<char*>(message.data()), message.size());
- return message;
+void SocketForwardRegionView::Recv(int connection_id, Packet* packet) {
+ CHECK(packet != nullptr);
+ do {
+ (data()->queues_[connection_id].*ReadDirection)
+ .Read(this, reinterpret_cast<char*>(packet), sizeof *packet);
+ } while (packet->IsBegin());
+ // TODO(haining) check packet generation number
+ CHECK(!packet->empty()) << "zero-size data message received";
+ CHECK_LE(packet->payload_length(), kMaxPayloadSize) << "invalid size";
}
-void SocketForwardRegionView::Send(int connection_id, const Message& message) {
- if (message.empty()) {
+void SocketForwardRegionView::Send(int connection_id, const Packet& packet) {
+ if (packet.empty()) {
+ LOG(WARNING) << "ignoring empty packet (not sending)";
return;
}
- std::int32_t len = message.size();
+ // TODO(haining) set packet generation number
+ CHECK_LE(packet.payload_length(), kMaxPayloadSize);
(data()->queues_[connection_id].*WriteDirection)
- .Write(this, reinterpret_cast<const char*>(&len), sizeof len);
- (data()->queues_[connection_id].*WriteDirection)
- .Write(this, reinterpret_cast<const char*>(message.data()),
- message.size());
+ .Write(this, packet.raw_data(), packet.raw_data_length());
}
void SocketForwardRegionView::SendBegin(int connection_id) {
- (data()->queues_[connection_id].*WriteDirection)
- .Write(this, reinterpret_cast<const char*>(&kConnectionBegin),
- sizeof kConnectionBegin);
+ Send(connection_id, Packet::MakeBegin());
}
void SocketForwardRegionView::SendEnd(int connection_id) {
- (data()->queues_[connection_id].*WriteDirection)
- .Write(this, reinterpret_cast<const char*>(&kConnectionEnd),
- sizeof kConnectionEnd);
+ Send(connection_id, Packet::MakeEnd());
}
void SocketForwardRegionView::IgnoreUntilBegin(int connection_id) {
- Message ignored(128);
- while (true) {
- std::int32_t len{};
+ Packet packet{};
+ do {
(data()->queues_[connection_id].*ReadDirection)
- .Read(this, reinterpret_cast<char*>(&len), sizeof len);
- if (len == kConnectionBegin) {
- break;
- } else if (len == kConnectionEnd) {
- continue;
- }
-
- CHECK_NE(len, 0) << "zero-size message received";
- CHECK_GT(len, 0) << "invalid size";
- ignored.resize(len);
- (data()->queues_[connection_id].*ReadDirection)
- .Read(this, reinterpret_cast<char*>(ignored.data()), ignored.size());
- }
+ .Read(this, reinterpret_cast<char*>(&packet), sizeof packet);
+ } while (!packet.IsBegin()); // TODO(haining) check generation number
}
#ifdef CUTTLEFISH_HOST
@@ -231,8 +206,8 @@
view_->IgnoreUntilBegin(connection_id_);
}
-Message SocketForwardRegionView::Connection::Recv() {
- return view_->Recv(connection_id_);
+void SocketForwardRegionView::Connection::Recv(Packet* packet) {
+ return view_->Recv(connection_id_, packet);
}
bool SocketForwardRegionView::Connection::closed() const {
@@ -247,10 +222,10 @@
view_->SendBegin(connection_id_);
}
-void SocketForwardRegionView::Connection::Send(const Message& message) {
+void SocketForwardRegionView::Connection::Send(const Packet& packet) {
if (closed()) {
LOG(INFO) << "connection closed, not sending\n";
return;
}
- view_->Send(connection_id_, message);
+ view_->Send(connection_id_, packet);
}
diff --git a/common/vsoc/lib/socket_forward_region_view.h b/common/vsoc/lib/socket_forward_region_view.h
index 1e4fe0d..89da339 100644
--- a/common/vsoc/lib/socket_forward_region_view.h
+++ b/common/vsoc/lib/socket_forward_region_view.h
@@ -25,7 +25,102 @@
namespace vsoc {
namespace socket_forward {
-using Message = std::vector<std::uint8_t>;
+struct Header {
+ std::uint32_t payload_length;
+ std::uint32_t generation;
+ enum MessageType : std::uint32_t {
+ DATA = 0,
+ BEGIN,
+ END,
+ };
+ MessageType message_type;
+};
+
+constexpr std::size_t kMaxPayloadSize =
+ layout::socket_forward::kMaxPacketSize - sizeof(Header);
+
+struct Packet {
+ private:
+ Header header_;
+ using Payload = char[kMaxPayloadSize];
+ Payload payload_data_;
+
+ static Packet MakePacket(Header::MessageType type) {
+ Packet packet{};
+ packet.header_.message_type = type;
+ return packet;
+ }
+
+ public:
+ static Packet MakeBegin() {
+ return MakePacket(Header::BEGIN);
+ }
+
+ static Packet MakeEnd() {
+ return MakePacket(Header::END);
+ }
+
+ static Packet MakeData() {
+ return MakePacket(Header::DATA);
+ }
+
+ bool empty() const {
+ return header_.message_type == Header::DATA && header_.payload_length == 0;
+ }
+
+ void set_payload_length(std::uint32_t length) {
+ CHECK_LE(length, sizeof payload_data_);
+ header_.message_type = Header::DATA;
+ header_.payload_length = length;
+ }
+
+ std::uint32_t generation() const {
+ return header_.generation;
+ }
+
+ void set_generation(std::uint32_t generation) {
+ header_.generation = generation;
+ }
+
+ Payload& payload() {
+ return payload_data_;
+ }
+
+ const Payload& payload() const {
+ return payload_data_;
+ }
+
+ std::uint32_t payload_length() const {
+ return header_.payload_length;
+ }
+
+ bool IsBegin() const {
+ return header_.message_type == Header::BEGIN;
+ }
+
+ bool IsEnd() const {
+ return header_.message_type == Header::END;
+ }
+
+ bool IsData() const {
+ return header_.message_type == Header::DATA;
+ }
+
+ char* raw_data() {
+ return reinterpret_cast<char*>(this);
+ }
+
+ const char* raw_data() const {
+ return reinterpret_cast<const char*>(this);
+ }
+
+ size_t raw_data_length() const {
+ return payload_length() + sizeof header_;
+ }
+};
+
+static_assert(sizeof(Packet) == layout::socket_forward::kMaxPacketSize, "");
+static_assert(std::is_pod<Packet>{}, "");
// Data sent will start with a uint32_t indicating the number of bytes being
// sent, followed be the data itself
@@ -40,17 +135,17 @@
void ReleaseConnectionID(int connection_id);
std::pair<int, int> GetWaitingConnectionIDAndPort();
- // Returns an empty Message if the other side is closed.
- Message Recv(int connection_id);
- // Does nothing if message is empty
- void Send(int connection_id, const Message& message);
+ // Returns an empty data packet if the other side is closed.
+ void Recv(int connection_id, Packet* packet);
+ // Does nothing if packet is empty
+ void Send(int connection_id, const Packet& packet);
void SendBegin(int connection_id);
void SendEnd(int connection_id);
- // skip everything in the connection queue until seeing the beginning of
- // the next message
+ // skip everything in the connection queue until seeing a BEGIN
void IgnoreUntilBegin(int connection_id);
+
bool IsOtherSideClosed(int connection_id);
public:
@@ -82,12 +177,12 @@
private:
// Sends should be done using a Sender.
- void Send(const Message& message);
+ void Send(const Packet& packet);
void SendBegin();
void SendEnd();
// Receives should be done using a Receiver.
- Message Recv();
+ void Recv(Packet* packet);
void IgnoreUntilBegin();
struct Releaser {
@@ -119,8 +214,8 @@
connection_->SendBegin();
}
- void Send(const Message& message) {
- connection_->Send(message);
+ void Send(const Packet& packet) {
+ connection_->Send(packet);
}
private:
@@ -143,8 +238,8 @@
connection_->IgnoreUntilBegin();
}
- Message Recv() {
- return connection_->Recv();
+ void Recv(Packet* packet) {
+ return connection_->Recv(packet);
}
private:
diff --git a/common/vsoc/shm/socket_forward_layout.h b/common/vsoc/shm/socket_forward_layout.h
index 970662d..9f4de05 100644
--- a/common/vsoc/shm/socket_forward_layout.h
+++ b/common/vsoc/shm/socket_forward_layout.h
@@ -25,11 +25,13 @@
namespace layout {
namespace socket_forward {
+constexpr std::size_t kMaxPacketSize = 8192;
+
struct QueuePair {
// Traffic originating from host that proceeds towards guest.
- CircularPacketQueue<16, 8192> host_to_guest;
+ CircularPacketQueue<16, kMaxPacketSize> host_to_guest;
// Traffic originating from guest that proceeds towards host.
- CircularPacketQueue<16, 8192> guest_to_host;
+ CircularPacketQueue<16, kMaxPacketSize> guest_to_host;
enum QueueState : std::uint32_t {
INACTIVE = 0,
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index d1a0443..a2930e3 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -104,10 +104,6 @@
"Location of the system partition images.");
DEFINE_string(vendor_image, "", "Location of the vendor partition image.");
-std::string g_default_uuid{
- GetPerInstanceDefault("699acfc4-c8c4-11e7-882b-5065f31dc1")};
-DEFINE_string(uuid, g_default_uuid.c_str(),
- "UUID to use for the device. Random if not specified");
DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
" host kernel. This is only used during transition of our clients."
" Will be deprecated soon.");
@@ -127,6 +123,8 @@
DEFINE_int32(socket_forward_proxy_port, 5555, "port on which to run the "
"socket_forward_proxy server");
+DECLARE_string(uuid);
+
namespace {
const std::string kDataPolicyUseExisting = "use_existing";
const std::string kDataPolicyCreateIfMissing = "create_if_missing";
diff --git a/host/libs/config/host_config.cpp b/host/libs/config/host_config.cpp
index 9acd663..cc0218d 100644
--- a/host/libs/config/host_config.cpp
+++ b/host/libs/config/host_config.cpp
@@ -24,12 +24,13 @@
#include <gflags/gflags.h>
-const char vsoc_user_prefix[] = "vsoc-";
+const char kVsocUserPrefix[] = "vsoc-";
+const char kDefaultUuidPrefix[] = "699acfc4-c8c4-11e7-882b-5065f31dc1";
int GetDefaultInstance() {
char* user = getenv("USER");
- if (user && !memcmp(user, vsoc_user_prefix, sizeof(vsoc_user_prefix) - 1)) {
- int temp = atoi(user + sizeof(vsoc_user_prefix) - 1);
+ if (user && !memcmp(user, kVsocUserPrefix, sizeof(kVsocUserPrefix) - 1)) {
+ int temp = atoi(user + sizeof(kVsocUserPrefix) - 1);
if (temp > 0) {
return temp;
}
@@ -41,6 +42,8 @@
"Path to the ivshmem client socket");
DEFINE_int32(instance, GetDefaultInstance(),
"Instance number. Must be unique.");
+DEFINE_string(uuid, vsoc::GetPerInstanceDefault(kDefaultUuidPrefix).c_str(),
+ "UUID to use for the device. Random if not specified");
std::string vsoc::GetPerInstanceDefault(const char* prefix) {
std::ostringstream stream;
@@ -54,7 +57,9 @@
}
std::string vsoc::GetDefaultPerInstanceDir() {
- return vsoc::GetPerInstanceDefault("/var/run/cvd-");
+ std::ostringstream stream;
+ stream << "/var/run/libvirt-" << kDefaultUuidPrefix;
+ return vsoc::GetPerInstanceDefault(stream.str().c_str());
}
std::string vsoc::GetDefaultPerInstancePath(const std::string& basename) {