mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
18084befa0
Summary: With this gone, we will be able to rename and move Stub.h outside of the win directory. Reviewed By: genevievehelsel Differential Revision: D23696243 fbshipit-source-id: ea05b10951fa38a77ce38cd6a09a293364dbeec9
226 lines
6.4 KiB
C++
226 lines
6.4 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <folly/File.h>
|
|
#include <folly/futures/Promise.h>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
#include "eden/fs/takeover/gen-cpp2/takeover_types.h"
|
|
#include "eden/fs/utils/PathFuncs.h"
|
|
|
|
#ifndef _WIN32
|
|
#include "eden/fs/fuse/FuseTypes.h"
|
|
#else
|
|
#include "eden/fs/win/utils/Stub.h" // @manual
|
|
#endif
|
|
|
|
namespace folly {
|
|
class IOBuf;
|
|
class exception_wrapper;
|
|
} // namespace folly
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
// Holds the versions supported by this build.
|
|
extern const std::set<int32_t> kSupportedTakeoverVersions;
|
|
|
|
/**
|
|
* TakeoverData contains the data exchanged between processes during
|
|
* graceful mount point takeover.
|
|
*/
|
|
class TakeoverData {
|
|
public:
|
|
enum : int32_t {
|
|
// The list of possible versions supported by the client
|
|
// and server in this build of the code. If/when we
|
|
// bump the version we will retain support for the prior
|
|
// version in both the client and server in order to
|
|
// allow rolling back a new build.
|
|
|
|
// This is a protocol version that we will never support.
|
|
// It is included in this enum to reserve it and so that
|
|
// we can use it in tests
|
|
kTakeoverProtocolVersionNeverSupported = 0,
|
|
|
|
// This is the protocol version supported by eden just prior
|
|
// to this protocol versioning code being written
|
|
kTakeoverProtocolVersionOne = 1,
|
|
|
|
// This version introduced thrift encoding of the takeover structures.
|
|
// It is nominally version 2 but named 3 here because VersionOne
|
|
// responses don't include a version header, but do always respond
|
|
// with either a word set to either 1 or 2. To disambiguate things
|
|
// we want to use word value 3 to indicate this new protocol, but
|
|
// naming the symbol Version3 and assigning it the value 3 seemed
|
|
// like too much of a headache, so we simply skip over using
|
|
// version 2 to describe this next one.
|
|
kTakeoverProtocolVersionThree = 3,
|
|
|
|
// This version introduced an additonal handshake before taking over
|
|
// that is sent after the TakeoverData is ready but before actually
|
|
// sending it. This is in order to make sure we only send the data if
|
|
// the new process is healthy and able to receive, because otherwise
|
|
// we would want to recover ourselves. While this does not change
|
|
// the actual data format of the TakeoverData, it does change the
|
|
// number of sends/receives, and this additional handshake would
|
|
// break a server with this extra handshake talking to a client
|
|
// without it
|
|
kTakeoverProtocolVersionFour = 4,
|
|
};
|
|
|
|
// Given a set of versions provided by a client, find the largest
|
|
// version that is also present in the provided set of supported
|
|
// versions.
|
|
static std::optional<int32_t> computeCompatibleVersion(
|
|
const std::set<int32_t>& versions,
|
|
const std::set<int32_t>& supported = kSupportedTakeoverVersions);
|
|
|
|
struct MountInfo {
|
|
MountInfo(
|
|
AbsolutePathPiece mountPath,
|
|
AbsolutePathPiece stateDirectory,
|
|
const std::vector<AbsolutePath>& bindMountPaths,
|
|
folly::File fd,
|
|
#ifndef _WIN32
|
|
fuse_init_out connInfo,
|
|
#endif
|
|
SerializedInodeMap&& inodeMap)
|
|
: mountPath{mountPath},
|
|
stateDirectory{stateDirectory},
|
|
bindMounts{bindMountPaths},
|
|
fuseFD{std::move(fd)},
|
|
#ifndef _WIN32
|
|
connInfo{connInfo},
|
|
#endif
|
|
inodeMap{std::move(inodeMap)} {
|
|
}
|
|
|
|
AbsolutePath mountPath;
|
|
AbsolutePath stateDirectory;
|
|
std::vector<AbsolutePath> bindMounts;
|
|
folly::File fuseFD;
|
|
#ifndef _WIN32
|
|
fuse_init_out connInfo;
|
|
#endif
|
|
SerializedInodeMap inodeMap;
|
|
};
|
|
|
|
/**
|
|
* Serialize the TakeoverData into a buffer that can be sent to a remote
|
|
* process.
|
|
*
|
|
* This includes all data except for file descriptors. The file descriptors
|
|
* must be sent separately.
|
|
*/
|
|
folly::IOBuf serialize(int32_t protocolVersion);
|
|
|
|
/**
|
|
* Serialize an exception.
|
|
*/
|
|
static folly::IOBuf serializeError(
|
|
int32_t protocolVersion,
|
|
const folly::exception_wrapper& ew);
|
|
|
|
/**
|
|
* Create a ping to send.
|
|
*/
|
|
static folly::IOBuf serializePing();
|
|
|
|
/**
|
|
* Deserialize the TakeoverData from a buffer.
|
|
*/
|
|
static TakeoverData deserialize(folly::IOBuf* buf);
|
|
|
|
/**
|
|
* Checks to see if a message is of type PING
|
|
*/
|
|
static bool isPing(const folly::IOBuf* buf);
|
|
|
|
/**
|
|
* The main eden lock file that prevents two edenfs processes from running at
|
|
* the same time.
|
|
*/
|
|
folly::File lockFile;
|
|
|
|
/**
|
|
* The thrift server socket.
|
|
*/
|
|
folly::File thriftSocket;
|
|
|
|
/**
|
|
* The list of mount points.
|
|
*/
|
|
std::vector<MountInfo> mountPoints;
|
|
|
|
/**
|
|
* The takeoverComplete promise will be fulfilled by the TakeoverServer code
|
|
* once the TakeoverData has been sent to the remote process.
|
|
*/
|
|
folly::Promise<std::optional<TakeoverData>> takeoverComplete;
|
|
|
|
private:
|
|
/**
|
|
* Serialize data using version 1 of the takeover protocol.
|
|
*/
|
|
folly::IOBuf serializeVersion1();
|
|
|
|
/**
|
|
* Serialize an exception using version 1 of the takeover protocol.
|
|
*/
|
|
static folly::IOBuf serializeErrorVersion1(
|
|
const folly::exception_wrapper& ew);
|
|
|
|
/**
|
|
* Deserialize the TakeoverData from a buffer using version 1 of the takeover
|
|
* protocol.
|
|
*/
|
|
static TakeoverData deserializeVersion1(folly::IOBuf* buf);
|
|
|
|
/**
|
|
* Serialize data using version 2 of the takeover protocol.
|
|
*/
|
|
folly::IOBuf serializeVersion3();
|
|
|
|
/**
|
|
* Serialize an exception using version 2 of the takeover protocol.
|
|
*/
|
|
static folly::IOBuf serializeErrorVersion3(
|
|
const folly::exception_wrapper& ew);
|
|
|
|
/**
|
|
* Deserialize the TakeoverData from a buffer using version 2 of the takeover
|
|
* protocol.
|
|
*/
|
|
static TakeoverData deserializeVersion3(folly::IOBuf* buf);
|
|
|
|
/**
|
|
* Message type values.
|
|
* If we ever need to include more information in the takeover data in the
|
|
* future we can do so by adding new message types here, and deprecating the
|
|
* older formats once we have upgraded all servers to use the new format.
|
|
*/
|
|
enum MessageType : uint32_t {
|
|
ERROR = 1,
|
|
MOUNTS = 2,
|
|
PING = 3,
|
|
};
|
|
|
|
/**
|
|
* The length of the serialized header.
|
|
* This is just a 4-byte message type field.
|
|
*/
|
|
static constexpr uint32_t kHeaderLength = sizeof(uint32_t);
|
|
};
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|