serialize FileHandleMap into TakeoverData

Summary:
This puts the data into the takeover information during takeover
shutdown, but doesn't do anything to pull it out again (that will be in a follow on diff).

The serialization stuff could be done a little bit more efficiently (since we
will perform an extra thrift serialization step just to compute the length, and
repeat it again later), but we're planning on replacing this with thrift
serializing soon, once simpkins diff stack lands, so I'm not losing sleep over
it.

Reviewed By: simpkins

Differential Revision: D6668846

fbshipit-source-id: e6d01428bd506a9e93b427db499770fce0a0983a
This commit is contained in:
Wez Furlong 2018-01-09 22:00:53 -08:00 committed by Facebook Github Bot
parent 1c2a4c3f93
commit 65b2d3c4b1
5 changed files with 40 additions and 7 deletions

View File

@ -164,7 +164,8 @@ folly::Future<TakeoverData> EdenServer::takeoverAll() {
edenMount->getConfig()->getClientDirectory(),
bindMounts,
std::move(channelData.fd),
channelData.connInfo);
channelData.connInfo,
edenMount->getDispatcher()->getFileHandles().serializeMap());
}));
} catch (const std::exception& ex) {
const auto& mountPath = entry.first;

View File

@ -6,6 +6,7 @@ cpp_library(
headers = glob(["*.h"]),
deps = [
"//eden/fs/fuse:fusell",
"//eden/fs/fuse:handlemap-cpp2-types",
"//eden/fs/utils:io",
"//eden/fs/utils:path",
"//folly:file",
@ -18,5 +19,6 @@ cpp_library(
"//folly/io:iobuf",
"//folly/io/async:async",
"//folly/io/async:server_socket",
"//thrift/lib/cpp2/protocol:protocol",
],
)

View File

@ -12,9 +12,11 @@
#include <folly/Format.h>
#include <folly/io/Cursor.h>
#include <folly/io/IOBuf.h>
#include <thrift/lib/cpp2/protocol/Serializer.h>
using folly::IOBuf;
using std::string;
using apache::thrift::CompactSerializer;
namespace facebook {
namespace eden {
@ -30,6 +32,13 @@ IOBuf TakeoverData::serialize() {
bodyLength += sizeof(uint32_t) + bindMount.stringPiece().size();
}
bodyLength += sizeof(fuse_init_out);
// TODO: remove this redundant serialization. We're doing this here
// solely to compute the size of the data. We plan to refactor this
// whole thing to use a single thrift struct; T25009883
auto serializedFileHandleMap =
CompactSerializer::serialize<std::string>(mount.fileHandleMap);
bodyLength += sizeof(uint32_t) + serializedFileHandleMap.size();
}
// Build a buffer with all of the mount paths
@ -68,6 +77,11 @@ IOBuf TakeoverData::serialize() {
// takeover.
app.push(folly::StringPiece{reinterpret_cast<const char*>(&mount.connInfo),
sizeof(mount.connInfo)});
auto serializedFileHandleMap =
CompactSerializer::serialize<std::string>(mount.fileHandleMap);
app.writeBE<uint32_t>(serializedFileHandleMap.size());
app.push(folly::StringPiece{serializedFileHandleMap});
}
return buf;
@ -142,12 +156,19 @@ TakeoverData TakeoverData::deserialize(const IOBuf* buf) {
fuse_init_out connInfo;
cursor.pull(&connInfo, sizeof(connInfo));
auto fileHandleMapLength = cursor.readBE<uint32_t>();
auto fileHandleMapBuffer = cursor.readFixedString(fileHandleMapLength);
auto fileHandleMap =
CompactSerializer::deserialize<SerializedFileHandleMap>(
fileHandleMapBuffer);
data.mountPoints.emplace_back(
AbsolutePath{mountPath},
AbsolutePath{stateDirectory},
std::move(bindMounts),
folly::File{},
connInfo);
connInfo,
std::move(fileHandleMap));
}
return data;

View File

@ -15,6 +15,7 @@
#include <vector>
#include "eden/fs/fuse/FuseTypes.h"
#include "eden/fs/fuse/gen-cpp2/handlemap_types.h"
#include "eden/fs/utils/PathFuncs.h"
namespace folly {
@ -25,6 +26,8 @@ class exception_wrapper;
namespace facebook {
namespace eden {
class SerializedFileHandleMap;
/**
* TakeoverData contains the data exchanged between processes during
* graceful mount point takeover.
@ -37,18 +40,21 @@ class TakeoverData {
AbsolutePathPiece stateDirectory,
const std::vector<AbsolutePath>& bindMountPaths,
folly::File fd,
fuse_init_out connInfo)
fuse_init_out connInfo,
SerializedFileHandleMap&& fileHandleMap)
: mountPath{mountPath},
stateDirectory{stateDirectory},
bindMounts{bindMountPaths},
fuseFD{std::move(fd)},
connInfo{connInfo} {}
connInfo{connInfo},
fileHandleMap{std::move(fileHandleMap)} {}
AbsolutePath mountPath;
AbsolutePath stateDirectory;
std::vector<AbsolutePath> bindMounts;
folly::File fuseFD;
fuse_init_out connInfo;
SerializedFileHandleMap fileHandleMap;
};
/**

View File

@ -169,7 +169,8 @@ TEST(Takeover, simple) {
client1Path,
std::vector<AbsolutePath>{},
folly::File{mount1FusePath.stringPiece(), O_RDWR | O_CREAT},
fuse_init_out{});
fuse_init_out{},
SerializedFileHandleMap{});
auto mount2Path = tmpDirPath + PathComponentPiece{"mount2"};
auto client2Path = tmpDirPath + PathComponentPiece{"client2"};
@ -184,7 +185,8 @@ TEST(Takeover, simple) {
client2Path,
mount2BindMounts,
folly::File{mount2FusePath.stringPiece(), O_RDWR | O_CREAT},
fuse_init_out{});
fuse_init_out{},
SerializedFileHandleMap{});
// Perform the takeover
auto serverSendFuture = serverData.takeoverComplete.getFuture();
@ -283,7 +285,8 @@ TEST(Takeover, manyMounts) {
stateDirectory,
bindMounts,
folly::File{fusePath.stringPiece(), O_RDWR | O_CREAT},
fuse_init_out{});
fuse_init_out{},
SerializedFileHandleMap{});
}
// Perform the takeover