mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
129d87fe23
Summary: While EdenFS does not use a separate privhelper process on Windows, it still defines a stub PrivHelper class. However, this class was previously defined in a separate win/utils/Stub.h header file, which led to awkward `#ifdef`s to include the correct platform-specific header file. This diff moves the definition of the dummy PrivHelper class in Windows into the same `PrivHelper.h` header file used on POSIX platforms. This results in a few more `ifdef`s in the PrivHelper files, but fewer `ifdef`s in the calling code, and will make it easier to start unifying more of the `EdenMain` logic on Windows and non-Windows platforms. Reviewed By: xavierd Differential Revision: D21332568 fbshipit-source-id: c63bf2b4a8b7e767d7db7dcda28675f735c23bf8
174 lines
5.3 KiB
C++
174 lines
5.3 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/Portability.h>
|
|
#include <folly/Range.h>
|
|
#include <sys/types.h>
|
|
#include <chrono>
|
|
#include <memory>
|
|
|
|
namespace folly {
|
|
class EventBase;
|
|
class File;
|
|
template <typename T>
|
|
class Future;
|
|
struct Unit;
|
|
} // namespace folly
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
#ifndef _WIN32
|
|
|
|
/**
|
|
* A helper class for performing operations that require elevated privileges.
|
|
*
|
|
* This sends the requests to a separate helper process that has the privileges
|
|
* required to peform these operations.
|
|
*/
|
|
class PrivHelper {
|
|
public:
|
|
virtual ~PrivHelper() {}
|
|
|
|
/**
|
|
* Attach the PrivHelper to an EventBase.
|
|
*
|
|
* This specifies the EventBase that the PrivHelper will use to drive I/O
|
|
* operations.
|
|
*
|
|
* This method must be called before using the PrivHelper, and it must be
|
|
* called from the EventBase thread.
|
|
*/
|
|
virtual void attachEventBase(folly::EventBase* eventBase) = 0;
|
|
|
|
/**
|
|
* Detach the PrivHelper from its EventBase.
|
|
*
|
|
* This method may only be called from the current EventBase thread.
|
|
*
|
|
* No further I/O can be performed on this PrivHelper until it is re-attached
|
|
* to another EventBase. Any outstanding requests will not complete until the
|
|
* PrivHelper is attached to another EventBase.
|
|
*/
|
|
virtual void detachEventBase() = 0;
|
|
|
|
/**
|
|
* Ask the privileged helper process to perform a fuse mount.
|
|
*
|
|
* Returns a folly::File object with the file descriptor containing the fuse
|
|
* connection.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::File> fuseMount(
|
|
folly::StringPiece mountPath,
|
|
bool readOnly) = 0;
|
|
|
|
/**
|
|
* Ask the privileged helper process to perform a fuse unmount.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> fuseUnmount(
|
|
folly::StringPiece mountPath) = 0;
|
|
|
|
/**
|
|
* @param clientPath Absolute path to the existing directory where the "real"
|
|
* storage is.
|
|
* @param mountPath Absolute path to the mount point directory where the bind
|
|
* mount should be created.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> bindMount(
|
|
folly::StringPiece clientPath,
|
|
folly::StringPiece mountPath) = 0;
|
|
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> bindUnMount(
|
|
folly::StringPiece mountPath) = 0;
|
|
|
|
/**
|
|
* Inform the privhelper process that we are shutting down as part of a
|
|
* graceful restart, and a new edenfs daemon will take over our existing
|
|
* mount points without unmounting them.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> fuseTakeoverShutdown(
|
|
folly::StringPiece mountPath) = 0;
|
|
|
|
/**
|
|
* Inform the privhelper process that we have taken over an existing mount
|
|
* point from another edenfs process.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> fuseTakeoverStartup(
|
|
folly::StringPiece mountPath,
|
|
const std::vector<std::string>& bindMounts) = 0;
|
|
|
|
/**
|
|
* Tell the privhelper server to write all future log messages to the
|
|
* specified file descriptor.
|
|
*/
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> setLogFile(
|
|
folly::File logFile) = 0;
|
|
|
|
/**
|
|
* Tell the privhelper server to use `duration` for the `daemon_timeout`
|
|
* parameter in subsequent fuseMount requests.
|
|
* The `daemon_timeout` is a macOS specific FUSE implementation detail;
|
|
* it is equivalent to our FuseChannel::fuseRequestTimeout_ value, except
|
|
* that the consequence of exceeding the timeout is that the FUSE session
|
|
* is torn down. */
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> setDaemonTimeout(
|
|
std::chrono::nanoseconds duration) = 0;
|
|
|
|
/**
|
|
* setLogFileBlocking() is a wrapper around setLogFile() that blocks until
|
|
* the call has completed.
|
|
*
|
|
* This method may only be called if the PrivHelper is not currently attached
|
|
* to an EventBase. This is primarily intended as a convenience method to
|
|
* allow calling setLogFile() before the main process's EventBase loop has
|
|
* started.
|
|
*/
|
|
void setLogFileBlocking(folly::File logFile);
|
|
void setDaemonTimeoutBlocking(std::chrono::nanoseconds duration);
|
|
|
|
/*
|
|
* Explicitly stop the privhelper process.
|
|
*
|
|
* The privhelper process will exit automatically when the main process exits
|
|
* even if this method is not called. However, this method can be used to
|
|
* explictly stop the privhelper process, and check its exit code.
|
|
*
|
|
* Note that when the privhelper is stopped it will unmount any outstanding
|
|
* mounts points.
|
|
*
|
|
* If the privhelper exited normally, the exit code is returned.
|
|
* If the privhelper was terminated due to a signal, the signal number is
|
|
* returned as a negative number.
|
|
*
|
|
* Throws an exception if the privhelper was not running, or if any other
|
|
* error occurs.
|
|
*/
|
|
virtual int stop() = 0;
|
|
};
|
|
|
|
#else // _WIN32
|
|
|
|
/**
|
|
* A stub PrivHelper class for Windows.
|
|
*
|
|
* We do not actually use a separate privhelper process on Windows. However,
|
|
* for ease of sharing server initialization code across platforms we still
|
|
* define a PrivHelper object, but it does nothing.
|
|
*/
|
|
class PrivHelper {
|
|
public:
|
|
void setLogFileBlocking(folly::File logFile);
|
|
void setDaemonTimeoutBlocking(std::chrono::nanoseconds duration);
|
|
};
|
|
|
|
#endif // _WIN32
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|