diff options
author | Steve Kim <kwstephenkim@google.com> | 2023-04-14 18:33:02 -0700 |
---|---|---|
committer | Steve Kim <kwstephenkim@google.com> | 2023-04-20 17:16:22 -0700 |
commit | d79ae01ba085612959283b7881283d92806352c2 (patch) | |
tree | 428a8f9f8a85276595d8a1737e38f9bdec023df2 /host | |
parent | 8a429379987033bc134f458ef0ecb0ef0b71a9bc (diff) | |
download | cuttlefish-d79ae01ba085612959283b7881283d92806352c2.tar.gz |
Save in-memory data to a memory file
The restart-server handler and the server should implement
functions to save the in-memory data in a memory file.
Bug: 232028559
Test: cvd version && cvd restart-server
Change-Id: Ic7e8351acad19cb58287a4e74fddbd8a006c2dd1
Diffstat (limited to 'host')
-rw-r--r-- | host/commands/cvd/server.cc | 13 | ||||
-rw-r--r-- | host/commands/cvd/server.h | 3 | ||||
-rw-r--r-- | host/commands/cvd/server_command/restart.cpp | 41 |
3 files changed, 49 insertions, 8 deletions
diff --git a/host/commands/cvd/server.cc b/host/commands/cvd/server.cc index 407801323..e73f3b8e8 100644 --- a/host/commands/cvd/server.cc +++ b/host/commands/cvd/server.cc @@ -469,4 +469,17 @@ Result<int> CvdServerMain(SharedFD server_fd, SharedFD carryover_client) { return 0; } +Result<std::string> ReadAllFromMemFd(const SharedFD& mem_fd) { + const auto n_message_size = mem_fd->LSeek(0, SEEK_END); + CF_EXPECT_NE(n_message_size, -1, "LSeek on the memory file failed."); + std::vector<char> buffer(n_message_size); + CF_EXPECT_EQ(mem_fd->LSeek(0, SEEK_SET), 0, mem_fd->StrError()); + auto n_read = ReadExact(mem_fd, buffer.data(), n_message_size); + CF_EXPECT(n_read == n_message_size, + "Expected to read " << n_message_size << " bytes but actually read " + << n_read << " bytes."); + std::string message(buffer.begin(), buffer.end()); + return message; +} + } // namespace cuttlefish diff --git a/host/commands/cvd/server.h b/host/commands/cvd/server.h index de7ca02b3..d6dd79ed9 100644 --- a/host/commands/cvd/server.h +++ b/host/commands/cvd/server.h @@ -93,4 +93,7 @@ Result<CvdServerHandler*> RequestHandler( Result<int> CvdServerMain(SharedFD server_fd, SharedFD carryover_client); +// Read all contents from the file +Result<std::string> ReadAllFromMemFd(const SharedFD& mem_fd); + } // namespace cuttlefish diff --git a/host/commands/cvd/server_command/restart.cpp b/host/commands/cvd/server_command/restart.cpp index 4c005095e..122df8d2b 100644 --- a/host/commands/cvd/server_command/restart.cpp +++ b/host/commands/cvd/server_command/restart.cpp @@ -18,18 +18,20 @@ #include <sys/types.h> +#include <cstdio> #include <iostream> #include <android-base/file.h> -#include <android-base/strings.h> #include <fruit/fruit.h> #include "cvd_server.pb.h" #include "common/libs/fs/shared_buf.h" #include "common/libs/fs/shared_fd.h" +#include "common/libs/utils/contains.h" #include "common/libs/utils/result.h" -#include "host/commands/cvd/flag.h" +#include "host/commands/cvd/common_utils.h" +#include "host/commands/cvd/epoll_loop.h" #include "host/commands/cvd/frontline_parser.h" #include "host/commands/cvd/instance_manager.h" #include "host/commands/cvd/server_command/components.h" @@ -42,6 +44,7 @@ namespace { constexpr char kRestartServerHelpMessage[] = R"(Cuttlefish Virtual Device (CVD) CLI. + usage: cvd restart-server <common args> <mode> <mode args> Common Args: @@ -101,11 +104,7 @@ class CvdRestartHandler : public CvdServerHandler { Result<cvd::Response> Handle(const RequestWithStdio& request) override { CF_EXPECT(CanHandle(request)); - CF_EXPECT(request.Credentials() != std::nullopt); - const uid_t uid = request.Credentials()->uid; cvd::Response response; - response.mutable_shutdown_response(); - if (request.Message().has_shutdown_request()) { response.mutable_shutdown_response(); } else { @@ -130,7 +129,7 @@ class CvdRestartHandler : public CvdServerHandler { return response; } - if (instance_manager_.HasInstanceGroups(uid)) { + if (instance_manager_.HasInstanceGroups(getuid())) { response.mutable_status()->set_code(cvd::Status::FAILED_PRECONDITION); response.mutable_status()->set_message( "Cannot restart cvd_server while devices are being tracked. " @@ -138,9 +137,19 @@ class CvdRestartHandler : public CvdServerHandler { return response; } + // On CF_ERR, the locks will be released automatically WriteAll(request.Out(), "Stopping the cvd_server.\n"); server_.Stop(); + CF_EXPECT(request.Credentials() != std::nullopt); + const uid_t client_uid = request.Credentials()->uid; + auto json_string = + CF_EXPECT(SerializedInstanceDatabaseToString(client_uid)); + std::optional<SharedFD> mem_fd; + if (instance_manager_.HasInstanceGroups(client_uid)) { + mem_fd = CF_EXPECT(CreateMemFileWithSerializedDb(json_string)); + } + const std::string subcmd = parsed.subcmd.value_or("reuse-server"); SharedFD new_exe; CF_EXPECT(Contains(supported_modes_, subcmd), @@ -153,7 +162,7 @@ class CvdRestartHandler : public CvdServerHandler { } else if (subcmd == "reuse-server") { new_exe = CF_EXPECT(NewExecFromPath(request, kServerExecPath)); } else { - return CF_ERR("Unrecognized command line"); + return CF_ERR("unsupported subcommand"); } CF_EXPECT(server_.Exec(new_exe, request.Client())); return CF_ERR("Should be unreachable"); @@ -227,6 +236,22 @@ class CvdRestartHandler : public CvdServerHandler { return new_exe; } + Result<std::string> SerializedInstanceDatabaseToString( + const uid_t client_uid) { + auto db_json = CF_EXPECT(instance_manager_.Serialize(client_uid), + "Failed to serialized instance database"); + return db_json.toStyledString(); + } + + Result<SharedFD> CreateMemFileWithSerializedDb( + const std::string& json_string) { + const std::string mem_file_name = "cvd_server_" + std::to_string(getpid()); + auto mem_fd = SharedFD::MemfdCreateWithData(mem_file_name, json_string); + CF_EXPECT(mem_fd->IsOpen(), + "MemfdCreateWithData failed: " << mem_fd->StrError()); + return mem_fd; + } + BuildApi& build_api_; std::vector<std::string> supported_modes_; FlagCollection flags_; |