mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
inodes: start plumbing Mountd in the mount code.
Summary: Once everything is plugged in, EdenFS will first register the mount point with Mountd, and then execute the mount.nfs CLI against itself to mount the repository with the OS. For now, this does the first part by simply informing Mountd of a new mount point during mount. Reviewed By: kmancini Differential Revision: D26139990 fbshipit-source-id: e5097b8e90c032c8c7bdd2cd03b69695074d7874
This commit is contained in:
parent
f20536cbaa
commit
22075c1159
@ -53,6 +53,8 @@ target_link_libraries(
|
||||
eden_telemetry
|
||||
eden_utils
|
||||
Folly::folly
|
||||
PRIVATE
|
||||
eden_nfs_mountd
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "eden/fs/model/Tree.h"
|
||||
#include "eden/fs/model/git/GitIgnoreStack.h"
|
||||
#include "eden/fs/model/git/TopLevelIgnores.h"
|
||||
#include "eden/fs/nfs/Mountd.h"
|
||||
#include "eden/fs/service/PrettyPrinters.h"
|
||||
#include "eden/fs/service/gen-cpp2/eden_types.h"
|
||||
#include "eden/fs/store/BlobAccess.h"
|
||||
@ -636,8 +637,17 @@ folly::Future<folly::Unit> EdenMount::unmount() {
|
||||
.via(serverState_->getThreadPool().get())
|
||||
.ensure([this] { channel_.reset(); });
|
||||
#else
|
||||
return serverState_->getPrivHelper()->fuseUnmount(
|
||||
getPath().stringPiece());
|
||||
if (serverState_->getReloadableConfig()
|
||||
.getEdenConfig()
|
||||
->enableNfsServer.getValue() &&
|
||||
getConfig()->getMountProtocol() == MountProtocol::NFS) {
|
||||
// TODO(xavierd): We need to actually do the unmount here.
|
||||
serverState_->getMountd()->unregisterMount(getPath());
|
||||
return folly::makeFuture();
|
||||
} else {
|
||||
return serverState_->getPrivHelper()->fuseUnmount(
|
||||
getPath().stringPiece());
|
||||
}
|
||||
#endif
|
||||
})
|
||||
.thenTry([this](Try<Unit>&& result) noexcept -> folly::Future<Unit> {
|
||||
@ -1252,43 +1262,54 @@ folly::Future<EdenMount::channelType> EdenMount::channelMount(bool readOnly) {
|
||||
return makeFuture(channel);
|
||||
});
|
||||
#else
|
||||
return serverState_->getPrivHelper()
|
||||
->fuseMount(mountPath.stringPiece(), readOnly)
|
||||
.thenTry(
|
||||
[mountPath, mountPromise, this](Try<folly::File>&& fuseDevice)
|
||||
-> folly::Future<folly::File> {
|
||||
if (fuseDevice.hasException()) {
|
||||
mountPromise->setException(fuseDevice.exception());
|
||||
return folly::makeFuture<folly::File>(
|
||||
fuseDevice.exception());
|
||||
}
|
||||
if (mountingUnmountingState_.rlock()
|
||||
->channelUnmountStarted()) {
|
||||
fuseDevice->close();
|
||||
return serverState_->getPrivHelper()
|
||||
->fuseUnmount(mountPath.stringPiece())
|
||||
.thenError(
|
||||
folly::tag<std::exception>,
|
||||
[](std::exception&& unmountError) {
|
||||
// TODO(strager): Should we make
|
||||
// EdenMount::unmount() also fail with the same
|
||||
// exception?
|
||||
XLOG(ERR)
|
||||
<< "fuseMount was cancelled, but rollback (fuseUnmount) failed: "
|
||||
<< unmountError.what();
|
||||
throw std::move(unmountError);
|
||||
})
|
||||
.thenValue([mountPath, mountPromise](folly::Unit&&) {
|
||||
auto error = FuseDeviceUnmountedDuringInitialization{
|
||||
mountPath};
|
||||
mountPromise->setException(error);
|
||||
return folly::makeFuture<folly::File>(error);
|
||||
});
|
||||
}
|
||||
if (serverState_->getReloadableConfig()
|
||||
.getEdenConfig()
|
||||
->enableNfsServer.getValue() &&
|
||||
getConfig()->getMountProtocol() == MountProtocol::NFS) {
|
||||
auto mountd = serverState_->getMountd();
|
||||
mountd->registerMount(mountPath, getRootInode()->getNodeId());
|
||||
// TODO(xavierd): We need to actually do a mount here.
|
||||
return makeFuture(folly::File());
|
||||
} else {
|
||||
return serverState_->getPrivHelper()
|
||||
->fuseMount(mountPath.stringPiece(), readOnly)
|
||||
.thenTry(
|
||||
[mountPath, mountPromise, this](Try<folly::File>&& fuseDevice)
|
||||
-> folly::Future<folly::File> {
|
||||
if (fuseDevice.hasException()) {
|
||||
mountPromise->setException(fuseDevice.exception());
|
||||
return folly::makeFuture<folly::File>(
|
||||
fuseDevice.exception());
|
||||
}
|
||||
if (mountingUnmountingState_.rlock()
|
||||
->channelUnmountStarted()) {
|
||||
fuseDevice->close();
|
||||
return serverState_->getPrivHelper()
|
||||
->fuseUnmount(mountPath.stringPiece())
|
||||
.thenError(
|
||||
folly::tag<std::exception>,
|
||||
[](std::exception&& unmountError) {
|
||||
// TODO(strager): Should we make
|
||||
// EdenMount::unmount() also fail with the same
|
||||
// exception?
|
||||
XLOG(ERR)
|
||||
<< "fuseMount was cancelled, but rollback (fuseUnmount) failed: "
|
||||
<< unmountError.what();
|
||||
throw std::move(unmountError);
|
||||
})
|
||||
.thenValue([mountPath, mountPromise](folly::Unit&&) {
|
||||
auto error =
|
||||
FuseDeviceUnmountedDuringInitialization{
|
||||
mountPath};
|
||||
mountPromise->setException(error);
|
||||
return folly::makeFuture<folly::File>(error);
|
||||
});
|
||||
}
|
||||
|
||||
mountPromise->setValue();
|
||||
return folly::makeFuture(std::move(fuseDevice).value());
|
||||
});
|
||||
mountPromise->setValue();
|
||||
return folly::makeFuture(std::move(fuseDevice).value());
|
||||
});
|
||||
}
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ add_library(
|
||||
target_link_libraries(
|
||||
eden_nfs_mountd
|
||||
PUBLIC
|
||||
eden_inodes_inodenumber
|
||||
eden_nfs_rpc_server
|
||||
eden_utils
|
||||
PRIVATE
|
||||
eden_nfs_mountd_rpc
|
||||
Folly::folly
|
||||
|
@ -7,15 +7,16 @@
|
||||
|
||||
#include "eden/fs/nfs/Mountd.h"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <folly/Synchronized.h>
|
||||
#include <folly/futures/Future.h>
|
||||
#include <folly/logging/xlog.h>
|
||||
#include <memory>
|
||||
#include "eden/fs/nfs/MountdRpc.h"
|
||||
|
||||
namespace facebook::eden {
|
||||
|
||||
namespace {
|
||||
|
||||
class MountdServerProcessor final : public RpcServerProcessor {
|
||||
public:
|
||||
MountdServerProcessor() = default;
|
||||
@ -45,6 +46,13 @@ class MountdServerProcessor final : public RpcServerProcessor {
|
||||
umountAll(folly::io::Cursor deser, folly::io::Appender ser, uint32_t xid);
|
||||
folly::Future<folly::Unit>
|
||||
exprt(folly::io::Cursor deser, folly::io::Appender ser, uint32_t xid);
|
||||
|
||||
void registerMount(AbsolutePathPiece path, InodeNumber rootIno);
|
||||
void unregisterMount(AbsolutePathPiece path);
|
||||
|
||||
private:
|
||||
folly::Synchronized<std::unordered_map<AbsolutePath, InodeNumber>>
|
||||
mountPoints_;
|
||||
};
|
||||
|
||||
using Handler = folly::Future<folly::Unit> (MountdServerProcessor::*)(
|
||||
@ -174,10 +182,31 @@ folly::Future<folly::Unit> MountdServerProcessor::dispatchRpc(
|
||||
return (this->*handlerEntry.handler)(std::move(deser), std::move(ser), xid);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
void MountdServerProcessor::registerMount(
|
||||
AbsolutePathPiece path,
|
||||
InodeNumber ino) {
|
||||
auto map = mountPoints_.wlock();
|
||||
auto [iter, inserted] = map->emplace(path.copy(), ino);
|
||||
XCHECK_EQ(inserted, true);
|
||||
}
|
||||
|
||||
Mountd::Mountd() : server_(std::make_shared<MountdServerProcessor>()) {
|
||||
void MountdServerProcessor::unregisterMount(AbsolutePathPiece path) {
|
||||
auto map = mountPoints_.wlock();
|
||||
auto numRemoved = map->erase(path.copy());
|
||||
XCHECK_EQ(numRemoved, 1u);
|
||||
}
|
||||
|
||||
Mountd::Mountd()
|
||||
: proc_(std::make_shared<MountdServerProcessor>()), server_(proc_) {
|
||||
server_.registerService(kMountdProgNumber, kMountdProgVersion);
|
||||
}
|
||||
|
||||
void Mountd::registerMount(AbsolutePathPiece path, InodeNumber ino) {
|
||||
proc_->registerMount(path, ino);
|
||||
}
|
||||
|
||||
void Mountd::unregisterMount(AbsolutePathPiece path) {
|
||||
proc_->unregisterMount(path);
|
||||
}
|
||||
|
||||
} // namespace facebook::eden
|
||||
|
@ -10,20 +10,38 @@
|
||||
// Implementation of the mount protocol as described in:
|
||||
// https://tools.ietf.org/html/rfc1813#page-106
|
||||
|
||||
#include "eden/fs/inodes/InodeNumber.h"
|
||||
#include "eden/fs/nfs/rpc/Server.h"
|
||||
#include "eden/fs/utils/PathFuncs.h"
|
||||
|
||||
namespace facebook::eden {
|
||||
|
||||
class MountdServerProcessor;
|
||||
|
||||
class Mountd {
|
||||
public:
|
||||
Mountd();
|
||||
|
||||
/**
|
||||
* Register a path as the root of a mount point.
|
||||
*
|
||||
* Once registered, the mount RPC request for that specific path will answer
|
||||
* positively with the passed in InodeNumber.
|
||||
*/
|
||||
void registerMount(AbsolutePathPiece path, InodeNumber rootIno);
|
||||
|
||||
/**
|
||||
* Unregister the mount point matching the path.
|
||||
*/
|
||||
void unregisterMount(AbsolutePathPiece path);
|
||||
|
||||
Mountd(const Mountd&) = delete;
|
||||
Mountd(Mountd&&) = delete;
|
||||
Mountd& operator=(const Mountd&) = delete;
|
||||
Mountd& operator=(Mountd&&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<MountdServerProcessor> proc_;
|
||||
RpcServer server_;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user