service: send the takeover mount after fuse is initialized

Summary:
On takeover, the new EdenFS sends the current mount point over to the
privhelper, and due to being a suid root process, the privhelper needs to
double check that the given mount point is valid before accepting it. In order
to do this, a `stat` is ran on the mount point.

Unfortunately, this `stat` call may need to perform a lookup and getattr FUSE
calls, but since EdenFS hasn't yet initialized FUSE, it may hang, leading to
EdenFS not being able to restart.

To fix this, we can simply start FUSE prior to advertising the mount point to
the privhelper, this way the lookup and getattr FUSE calls can be answered.

Reviewed By: kmancini

Differential Revision: D32322661

fbshipit-source-id: 4ea1e44ce362e04ed7eebaff1f2a8f381f8bff60
This commit is contained in:
Xavier Deguillard 2021-11-10 18:34:02 -08:00 committed by Facebook GitHub Bot
parent f7ec60188e
commit 7dd8eb32b7

View File

@ -1366,17 +1366,21 @@ Future<Unit> EdenServer::performTakeoverStart(
FOLLY_MAYBE_UNUSED std::shared_ptr<EdenMount> edenMount,
FOLLY_MAYBE_UNUSED TakeoverData::MountInfo&& info) {
#ifndef _WIN32
auto mountPath = info.mountPath;
std::vector<std::string> bindMounts;
for (const auto& bindMount : info.bindMounts) {
bindMounts.emplace_back(bindMount.value());
}
auto future = serverState_->getPrivHelper()->takeoverStartup(
info.mountPath.stringPiece(), bindMounts);
return std::move(future).thenValue([this,
edenMount = std::move(edenMount),
info = std::move(info)](auto&&) mutable {
return completeTakeoverStart(std::move(edenMount), std::move(info));
});
auto future = completeTakeoverStart(edenMount, std::move(info));
return std::move(future).thenValue(
[this,
edenMount = std::move(edenMount),
bindMounts = std::move(bindMounts),
mountPath = std::move(mountPath)](auto&&) mutable {
return serverState_->getPrivHelper()->takeoverStartup(
mountPath.stringPiece(), bindMounts);
});
#else
NOT_IMPLEMENTED();
#endif