mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
6f67546602
Summary: Update the TakeoverClient and TakeoverServer code to use the new UnixSocket helper class for exchanging messages, file descriptors, and credential information. This does not change the message serialization code much yet, it merely changes the code to use the UnixSocket class for I/O. Reviewed By: wez Differential Revision: D6494979 fbshipit-source-id: 3129fe8605b1b3b7a24e6e84e94dccf3ea2b4170
132 lines
4.1 KiB
C++
132 lines
4.1 KiB
C++
/*
|
|
* Copyright (c) 2004-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
*/
|
|
#include "eden/fs/takeover/TakeoverData.h"
|
|
|
|
#include <folly/Format.h>
|
|
#include <folly/io/Cursor.h>
|
|
#include <folly/io/IOBuf.h>
|
|
|
|
using folly::IOBuf;
|
|
using std::string;
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
IOBuf TakeoverData::serialize() {
|
|
// Compute the body data length
|
|
uint64_t bodyLength = sizeof(uint32_t);
|
|
for (const auto& mount : mountPoints) {
|
|
bodyLength += sizeof(uint32_t) + mount.path.stringPiece().size();
|
|
bodyLength += sizeof(uint32_t);
|
|
for (const auto& bindMount : mount.bindMounts) {
|
|
bodyLength += sizeof(uint32_t) + bindMount.stringPiece().size();
|
|
}
|
|
}
|
|
|
|
// Build a buffer with all of the mount paths
|
|
auto fullCapacity = kHeaderLength + bodyLength;
|
|
IOBuf buf(IOBuf::CREATE, fullCapacity);
|
|
folly::io::Appender app(&buf, 0);
|
|
|
|
// Serialize the message type
|
|
app.writeBE<uint32_t>(MessageType::MOUNTS);
|
|
|
|
// Write the number of mount points
|
|
app.writeBE<uint32_t>(mountPoints.size());
|
|
|
|
// Serialize each mount point
|
|
for (const auto& mount : mountPoints) {
|
|
// The mount path
|
|
const auto& pathStr = mount.path.stringPiece();
|
|
app.writeBE<uint32_t>(pathStr.size());
|
|
app(pathStr);
|
|
// Number of bind mounts, followed by the bind mount paths
|
|
app.writeBE<uint32_t>(mount.bindMounts.size());
|
|
for (const auto& bindMount : mount.bindMounts) {
|
|
app.writeBE<uint32_t>(bindMount.stringPiece().size());
|
|
app(bindMount.stringPiece());
|
|
}
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
folly::IOBuf TakeoverData::serializeError(const folly::exception_wrapper& ew) {
|
|
// Compute the body data length
|
|
auto exceptionClassName = ew.class_name();
|
|
folly::StringPiece what = ew ? ew.get_exception()->what() : "";
|
|
uint64_t bodyLength = sizeof(uint32_t) + exceptionClassName.size() +
|
|
sizeof(uint32_t) + what.size();
|
|
|
|
// Allocate the buffer
|
|
auto fullCapacity = kHeaderLength + bodyLength;
|
|
IOBuf buf(IOBuf::CREATE, fullCapacity);
|
|
folly::io::Appender app(&buf, 0);
|
|
|
|
// Serialize the message type
|
|
app.writeBE<uint32_t>(MessageType::ERROR);
|
|
|
|
// Write the error type and message
|
|
app.writeBE<uint32_t>(exceptionClassName.size());
|
|
app(exceptionClassName);
|
|
app.writeBE<uint32_t>(what.size());
|
|
app(what);
|
|
|
|
return buf;
|
|
}
|
|
|
|
TakeoverData TakeoverData::deserialize(const IOBuf* buf) {
|
|
folly::io::Cursor cursor(buf);
|
|
|
|
auto messageType = cursor.readBE<uint32_t>();
|
|
if (messageType != MessageType::ERROR && messageType != MessageType::MOUNTS) {
|
|
throw std::runtime_error(
|
|
folly::to<string>("unknown takeover data message type ", messageType));
|
|
}
|
|
|
|
// Check the message type
|
|
if (messageType == MessageType::ERROR) {
|
|
auto errorTypeLength = cursor.readBE<uint32_t>();
|
|
auto errorType = cursor.readFixedString(errorTypeLength);
|
|
auto errorMessageLength = cursor.readBE<uint32_t>();
|
|
auto errorMessage = cursor.readFixedString(errorMessageLength);
|
|
|
|
throw std::runtime_error(errorType + ": " + errorMessage);
|
|
}
|
|
if (messageType != MessageType::MOUNTS) {
|
|
throw std::runtime_error(
|
|
folly::to<string>("unknown takeover data message type ", messageType));
|
|
}
|
|
|
|
TakeoverData data;
|
|
auto numMounts = cursor.readBE<uint32_t>();
|
|
for (uint32_t mountIdx = 0; mountIdx < numMounts; ++mountIdx) {
|
|
auto pathLength = cursor.readBE<uint32_t>();
|
|
auto path = cursor.readFixedString(pathLength);
|
|
auto numBindMounts = cursor.readBE<uint32_t>();
|
|
|
|
std::vector<AbsolutePath> bindMounts;
|
|
bindMounts.reserve(numBindMounts);
|
|
for (uint32_t bindIdx = 0; bindIdx < numBindMounts; ++bindIdx) {
|
|
auto bindPathLength = cursor.readBE<uint32_t>();
|
|
auto bindPath = cursor.readFixedString(bindPathLength);
|
|
bindMounts.emplace_back(AbsolutePathPiece{bindPath});
|
|
}
|
|
|
|
data.mountPoints.emplace_back(
|
|
AbsolutePath{path}, std::move(bindMounts), folly::File{});
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|