inodes: attempt to NFS mount

Summary:
With the PrivHelper now being able to try to NFS mount, we can just plug it in
the EdenMount code to actually attempt to mount EdenFS via NFS.

The mount will expectedly fail due to the FSINFO RPC not being implemented just
yet, but that will be the next step.

Reviewed By: kmancini

Differential Revision: D26266143

fbshipit-source-id: a44ae98af76b55a0c24c89e766c072c1a2e1b4fd
This commit is contained in:
Xavier Deguillard 2021-02-09 12:45:00 -08:00 committed by Facebook GitHub Bot
parent 91336a090e
commit 2f754b2305
6 changed files with 93 additions and 15 deletions

View File

@ -1270,20 +1270,53 @@ folly::Future<EdenMount::channelType> EdenMount::channelMount(bool readOnly) {
// Make sure that we are running on the EventBase while registering
// the mount point.
return via(
nfsServer->getEventBase(),
[this, nfsServer, mountPath = std::move(mountPath)]() {
nfsServer->registerMount(
mountPath, getRootInode()->getNodeId());
// TODO(xavierd): We need to actually do a mount here.
return folly::File();
auto fut =
via(nfsServer->getEventBase(), [this, mountPath, nfsServer]() {
return nfsServer->registerMount(
mountPath,
getRootInode()->getNodeId(),
getDispatcher(),
&getStraceLogger(),
serverState_->getProcessNameCache(),
std::chrono::duration_cast<folly::Duration>(
serverState_->getReloadableConfig()
.getEdenConfig()
->prjfsRequestTimeout.getValue()),
serverState_->getNotifications());
});
return std::move(fut).thenValue(
[this,
readOnly,
mountPromise = std::move(mountPromise),
mountPath = std::move(mountPath)](
NfsServer::NfsMountInfo mountInfo) mutable {
auto [channel, mountdPort, nfsdPort] = std::move(mountInfo);
return serverState_->getPrivHelper()
->nfsMount(
mountPath.stringPiece(), mountdPort, nfsdPort, readOnly)
.thenTry([mountPromise = std::move(mountPromise),
channel = std::move(channel)](
Try<folly::Unit>&& try_) mutable {
if (try_.hasException()) {
mountPromise->setException(try_.exception());
return folly::makeFuture<EdenMount::channelType>(
try_.exception());
}
// TODO(xavierd): Do something meaningful once nfsMount
// succeeds, and return the channel.
XLOG(FATAL) << "Mount should have failed but didn't?";
mountPromise->setValue();
return makeFuture(folly::File());
});
});
} else {
return serverState_->getPrivHelper()
->fuseMount(mountPath.stringPiece(), readOnly)
.thenTry(
[mountPath, mountPromise, this](Try<folly::File>&& fuseDevice)
-> folly::Future<folly::File> {
-> folly::Future<EdenMount::channelType> {
if (fuseDevice.hasException()) {
mountPromise->setException(fuseDevice.exception());
return folly::makeFuture<folly::File>(

View File

@ -42,8 +42,14 @@ int main(int argc, char** argv) {
SignalHandler signal(evb);
NfsServer server(false, evb);
auto [nfsd, mountdport, nfsdport] =
server.registerMount(AbsolutePathPiece("/foo/bar"), InodeNumber(42));
auto [nfsd, mountdport, nfsdport] = server.registerMount(
AbsolutePathPiece("/foo/bar"),
InodeNumber(42),
nullptr,
nullptr,
nullptr,
std::chrono::duration_cast<folly::Duration>(std::chrono::seconds(0)),
nullptr);
XLOG(INFO) << "Started NfsServer, mountdport=" << mountdport
<< ", nfsdport=" << nfsdport;

View File

@ -14,8 +14,20 @@ namespace facebook::eden {
NfsServer::NfsMountInfo NfsServer::registerMount(
AbsolutePathPiece path,
InodeNumber rootIno) {
auto nfsd = std::make_unique<Nfsd3>(false, evb_);
InodeNumber rootIno,
Dispatcher* const dispatcher,
const folly::Logger* straceLogger,
std::shared_ptr<ProcessNameCache> processNameCache,
folly::Duration requestTimeout,
Notifications* notifications) {
auto nfsd = std::make_unique<Nfsd3>(
false,
evb_,
dispatcher,
straceLogger,
std::move(processNameCache),
requestTimeout,
notifications);
mountd_.registerMount(path, rootIno);
auto nfsdPort = nfsd->getPort();

View File

@ -15,6 +15,10 @@
namespace facebook::eden {
class Dispatcher;
class Notifications;
class ProcessNameCache;
class NfsServer {
public:
/**
@ -52,7 +56,12 @@ class NfsServer {
*/
NfsServer::NfsMountInfo registerMount(
AbsolutePathPiece path,
InodeNumber rootIno);
InodeNumber rootIno,
Dispatcher* const dispatcher,
const folly::Logger* straceLogger,
std::shared_ptr<ProcessNameCache> processNameCache,
folly::Duration requestTimeout,
Notifications* FOLLY_NULLABLE notifications);
/**
* Unregister the mount point matching the path.

View File

@ -350,7 +350,14 @@ folly::Future<folly::Unit> Nfsd3ServerProcessor::dispatchRpc(
}
} // namespace
Nfsd3::Nfsd3(bool registerWithRpcbind, folly::EventBase* evb)
Nfsd3::Nfsd3(
bool registerWithRpcbind,
folly::EventBase* evb,
Dispatcher* const /*dispatcher*/,
const folly::Logger* /*straceLogger*/,
std::shared_ptr<ProcessNameCache> /*processNameCache*/,
folly::Duration /*requestTimeout*/,
Notifications* /*notifications*/)
: server_(std::make_shared<Nfsd3ServerProcessor>(), evb) {
if (registerWithRpcbind) {
server_.registerService(kNfsdProgNumber, kNfsd3ProgVersion);

View File

@ -16,6 +16,10 @@
namespace facebook::eden {
class Dispatcher;
class Notifications;
class ProcessNameCache;
class Nfsd3 {
public:
/**
@ -34,7 +38,14 @@ class Nfsd3 {
* to manually specify the port on which this server is bound, so registering
* is not necessary for a properly behaving EdenFS.
*/
Nfsd3(bool registerWithRpcbind, folly::EventBase* evb);
Nfsd3(
bool registerWithRpcbind,
folly::EventBase* evb,
Dispatcher* const dispatcher,
const folly::Logger* straceLogger,
std::shared_ptr<ProcessNameCache> processNameCache,
folly::Duration requestTimeout,
Notifications* FOLLY_NULLABLE notifications);
/**
* Obtain the TCP port that this NFSv3 program is listening on.